使用拦截器记录REST服务但无法记录请求和响应

时间:2018-05-16 07:13:48

标签: java spring logging interceptor

我有一些REST服务,我想记录请求和响应。他们收到一个JSON请求并生成另一个JSON响应。我创建了一个拦截器但是我无法获得请求/响应主体。这是我的cxf配置:

<bean id="ContextInInterceptor" class="main.interceptors.ContextMessageInInterceptor"></bean>
<bean id="ContextOutInterceptor" class="main.interceptors.ContextMessageOutInterceptor"></bean>
<bean id="ContextJSONInInterceptor" class="main.interceptors.ContextJSONInInterceptor"></bean>
<bean id="ContextJSONOutInterceptor" class="main.interceptors.ContextJSONOutInterceptor"></bean>

<cxf:bus>
   <cxf:features>
      <cxf:logging/>
   </cxf:features>

   <cxf:inInterceptors>
      <ref bean="ContextInInterceptor"/>
   </cxf:inInterceptors>
   <cxf:outInterceptors>
      <ref bean="ContextOutInterceptor"/>
   </cxf:outInterceptors>
</cxf:bus>

这是我的拦截器代码:

public class ContextMessageInInterceptor extends AbstractPhaseInterceptor<org.apache.cxf.message.Message> {

       @Autowired
       ContextJSONInInterceptor contextJSONInInterceptor;

       public ContextMessageInInterceptor() {
           super(Phase.PRE_INVOKE);
       }

       @Override
       public void handleMessage(Message message) {
           contextJSONInInterceptor.handleMessage(message);
       }
}

public class ContextJSONInInterceptor extends AbstractPhaseInterceptor<Message> {

    public ContextJSONInInterceptor() {
        super(Phase.PRE_INVOKE);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        System.out.println("Content-Type: " + message.get(Message.CONTENT_TYPE));
        System.out.println(message.toString());
        System.out.println("---------------");
    }
}

public class ContextMessageOutInterceptor extends AbstractPhaseInterceptor<Message> {

    @Autowired
    ContextJSONOutInterceptor contextJSONOutInterceptor;

    public ContextMessageOutInterceptor() {
        super(Phase.WRITE);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        contextJSONOutInterceptor.handleMessage(message);
    }
}

public class ContextJSONOutInterceptor extends AbstractPhaseInterceptor<Message> {

    public ContextJSONOutInterceptor() {
        super(Phase.WRITE);
    }

    @Override
    public void handleMessage(Message message) throws Fault {
        System.out.println("Content-Type: " + Message.CONTENT_TYPE);
        System.out.println(message.toString());
        System.out.println("---------------");
    }

}

ContextMessageInInterceptor和ContextMessageOutInterceptor分别正常运行,它们分别转到ContextJSONInInterceptor和ContextJSONOutInterceptor,但我不知道如何从这些拦截器中获取请求/响应主体。我试图使用“消息”常量,内容类型就是我得到的。

任何人都知道如何从这些拦截器获取请求/响应主体?

非常感谢你的时间。

2 个答案:

答案 0 :(得分:1)

而不是拦截器,AOP将是一个不错的选择。您可以在请求/响应流量通过的控制器方法中应用它。要在请求范围内获取请求对象,您可以执行以下操作:

HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
            .getRequest();

答案 1 :(得分:0)

您有两种选择:使用HandlerInterceptor,您可以看到请求和方法,通过一些反思,您可以获得一些可能是您需要的信息。

public class ApiInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // code
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//code
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
   // code
    }
}

第二个选项是Spring AOP(可以是互补的)。您可以使用针对所有@RequestMapping()注释的切入点,以及将在您想要的确切时刻执行的建议。我不久前就asked (and answered) a question这个问题。