Java 如何在失败时打印验证错误
给定以下dto和控制器Java 如何在失败时打印验证错误,java,spring-mvc,spring-boot,bean-validation,Java,Spring Mvc,Spring Boot,Bean Validation,给定以下dto和控制器 public class PasswordCredentials implements AuthenticationProvider { @NotNull @NotEmpty @JsonProperty( access = JsonProperty.Access.WRITE_ONLY ) private String user; @NotNull @NotEmpty @JsonProperty( access =
public class PasswordCredentials implements AuthenticationProvider {
@NotNull
@NotEmpty
@JsonProperty( access = JsonProperty.Access.WRITE_ONLY )
private String user;
@NotNull
@NotEmpty
@JsonProperty( access = JsonProperty.Access.WRITE_ONLY )
private CharSequence pass;
public void setPass( final CharSequence pass ) {
this.pass = pass;
}
public void setUser( final String user ) {
this.user = user;
}
@Override
public Authentication toAuthentication() {
return new UsernamePasswordAuthenticationToken( user, pass );
}
}
@RestController
@RequestMapping( path = "authentication" )
class AuthenticationController {
private final AuthenticationManager am;
AuthenticationController( final AuthenticationManager am ) {
this.am = am;
}
@RequestMapping( path = "password", method = RequestMethod.POST, consumes = {
"!" + MediaType.APPLICATION_FORM_URLENCODED_VALUE
} )
ResponseEntity<?> login( @Valid @RequestBody final PasswordCredentials credentials ) {
Authentication authenticate = am.authenticate( credentials.toAuthentication() );
if ( authenticate.isAuthenticated() ) {
return ResponseEntity.status( HttpStatus.NO_CONTENT ).build();
}
return ResponseEntity.status( HttpStatus.FORBIDDEN ).build();
}
}
Spring具有
@ControllerAdvice
和@ExceptionHandler
注释来处理控制器中的错误
class RestConfig extends RepositoryRestConfigurerAdapter {
@Bean
Validator validator() {
return new LocalValidatorFactoryBean();
}
@Override
public void configureValidatingRepositoryEventListener(
final ValidatingRepositoryEventListener validatingListener ) {
Validator validator = validator();
//bean validation always before save and create
validatingListener.addValidator( "beforeCreate", validator );
validatingListener.addValidator( "beforeSave", validator );
}
@Override
public void configureRepositoryRestConfiguration( final RepositoryRestConfiguration config ) {
config.setBasePath( "/v0" );
config.setReturnBodyOnCreate( false );
config.setReturnBodyOnUpdate( false );
}
@ControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Error processValidationError(MethodArgumentNotValidException ex) {
BindingResult result = ex.getBindingResult();
.....
return new Error();
}
// Other exceptions
}
我想改进Anton Novopashin的答案:只需在响应实体中返回错误
@ControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<String> processValidationError(MethodArgumentNotValidException ex) {
return new ResponseEntity(ex.getMessage, HttpStatus.BAD_REQUEST);
}
// Other exceptions
}
@ControllerAdvice
公共类例外Translator{
@ExceptionHandler(MethodArgumentNotValidException.class)
@应答器
公共响应验证过程错误(MethodArgumentNotValidException ex){
返回新的响应属性(例如getMessage、HttpStatus.BAD_请求);
}
//其他例外情况
}
我不确定是谁或为什么否决了现有答案,但它们都是正确的-处理验证错误的最佳方法是声明一个@ControllerAdvice
,然后在那里处理异常。下面是我的全局错误处理程序的一个片段,取自现有项目:
@ControllerAdvice
@ResponseBody
public class RestfulErrorHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ErrorResponse methodValidationError(MethodArgumentNotValidException e) {
final ErrorResponse response = new ErrorResponse();
for (ObjectError error : e.getBindingResult().getAllErrors()) {
if (error instanceof FieldError) {
response.addFieldError((FieldError) error);
} else {
response.addGeneralError(error.getDefaultMessage());
}
}
return response;
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ConstraintViolationException.class)
public ErrorResponse constraintViolationError(ConstraintViolationException e) {
final ErrorResponse response = new ErrorResponse();
for (ConstraintViolation<?> v : e.getConstraintViolations()) {
response.addFieldError(v.getPropertyPath(), v.getMessage());
}
return response;
}
}
@ControllerAdvice
@应答器
公共类RestfulErrorHandler{
@ResponseStatus(HttpStatus.BAD_请求)
@ExceptionHandler(MethodArgumentNotValidException.class)
公共ErrorResponse methodValidationError(MethodArgumentNotValidException e){
最终错误响应=新的错误响应();
对于(ObjectError错误:e.getBindingResult().getAllErrors()){
if(错误实例of FieldError){
响应。addFieldError((FieldError)错误);
}否则{
addGeneralError(error.getDefaultMessage());
}
}
返回响应;
}
@ResponseStatus(HttpStatus.BAD_请求)
@ExceptionHandler(ConstraintViolationException.class)
公共错误响应constraintViolationError(ConstraintViolationException e){
最终错误响应=新的错误响应();
for(constraintviolationv:e.getConstraintViolations()){
addFieldError(v.getPropertyPath(),v.getMessage());
}
返回响应;
}
}
您还应该处理ConstraintViolationException
s,因为它们也可能被抛出。这里是,我把它作为一个要点,以免混淆要点
您可能还应该处理,我不确定spring数据rest
是否已经处理了它们