我在tomEE plus 1.7.1中使用Apache CXF WebClient。 (CXF-RT-前端-JAXRS-2.6.14.jar)
我实现了一个期望JSON服务器响应的REST客户端:
public RestClient(String aBaseUrl, String aPath) {
this.client = WebClient.create(aBaseUrl);
this.client.path(aPath);
this.client.accept(MediaType.APPLICATION_JSON);
}
public JSONObject post(MultivaluedMap<String, String> params) {
LOG.debug("sending POST request to: " + this.client.getCurrentURI());
LOG.debug("POST parameters: " + PrivacyFilter.getLogLineFor(params));
Form theForm = new Form(params);
JSONObject theJson;
String resp = this.client.post(theForm, String.class);
try {
theJson = new JSONObject(resp);
} catch (JSONException e) {
LOG.warn("got malformed answer from Server - cannot parse as JSON");
LOG.trace(resp);
throw new RuntimeException("got malformed answer from Server - cannot parse as JSON", e);
}
return theJson;
}
我希望服务器在HTTP正文中返回JSON数据。 我期望所有HTTP状态代码。也适用于代码不是2xx的错误情况。
这是我的问题。 如果HTTP状态代码是&gt; = 400,CXF接缝(出于任何原因???)抛出ServerWebApplicationException。我在WebClient实现中发现了这段代码:
if (r.getStatus() >= 400 && responseClass != Response.class) {
throw new ServerWebApplicationException(r);
}
这是什么原因? RESTful API还能解决大于400的代码,这是不是很正常?在我看来,在这种情况下,异常不接缝确实是一个很好的解决方案。
我没有弄清楚如何使用CXF实现我的REST客户端。有可能改变这种行为吗?仅当responseClass!= Response.class时才会抛出Exception接缝。我以这种方式修改了REST客户端:
public JSONObject post(MultivaluedMap<String, String> params) {
LOG.debug("sending POST request to: " + this.client.getCurrentURI());
LOG.debug("POST paramters: " + PrivacyFilter.getLogLineFor(params));
Form theForm = new Form(params);
JSONObject theJson;
Response respObject = this.client.post(theForm, Response.class);
// HOW TO GET THE HTTP BODY OUT OF reps?!
try {
theJson = new JSONObject(resp);
} catch (JSONException e) {
LOG.warn("got malformed answer from Server - cannot parse as JSON");
LOG.trace(resp);
throw new RuntimeException("got malformed answer from Server - cannot parse as JSON", e);
}
return theJson;
}
在这里,我没有找到访问HTTP正文的可能性。 Response对象没有接缝来拥有它的访问器。 javax.ws.rs.core.Response中一个有趣的方法是:
Object getEntity()
如果我调用它,我会得到一个sun.net.www.protocol.http.HttpURLConnection $ HttpInputStream的实例,这并不是真的有用。
您是否了解如何使用CXF实现REST客户端,在HTTP状态代码大于400的情况下不会崩溃?
答案 0 :(得分:0)
我发现了问题。 问题出在方法中的org.apache.cxf.jaxrs.client.AbstractClient实现中
protected <T> T readBody(Response r, Message outMessage, Class<T> cls, Type type, Annotation[] anns);
如果服务器返回的HTTP代码大于400,则此方法不会将HTTP正文复制到Response对象。
最新版本2.6.16解决了这个问题。可以从ServerWebApplicationException中提取正文。
/* CXF does it for HTTP codes >400
*
* the original CXF (cxf-rt-frontend-jaxrs-2.6.14.jar) from tomEE 1.7.1
* does not provide the HTTP body in >400 case.
*
* We assume the usage of cxf-rt-frontend-jaxrs-2.6.16.jar here
*/
catch (ServerWebApplicationException e) {
resp = e.getMessage(); // here is the HTTP body!
}
我把它添加到我的pom.xml:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>2.6.16</version>
<scope>compile</scope>
</dependency>
这会让很多CXF JAR进入网络应用程序。结果tomEE不再起作用了。 CXF服务器部件不再起作用。
java.lang.ExceptionInInitializerError
...
Caused by: java.lang.IllegalArgumentException: interface org.apache.cxf.jaxrs.impl.tl.ThreadLocalProxy is not visible from class loader
结果我不能使用tomEE plus 1.7.1中的CXF WebClient。有什么建议?我将尝试使用apache HTTP客户端:(。