处理CXF请求的前/后处理

时间:2016-11-01 14:34:45

标签: java filter jax-rs cxf interceptor

我们开始通过CRUD操作在服务器上审核客户端请求。

我们不想调用审计类来记录请求,而是使用CXF过滤器来预处理&后处理每个请求。我是什么意思?

我们希望审核每个更新请求(包含JSON)及其旧值(在更改之前,对数据库执行GET操作),但仅在之后将其记录到记录器中成功完成。

我们已经在抛出异常时使用此方法更改响应体(通过使用jaxsrs:providers标记和ExceptionMapper实现),但我无法理解如何将其用于前/后处理请求。

谢谢!

更新

我有点理解制作CXF拦截器需要做些什么:

  • 创建一个扩展AbstractPhaseInterceptor
  • 的班级
  • 在类构造函数中调用super(Phase.[the-needed-pahse])以确定拦截器何时运行(here是所有传入/传出阶段的列表)
  • 覆盖handleMessage,因为它是继承的方法,在这里你要写下你的逻辑
  • 将拦截器添加到项目的web.xml文件

例如:

public void handleMessage(Message request) throws Fault {       
    try {
        InputStream is = request.getContent(InputStream.class);
        String reqBodyAsString = org.apache.commons.io.IOUtils.toString(is, "UTF-8");
        IOUtils.closeQuietly(is);       
        // Do the logic
        is = org.apache.commons.io.IOUtils.toInputStream(reqBodyAsString, "UTF-8");
        request.setContent(InputStream.class, is);
        org.apache.commons.io.IOUtils.closeQuietly(is);
    } 
    catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

web.xml文件:

<jaxrs:server id="[id]" address="[URL]">
    <jaxrs:inInterceptors><!-- because we want it to run BEFORE the request logic -->
        <ref bean="[interceptor-id]" />
    </jaxrs:inInterceptors>
</jaxrs:server>

<bean id="[interceptor-id]" class="[package-path.interceptor-class-name]"/>

您可以看到,在阅读完内容后,我又将其写回请求中。那是因为我得到一个例外,说我的身体是null

这就是我被困的地方,我有一个拦截器,但在阅读了请求体之后,似乎逻辑无法继续。

1 个答案:

答案 0 :(得分:0)

您正在使用请求流。您需要在记录之前对其进行缓存,并在CXF消息中设置新流

public void handleMessage(Message message) {
      //Get the message body into payload[] and set a new non-consumed  inputStream into Message
      InputStream in = message.getContent(InputStream.class);
      byte payload[] = IOUtils.readBytesFromStream(in); //log this
      ByteArrayInputStream bin = new ByteArrayInputStream(payload);
    message.setContent(InputStream.class, bin);
 }

不需要关闭流。另请注意,您可以使用CXF默认日志记录拦截器https://stackoverflow.com/a/37820362/6371459