如何从aop @before到spring Controller方法的建议获取更新/修改的httpservletrequest对象

发布于 2025-02-07 13:34:53 字数 1643 浏览 1 评论 0原文

我在Spring Boot应用程序中使用了Spring AOP @Before建议,并且在击中任何API之前应该执行。 我的任务/要求: - 如果未传递“请求标题”应用程序名称,则我们应该修改标题,并将每个API的应用程序名称添加到“未知”值中。 我正在使用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);
}

弹簧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;
     }
  }

I used Spring AOP @Before advice in Spring boot application, and it should execute before hitting any api's.
My task/requirement :- If in the request header application-name is not passed then we should modify the header and add to 'unknown' value to the application-name for every API.
I am modifying the header in the AOP @before advice using HttpServletWrapper class as shown below.

Problem is - the AOP should return updated HttpServletrequest to a controller method but it's not working, not returning the updated one in controller.

Controller:-

@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 code,

@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;
     }
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

[旋木] 2025-02-14 13:34:53

最后,我解决了这个问题,

而不是使用@before建议使用的@around建议,而应使用consge方法返回对象。

@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请求正在使用控制器方法。谢谢

Finally I resolved the issue,

Instead of using @Before advice used @Around advice, Around advice should return the object using proceed method.

@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});
    }
}

Updated httpservlet request is getting in controller method. Thanks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文