如何在将请求体传递给控制器​​之前在 Spring 中对其进行预处理?

4 java spring servlets servlet-filters

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

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

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

oze*_*ray 5

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

您可以定义一个@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) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@PostMapping
public SampleDTO saveSample(@RequestBody Sample sample, HttpServletRequest request) { 
    //.....
}
Run Code Online (Sandbox Code Playgroud)