用于修改请求的Servlet过滤器与CXF拦截器回复内容?

时间:2012-02-07 15:52:49

标签: java web-services cxf jax-rs

我们使用Apache CXF构建了一些REST(jax-rs)Web服务。他们返回JSON响应。

我现在需要修改一些请求参数和响应内容。 (基本上我们需要对服务返回的一些数据进行编码/加密;当在后续服务调用中将其用作参数时,解码/解密相同的数据。)

我觉得这里至少有4个选项:

  1. 使用Servlet过滤器
  2. 使用CXF Interceptor
  3. 使用JAX-RS过滤器
  4. 不要使用任何特定模式,并在实际服务逻辑中执行编码/解码。
  5. 之前我使用过Servlet过滤器,并且确切地了解如何修改请求参数和响应体,所以我倾向于这一点。但是,我愿意使用CXF Interceptor或JAX-RS过滤器,如果这是使用CXF时解决此问题的更“正确”的方法。但根据文档,我并不真正理解如何来做到这一点。例如,我是否使用Message对象的setContent方法来更改JSON响应?在这种情况下,format参数是什么,只是String.class?

1 个答案:

答案 0 :(得分:9)

在这里回答我自己的问题...我最终使用了JAX-RS过滤器,一旦我完成了缺少文档,它运行良好。我使用了http://cxf.apache.org/docs/jax-rs-filters.html中的(相当稀疏的)文档。注意尽管它的名字,JAX-RS过滤器是特定于CXF的野兽,不是JAX-RS标准的一部分(据我所知)。

以下是一些示例代码:

@Context
private HttpServletRequest httpRequest;
@Context
private UriInfo uriInfo;

/**
 * @see org.apache.cxf.jaxrs.ext.ResponseHandler#handleResponse(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.OperationResourceInfo, javax.ws.rs.core.Response)
 */
public Response handleResponse(Message message, OperationResourceInfo opResourceInfo, Response response) {
    try {

        // log the injected context data; useful for debugging CXF problems
        logContextData(httpRequest, uriInfo);

        OutputStream os = message.getContent(OutputStream.class);
        String relevantData = getDataFromRequest(httpRequest);
        message.setContent(OutputStream.class, new MyOutputStreamWrapper(os, relevantData));

    } catch (CustomException e) {
            // return some status that is related to CustomException
        return Response.status(Status.UNAUTHORIZED).build();
    } catch (Exception e) {
        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
    }

    return response;
}

/**
 * @see org.apache.cxf.jaxrs.ext.RequestHandler#handleRequest(org.apache.cxf.message.Message, org.apache.cxf.jaxrs.model.ClassResourceInfo)
 */
public Response handleRequest(Message message, ClassResourceInfo classResourceInfo) {
    try {

        // log the injected context data; useful for debugging CXF problems
        logContextData();

        String updatedQueryString = buildNewQueryString(this.uriInfo, httpRequest);

        message.put(Message.QUERY_STRING, updatedQueryString);


        // returning null tells CXF to continue the request (i.e. a non-null value would halt the request)
        return null;

    } catch (CustomException e) {
        // return some status that is related to CustomException
        return Response.status(Status.UNAUTHORIZED).build();
    } catch (Exception e) {
        return Response.status(Status.INTERNAL_SERVER_ERROR).build();
    }
}

我应该注意,MyOutputStreamWrapper的实现是修改响应内容的重要部分。由于安全考虑,我无法在此处包含该源(实际上我的实现具有不同的名称)。