【问题标题】:Get Request/Response Body&Header in Spring AOP在 Spring AOP 中获取请求/响应正文和标头
【发布时间】:2020-05-28 14:23:51
【问题描述】:

我想在我的方面前后获取请求/响应正文和标头(如果可用或如何获取它们)。

我的意思是我认为之前的注释应该是为请求工作的,

with after 注释应该可以用于响应。可 ?

到目前为止我所做的尝试:

我尝试了日志库,它对我来说非常复杂,我不知道如何使用它。所以我放弃了。

执行器可以发挥作用,但我正在做额外的工作,例如端点调用的次数等。因此我不能使用执行器。

我也尝试获取至少如下所示的请求标头,但我认为这些标头始终相同。我无法像 httpservetrequest 那样获得 httpservletresponse。

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

那么 request.getHeader("date") 但是 requestbody 呢?

如何获取 requestbody ?响应体?响应头?

我的方面文件:

@Aspect
@Component
public class AppAspect implements ResponseInfo{

    @Before("execution(@(@org.springframework.web.bind.annotation.RequestMapping *) * *(..))")
    public void loggingStartPointRequests(JoinPoint joinPoint) {

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

}

@After("execution(@(@org.springframework.web.bind.annotation.RequestMapping *) * *(..))")
    public void loggingEndPointRequests(JoinPoint joinPoint) throws IOException {

    }

}

我的控制器类:

@RestController
public class MainController {

    @GetMapping("/people") // 
    public ResponseEntity<Poeple> getAllPeople(@RequestParam(name = "page", required = false) Integer page,
            @RequestParam(name = "size", required = false) Integer size,
            @RequestParam(name = "sortBy", required = false) Boolean sortByNameOrEpCount) {
doSomething();
}

}

【问题讨论】:

  • 请求和响应正文只能读取一次,除非进行了一些特殊处理。您是否还可以使用要求或您希望在某个方面阅读这些内容的原因来更新问题?
  • 其实不需要使用Aspect。如果我们可以在控制器方法中以某种方式做到这一点,那应该没问题。所以我的意思是我们可以在控制器方法中获取所有标题和正文吗?我只是认为获取请求和响应标头正文只能获取内部方面。我问了那个。
  • Aspect 与否,请求/响应正文只能读取一次,除非它被操作为可重新读取。如果您可以更新有关为什么在控制器中需要这些信息的要求,知识渊博的人可以分享想法。获取请求/响应正文的目的是什么?

标签: spring http aop spring-aop actuator


【解决方案1】:

我认为您需要实现接口HandlerInterceptor,它将帮助您能够检查请求和响应。例如:

public class ApiMonitor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    // when the client access to your endpoint
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    // when you finished your process 
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    // after you already returned an answer to the client
}
}

如果您想在将返回的对象发送给客户端之前对其进行操作,那么您需要 AOP,是的。这是一个示例,说明我如何在某些端点上修改某个对象,然后再将其解析为 json。

@Component
@Aspect
public class MyCustomAOPInterceptor {

/**
* These poincuts check the execution of a method in any (*) 
* class of my.package.controller and that start with
* get/list/find plus any other word (*) . For example
* my.package.controller.UserController.getUserById()
*/
@Pointcut("execution(* my.package.controller.*.get*(..))")
public void petitionsStartWithGet() { }

@Pointcut("execution(* my.package.controller.*.list*(..))")
public void petitionsStartWithList() { }

@Pointcut("execution(* my.package.controller.*.find*(..))")
public void petitionsStartWithFind() { }

@AfterReturning(pointcut = "petitionsStartWithGet() || petitionsStartWithList() || petitionsStartWithFind()", returning = "result")
public void translateEntities(JoinPoint joinPoint, Object result) {
    // do your stuff; result is the object that you need
}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2011-06-14
    • 2015-02-18
    • 2020-05-23
    • 2012-05-02
    • 1970-01-01
    相关资源
    最近更新 更多