如何发送自定义JSON错误而不是spring提供的错误?我需要自定义验证和默认验证,如@NotNull, @NotEmpty, @Email
等等。
只有在未违反POJO
类级别的验证约束时才会触发该函数
package com.flasher.controller.rest;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.flasher.dto.UserRegistrationInfo;
import com.flasher.service.RegistrationService;
import com.flasher.validator.UserRegistrationInfoValidator;
@RestController
@RequestMapping(value = "/api")
public class RegistrationControllerRest {
@Autowired
RegistrationService registrationService;
@Autowired
UserRegistrationInfoValidator userRegistrationInfoValidator;
@RequestMapping(value = "/v1/user", method = RequestMethod.POST)
public void registerUser(@RequestBody @Valid UserRegistrationInfo userRegistrationInfo, HttpServletRequest request,
BindingResult bindingResult) {
userRegistrationInfoValidator.setRemoteAddr(request.getRemoteAddr());
userRegistrationInfoValidator.validate(userRegistrationInfo, bindingResult);
if(bindingResult.hasErrors()){
System.out.println("has errors--");
List<FieldError> fieldErrors =bindingResult.getFieldErrors();
fieldErrors.stream().forEach(fieldError->{
System.out.println(fieldError.getField()+" "+fieldError.getDefaultMessage());
});
}
}
}
package com.flasher.dto;
import javax.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
public class UserRegistrationInfo {
@NotNull
@NotEmpty
@Length(min = 4, max = 30)
private String userName;
@NotNull
@NotEmpty
@Email
private String email;
@NotNull
@NotEmpty
@Length(min = 4, max = 15)
private String password;
@NotNull
@NotEmpty
private String reCaptcha;
@NotNull
private Boolean isAgreedTerms;
public UserRegistrationInfo() {
}
public UserRegistrationInfo(String userName, String email, String password, String reCaptcha,
Boolean isAgreedTerms) {
this.userName = userName;
this.email = email;
this.password = password;
this.reCaptcha = reCaptcha;
this.isAgreedTerms = isAgreedTerms;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getReCaptcha() {
return reCaptcha;
}
public void setReCaptcha(String reCaptcha) {
this.reCaptcha = reCaptcha;
}
public Boolean getIsAgreedTerms() {
return isAgreedTerms;
}
public void setIsAgreedTerms(Boolean isAgreedTerms) {
this.isAgreedTerms = isAgreedTerms;
}
}
package com.flasher.validator;
import java.util.regex.Pattern;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.flasher.dto.UserRegistrationInfo;
import com.flasher.util.GoogleReCaptchaChecker;
public class UserRegistrationInfoValidator implements Validator {
@Autowired
GoogleReCaptchaChecker googleReCaptchaChecker;
String remoteAddr;
@Override
public boolean supports(Class<?> className) {
return UserRegistrationInfo.class.equals(className);
}
@Override
public void validate(Object obj, Errors errs) {
UserRegistrationInfo userRegistrationInfo = (UserRegistrationInfo) obj;
if(Pattern.compile("[^\\w]").matcher(userRegistrationInfo.getUserName()).find()){
errs.rejectValue("userName","", "Username cannot contain special characters");
}
if(Pattern.compile("[^(\\w!@#$%^&*())]").matcher(userRegistrationInfo.getUserName()).find()){
errs.rejectValue("userName","", "Password cannot contain disallowed characters");
}
if(!userRegistrationInfo.getIsAgreedTerms()){
errs.rejectValue("isAgreedTerms", "you have to agree the terms and condition in order to register");
}
if(!googleReCaptchaChecker.validateGoogleReCaptcha(userRegistrationInfo.getReCaptcha(),remoteAddr)){
errs.rejectValue("reCaptcha", "","invalid reCaptcha");
}
}
public void setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
}
}
{
"timestamp": 1487250555542,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.web.bind.MethodArgumentNotValidException",
"errors": [
{
"codes": [
"Length.userRegistrationInfo.userName",
"Length.userName",
"Length.java.lang.String",
"Length"
],
"arguments": [
{
"codes": [
"userRegistrationInfo.userName",
"userName"
],
"arguments": null,
"defaultMessage": "userName",
"code": "userName"
},
30,
4
],
"defaultMessage": "length must be between 4 and 30",
"objectName": "userRegistrationInfo",
"field": "userName",
"rejectedValue": "",
"bindingFailure": false,
"code": "Length"
},
{
"codes": [
"NotEmpty.userRegistrationInfo.userName",
"NotEmpty.userName",
"NotEmpty.java.lang.String",
"NotEmpty"
],
"arguments": [
{
"codes": [
"userRegistrationInfo.userName",
"userName"
],
"arguments": null,
"defaultMessage": "userName",
"code": "userName"
}
],
"defaultMessage": "may not be empty",
"objectName": "userRegistrationInfo",
"field": "userName",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotEmpty"
}
],
"message": "Validation failed for object='userRegistrationInfo'. Error count: 2",
"path": "//api/v1/user"
}
答案 0 :(得分:2)
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ValidationErrorResponse handleMathodArgumentNotValidException(
MethodArgumentNotValidException methodArgumentNotValidException) {
BindingResult bindingResult = methodArgumentNotValidException.getBindingResult();
List<ValidationError> validationErrors = new ArrayList<ValidationError>();
if (bindingResult.hasErrors()) {
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
fieldErrors.stream().forEach(fieldError -> {
validationErrors.add(new ValidationError(fieldError.getField(), fieldError.getDefaultMessage()));
});
}
return new ValidationErrorResponse(validationErrors);
}
答案 1 :(得分:0)
像这样创建pojo:
public class ValidationError {
private String name;
private String msg;*
并创建另一个pojo:
public class ValidationErrorResponse {
private List<ValidationError> errors;
添加此方法:
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ValidationErrorResponse handleValidationException(
BindingResult exception) {
List<ValidationError> errors = new ArrayList<ValidationError>();
for (ObjectError er : exception.getAllErrors()) {
FieldError fl = (FieldError) er;
errors.add(new ValidationError(fl.getField(), er
.getDefaultMessage()));
}
return new ValidationErrorResponse(errors);
}
并更改您的方法:
@RequestMapping(value = "/v1/user", method = RequestMethod.POST)
public ResponseEntity<?>registerUser(@RequestBody @Valid UserRegistrationInfo userRegistrationInfo, HttpServletRequest request,
BindingResult bindingResult) {
if(bindingResult.hasErrors()){
return new ResponseEntity<ValidationErrorResponse>(
handleValidationException(br), HttpStatus.BAD_REQUEST);
}
// your bussines logic here
return new ResponseEntity ....
}