如何使用org.apache.cxf.jaxrs.client.WebClient而不获取ServerWebApplicationExceptions?

时间:2015-01-07 21:44:28

标签: rest cxf jax-rs

我在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的情况下不会崩溃?

1 个答案:

答案 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客户端:(。