我想编写一个基于注释的api,它可以在我的库中记录,请求和响应。 基本上,计划是如果开发人员做了这样的事情:
@RequestMapping(value = "/todo", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
@CustomCopy
public void createNewTodo() {
我将复制请求和响应并将其转储到数据库中。我已经开始将HandlerInterceptorAdaptor
与afterComplete
一起使用,但这并没有成功,因为我无法复制响应,因为在调用Complete之后,响应已被刷新。
接下来,我打算使用OncePerRequestFilter
方法。基本上将其用作模板。
我只是想不通:
非常感谢您的帮助。
答案 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
注释。