【问题标题】:How to pre-process the request body in Spring before passing it to the a Controller?如何在将请求主体传递给控制器​​之前在 Spring 中对其进行预处理?
【发布时间】:2012-04-23 18:55:51
【问题描述】:

我正在实现一个 RESTful 服务,我想在将 XML 传递到 CastorUnmarshaller 之前,在拦截器中针对 XSD 验证 XML。 不过,在WebRequestInterceptor 中,我必须阅读只能读取一次的请求正文,因此解组器无法读取它。有办法吗?

我知道我可以在 Controller 中手动进行验证和解组,但我想使用 @RequestBody <DomainObject> 方式解组它。

或者,作为另一种解决方案,有没有办法告诉CastorUnmarshaller 针对 xsd 验证它?

【问题讨论】:

    标签: java spring servlets servlet-filters


    【解决方案1】:

    很长一段时间过去了,但其他人可能会从中受益:

    您可以定义一个@Around 方面并拦截传入的请求及其各自的主体,如下所示:

    @Aspect
    @Component
    public class RequestResponseLoggingAdvice {
    
        private static final Logger logger = LoggerFactory.getLogger(RequestResponseLoggingAdvice.class);
    
        @Pointcut("within(@org.springframework.web.bind.annotation.RestController*)") 
        public void restcontroller() {}
    
        @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)") 
        public void postmapping() {}
    
        @Around("restcontroller() && postmapping() && args(.., @RequestBody body, request)") 
        public Object logPostMethods(ProceedingJoinPoint joinPoint, Object body, HttpServletRequest request) throws Throwable {
            logger.debug(request.toString()); // You may log request parameters here.
            logger.debug(body.toString()); // You may do some reflection here
    
            Object result;
            try {
                result = joinPoint.proceed();
                logger.debug(result.toString());
            } catch(Throwable t) {}
        }
    }
    

    请注意,您的 REST 控制器方法必须具有适合上述方面的签名才能挂钩。示例如下:

    @PostMapping
    public SampleDTO saveSample(@RequestBody Sample sample, HttpServletRequest request) { 
        //.....
    }
    

    【讨论】:

    • 谢谢你!我不知道我可以在切入点中指定@RequestBody,
    【解决方案2】:

    您可能可以附加一个@Before 方面(spring AOP)。在那里,您可以获得与传递给控制器​​方法相同的请求正文参数。

    另一种选择是将请求包装成一个支持多次读取正文的请求(通过第一次缓存)

    【讨论】:

      【解决方案3】:

      过滤器也可用于验证通过的 XML。 org.springframework.oxm.castor.CastorMarshaller 有一个 validating 属性来启用对传入和传出文档的验证。 但是必须解决在 Spring-MVC 的默认编组器中启用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-10
        • 1970-01-01
        • 2022-09-24
        • 2023-03-19
        • 2015-02-14
        • 2019-03-31
        • 2021-11-21
        • 2017-01-08
        相关资源
        最近更新 更多