我正在开发一个大型的Spring Boot代码库,试图在其中引入请求标头验证。
这是我的示例控制器:
import javax.validation.constraints.Size;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Validated
@RequestMapping("/abc/test/v1")
public class TestController {
@GetMapping("/testMethod")
public String testMethod(@RequestHeader
@Size(min = 10, message = "Not valid header") String foo) {
return foo;
}
}
这是@ControllerAdvice
错误处理程序:
import java.util.LinkedList;
import java.util.List;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.abc.test.exception.RequestParamValidationException;
@SuppressWarnings({ "unchecked", "rawtypes" })
@ControllerAdvice
@RequestMapping( produces = MediaType.APPLICATION_JSON_VALUE)
public class ValidationExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<RequestParamValidationException> handleConstraintVoilationexception(ConstraintViolationException ex, WebRequest req) {
List<String> details = new LinkedList<>();
for(ConstraintViolation<?> violation : ex.getConstraintViolations()) {
details.add(violation.getMessage());
}
RequestParamValidationException exception = new RequestParamValidationException
("Request Param Validation Failed", details);
return new ResponseEntity(exception, HttpStatus.BAD_REQUEST);
}
}
这是我的项目的最小可复制示例,但我没有其他错误处理程序。
即使我应该得到一个ConstraintVoilationexception
,但是MissingRequestHeaderException
仍然由一个我尚未声明的神秘错误处理程序处理,正如我从日志中看到的那样:
2020-06-08 10:49:10.655 WARN 3180 --- [0.0-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingRequestHeaderException: Missing request header 'foo' for method parameter of type String]
它永远不会到达我的异常处理程序。
我如何找出这个神秘的异常处理程序是什么?
谢谢。
答案 0 :(得分:1)
首先,您需要定义ValidationExceptionHandler的顺序
这是通过注释@Order(Ordered.HIGHEST_PRECEDENCE)
第二,您需要重写方法,因为MissingRequestHeaderException
是ServletRequestBindingException
的子类
@Override
protected ResponseEntity<Object> handleServletRequestBindingException(
final ServletRequestBindingException ex,
final HttpHeaders headers,
final HttpStatus status,
final WebRequest request
) {
return super.handleServletRequestBindingException(ex, headers, status, request);
}
答案 1 :(得分:0)
MissingRequestHeaderException
是ServletRequestBindingException
的子类。默认情况下,扩展ResponseEntityExceptionHandler将自动为您提供各种方法来处理不同的异常。方法之一是 handleServletRequestBindingException 。
因此,您的MissingRequestHeaderException由 ResponseEntityExceptionHandler 方法处理。
如果必须验证,请转到IDE中的ResponseEntityExceptionHandler代码。 希望这会有所帮助。