基于注释应用一次

时间:2018-08-10 22:43:04

标签: java spring spring-boot aop

我想编写一个基于注释的api,它可以在我的库中记录,请求和响应。 基本上,计划是如果开发人员做了这样的事情:

@RequestMapping(value = "/todo", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
@CustomCopy
public void createNewTodo() {

我将复制请求和响应并将其转储到数据库中。我已经开始将HandlerInterceptorAdaptorafterComplete一起使用,但这并没有成功,因为我无法复制响应,因为在调用Complete之后,响应已被刷新。

接下来,我打算使用OncePerRequestFilter方法。基本上将其用作模板。

我只是想不通:

  • 如何将注释与过滤器连接起来?
  • 如果还有另一种方法,我可以使用注释,也可以使用请求和响应正文。
  • 我打算用来研究AOP,但仍然没有弄清楚。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

使用AOP,您可以这样做:

依赖性

compile 'org.aspectj:aspectjweaver:{version}'

创建注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomCopy {

}

保存请求响应:

@Aspect
@Component
public class SaveRequestResponse {
    @Around("@annotation(CustomCopy)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

        //Request build
        ContentCachingRequestWrapper request = getWrapper(joinPoint);
        StringBuilder apiLog = new StringBuilder();
        apiLog.append("Rest API: ").append(request.getRequestURL().toString()).append("\n");
        apiLog.append("Body:").append(getRequestBody(request)).append("\n");

        for (String header : Collections.list(request.getHeaderNames())) {
            apiLog.append(header).append(":").append(request.getHeader(header))
                    .append("\n");
        }
        //Request build end

        //method called
        Object proceed = joinPoint.proceed();

        //after method called response
        String response = new ObjectMapper().writeValueAsString(proceed);
        //save apiLog(Full request) && response
        return proceed;
    }
    private String getRequestBody(final ContentCachingRequestWrapper wrapper) {
        String payload = null;
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                try {
                    int maxLength = buf.length > 500 ? 500 : buf.length;
                    payload = new String(buf, 0, maxLength,
                            wrapper.getCharacterEncoding());
                } catch (UnsupportedEncodingException e) {
                    logger.error("UnsupportedEncoding.", e);
                }
            }
        }
        return payload;
    }
    private ContentCachingRequestWrapper getWrapper(ProceedingJoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        ContentCachingRequestWrapper request = null;
        for (Object arg : args) {
            if (arg instanceof ContentCachingRequestWrapper) {
                request = (ContentCachingRequestWrapper) arg;
                break;
            }
        }
        return request;
    }
}

现在在控制器方法中使用此@CustomCopy注释。