我在Spring引导应用程序中使用了Spring AOP @Before建议,它应该在碰到任何api之前执行。我的任务/需求:-如果在请求头中application-name没有传递,那么我们应该修改头并为每个API的application-name添加"unknown"值。我正在使用HttpServletWrapper类修改AOP @before通知中的头,如下所示。
问题是- AOP应该返回更新的HttpServletrequest到控制器方法,但它不工作,不返回更新的控制器.
控制器:
@GetMapping
@RequestMapping("/demo")
public ResponseEntity<String> getEmployee(HttpServletRequest request) {
System.out.println("Header, application-name"+request.getHeader("application-name"));
return new ResponseEntity<>("Success", HttpStatus.OK);
}
Spring AOP代码,
@Aspect
@Component
public class AOPExample {
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) ||"
+ "@annotation(org.springframework.web.bind.annotation.PostMapping)")
public void controllerRequestMapping() {}
@Before("controllerRequestMapping()")
public HttpServletRequest advice(JoinPoint jp) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String header = request.getHeader("application-name");
if (header == null) {
HttpServletRequestWrapperClass wrappedRequest = new HttpServletRequestWrapperClass(request);
wrappedRequest.putHeader("application-name", "Unknown");
request = wrappedRequest;
} else {
//validate application name
//400 - throw bad request exception
}
System.out.println("After setting---"+request.getHeader("application-name"));
return request;
}
}
最后我解决了这个问题,
Around通知应该使用proceed方法返回对象,而不是使用@Before通知。
@Aspect
@Component
public class AOPExample {
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping) ||"
+ "@annotation(org.springframework.web.bind.annotation.PostMapping)")
public void controllerRequestMapping() {}
@Around("controllerRequestMapping()")
public Object advice(ProceedingJoinPoint jp) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
.getRequest();
String header = request.getHeader("application-name");
System.out.println("Header in AOP"+header);
if (header == null) {
HttpServletRequestWrapperClass wrappedRequest = new HttpServletRequestWrapperClass(request);
wrappedRequest.putHeader("application-name", "Unknown");
request = wrappedRequest;
} else {
//validate application name
//400 - throw bad request exception
//throw new BadRequestException("Invalid application name");
}
System.out.println("After setting---"+request.getHeader("application-name"));
return jp.proceed(new Object[] {request});
}
}
更新的httpservlet请求正在进入控制器方法。由于