[英]Using CXF ClientBUilder, how to unmarshal post response parameters into Java class
I'm using CXF ClientBuilder to send POST data to a REST service. 我正在使用CXF ClientBuilder将POST数据发送到REST服务。 The response I get back looks like this right now: 我得到的回复现在看起来像这样:
errorCode=206&errorMessage=blah+blah
I want to unmarshal this into fields in a POJO. 我想将其解组到POJO的字段中。
The following code block illustrates what I have right now: 以下代码块说明了我现在所拥有的:
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();
}
}
As written right now, I get the response as I originally described. 就像现在写的那样,我得到了我最初描述的答复。 I'm trying to figure out some variation of those last commented-out lines to replace the first "request.post()" and the two following lines, to get the result I'm looking for. 我试图找出这些最后注释掉的行的某种形式,以替换第一个“ request.post()”和后面的两行,以得到我想要的结果。
Update : 更新 :
I did find at least one way to do this, but I don't know if it's the best way. 我确实找到了至少一种方法来执行此操作,但是我不知道这是否是最佳方法。
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"));
The key was using the Form object for the response type. 关键是使用Form对象作为响应类型。 With this solution, I still have to reference the field names. 使用此解决方案,我仍然必须引用字段名称。 Is there a cleaner way to do this? 有没有更清洁的方法可以做到这一点?
Update : 更新 :
I would guess that a cleaner solution would require implementing a MessageBodyReader for this CodeAndMessage class, but I'm not sure yet how to do that. 我猜想更干净的解决方案将需要为此CodeAndMessage类实现MessageBodyReader,但是我不确定如何做到这一点。
My MessageBodyReader implementation looks like this: 我的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)).
...;
}
}
When creating the ClientBuilder, I register the MBR like this: 创建ClientBuilder时,我会这样注册MBR:
ClientBuilder builder = ClientBuilder.newBuilder().register(StuffResponseReader.class);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.