Java OncePerRequestFilter中的返回体
更新: 在与一位同事研究过这一点之后,这可能是因为Spring应用程序在Tomcat服务器上运行,该服务器遵循标准协议(),并且不会返回HEAD请求的正文 ===================== 我的OncePerRequestFilter设计用于拒绝任何HEAD请求,如您在此处所见:Java OncePerRequestFilter中的返回体,java,spring,spring-boot,spring-mvc,Java,Spring,Spring Boot,Spring Mvc,更新: 在与一位同事研究过这一点之后,这可能是因为Spring应用程序在Tomcat服务器上运行,该服务器遵循标准协议(),并且不会返回HEAD请求的正文 ===================== 我的OncePerRequestFilter设计用于拒绝任何HEAD请求,如您在此处所见: @Component public class RestrictedResponseFilter extends OncePerRequestFilter { @Autowired @Qua
@Component
public class RestrictedResponseFilter extends OncePerRequestFilter {
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Override
public void doFilterInternal(HttpServletRequest httpRequest, HttpServletResponse httpServletResponse, FilterChain chain) throws IOException, ServletException {
if(httpRequest.getMethod().equals(HttpMethod.HEAD.name())){
resolver.resolveException(httpRequest,httpServletResponse,null,new RequestRejectedException("Http Method HEAD rejected"));
} else {
chain.doFilter(httpRequest,httpServletResponse);
}
}
}
resolver.resolveException通过我的ResponseEntityExceptionHandler类发送请求:
@CrossOrigin("*")
@Slf4j
@RestControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);
...
@ExceptionHandler(RequestRejectedException.class)
public ResponseEntity handleRequestRejectedException(final RequestRejectedException e, final WebRequest request){
logger.error(e.getMessage(), e);
return handleExceptionInternal(e,null,null,HttpStatus.FORBIDDEN,request);
}
private SpringErrorSwaggerDefinition buildResponse(final Exception e, final WebRequest request, final HttpStatus status){
final SpringErrorSwaggerDefinition cvdosResponse = SpringErrorSwaggerDefinition.builder()
.message(e.getMessage())
.timestamp(System.currentTimeMillis())
.error(status.getReasonPhrase())
.exception(e.getClass().getName())
.path(request.getContextPath())
.status(status.value())
.build();
return cvdosResponse;
}
@Override
protected ResponseEntity<Object> handleExceptionInternal(
Exception ex, @Nullable Object body, @Nullable HttpHeaders headers, HttpStatus status, WebRequest request) {
final SpringErrorSwaggerDefinition response = buildResponse(ex,request,status);
return new ResponseEntity<>(response, status);
}
}
@交叉原点(“*”)
@Slf4j
@再控制建议
公共类MyExceptionHandler扩展了ResponseEntityExceptionHandler{
私有静态最终记录器Logger=LoggerFactory.getLogger(MyExceptionHandler.class);
...
@ExceptionHandler(RequestRejectedException.class)
公共响应HandlerRequestRejectedException(最终请求拒绝Exception e,最终WebRequest请求){
logger.error(e.getMessage(),e);
返回handleExceptionInternal(e,null,null,HttpStatus.FORBIDDEN,request);
}
私有SpringErrorSwaggerDefinition构建响应(最终异常e、最终WebRequest请求、最终HttpStatus状态){
最终SpringErrorSwaggerDefinition CVDOSSResponse=SpringErrorSwaggerDefinition.builder()
.message(如getMessage())
.timestamp(System.currentTimeMillis())
.error(status.getReasonPhrase())
.exception(例如getClass().getName())
.path(请求.getContextPath())
.status(status.value())
.build();
返回响应;
}
@凌驾
受保护的响应安全句柄内部异常(
异常(例如,@Nullable对象体,@Nullable HttpHeaders标头,HttpStatus状态,WebRequest请求){
最终SpringErrorSwaggerDefinition响应=构建响应(例如,请求,状态);
返回新的ResponseEntity(响应、状态);
}
}
此类中处理的其他异常返回SpringErrorSwaggerDefinition响应主体。但是,通过过滤器时不会发生这种情况。我如何解决这个问题?那么你的意思是说流没有到达
HandlerRequestRejectedException
方法吗?@Jignesh M.Khatri,流正在到达ExceptionHandler,因为在调试模式下查看它显示流构建了SpringErrorSwaggerDefinition对象,但是当我在Postman中调用它时,响应中没有主体。换句话说,我得到的只是403响应代码和通用头。当然会的。您直接调用的组件是SpringMVC错误处理的一部分。但是,您只调用组件,而没有在SpringMVC的范围内调用该组件(在SpringMVC有机会做任何事情之前,它是在过滤方式的范围内调用的)。因此,您正在调用的冲突解决程序没有做多少工作。返回的ModelAndView
(通常用于由Spring MVC呈现响应)被完全忽略。@请调用resolver,而不是调用resolveException。resolveException
尝试直接抛出异常。