使用CXF ClientBUilder,如何将后响应参数解组为Java类

时间:2017-04-10 22:27:44

标签: java jax-rs cxf

我使用CXF ClientBuilder将POST数据发送到REST服务。我回来的回答现在看起来像这样:

errorCode=206&errorMessage=blah+blah

我想将其解组为POJO中的字段。

以下代码块说明了我现在所拥有的内容:

public void validateToken(String token) {
    WebTarget   target  = client.target(getHostPort()).path(getPath());
    Builder request = target.request(MediaType.APPLICATION_JSON_TYPE);
    Form  form    = new Form();
    form.param("TokenID", token);
    Response  postResponse    = request.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
    System.out.println("postResponse[" + postResponse + "]");
    System.out.println("response.text[" + postResponse.readEntity(String.class) + "]");
//      CodeAndMessage    codeAndMessage  = request.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), CodeAndMessage.class);
//      System.out.println("codeAndMessage[" + codeAndMessage + "]");
}

public static class CodeAndMessage {
    private String errorCode;
    private String errorMessage;

    public String getErrorCode() { return errorCode; }
    public String getErrorMessage() { return errorMessage; }

    public void setErrorCode(String errorCode) { this.errorCode = errorCode; }
    public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }

    @Override
    public String toString() {
        return new ToStringBuilder(this).
                append("errorCode", getErrorCode()).
                append("errorMessage", getErrorMessage()).
                build();
    }
}

正如现在所写,我得到了我最初描述的回复。我试图弄清楚那些最后注释掉的行的一些变化来替换第一个" request.post()"以及以下两行,以获得我正在寻找的结果。

更新

我确实找到了至少一种方法,但我不知道这是否是最佳方式。

    Form  responseForm    = request.post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), Form.class);
    System.out.println("responseForm[" + responseForm + "] map[" + responseForm.asMap() + "]");
    return new CodeAndMessage().
                errorCode(responseForm.asMap().getFirst("errorCode")).
                errorMessage(responseForm.asMap().getFirst("errorMessage"));

密钥是使用Form对象作为响应类型。有了这个解决方案,我仍然需要引用字段名称。有更清洁的方法吗?

更新

我猜想更清洁的解决方案需要为此CodeAndMessage类实现MessageBodyReader,但我还不确定如何做到这一点。

1 个答案:

答案 0 :(得分:1)

我的MessageBodyReader实现如下所示:

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Consumes;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;

import org.apache.cxf.jaxrs.provider.FormEncodingProvider;

@Provider
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public class StuffResponseReader  implements MessageBodyReader<StuffResponse> {

    private FormEncodingProvider<Form> formProvider = new FormEncodingProvider<>();

    private static final String PROP_ERROR_CODE                 = "errorCode";
    private static final String PROP_ERROR_DESCRIPTION          = "errorMessage";
    ...

    @Override
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type.isAssignableFrom(StuffResponse.class);
    }

    @Override
    public StuffResponse readFrom(Class<StuffResponse> type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException {
        Form    form    = formProvider.readFrom(Form.class, Form.class, annotations, mediaType, httpHeaders, entityStream);
        MultivaluedMap<String, String> data = form.asMap();
        return new StuffResponse().
                errorCode(data.getFirst(PROP_ERROR_CODE)).
                errorDescription(data.getFirst(PROP_ERROR_DESCRIPTION)).
                ...;
    }
}

创建ClientBuilder时,我注册了MBR:

ClientBuilder   builder = ClientBuilder.newBuilder().register(StuffResponseReader.class);