【问题标题】:Not Able to Successfully USE Validations in Spring REST Webservice无法在 Spring REST Web 服务中成功使用验证
【发布时间】:2020-04-19 05:40:10
【问题描述】:

我正在尝试在我的 SPRING REST-API 上应用验证,但我遇到了这个异常:

Apr 10, 2020 12:05:26 PM org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver doResolveHandlerMethodExceptionWARNING: Failed to invoke @ExceptionHandler method: public com.luv2code.springdemo.exceptionhandling.RestFieldErrorValidation com.luv2code.springdemo.exceptionhandling.GlobalExceptionHandler.processValidationError(org.springframework.web.bind.MethodArgumentNotValidException)org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class com.luv2code.springdemo.exceptionhandling.RestFieldErrorValidation    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:226)

实体类:

@Entity@Table(name="customer")
public class Customer {     

@Id 
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")  
private int id; 

@Column(name="first_name")
@NotNull(message = "Firstname is necessary")    
@Size(min=1,message="This field is required")
private String firstName;   

@Column(name="last_name")   
@NotNull(message = "Lastname is necessary") 
@Size(min=1,message="This field is required")
private String lastName;    

@Column(name="email")   
private String email;         
       // getters and setters
}

FieldValidation 处理程序类:

public class RestFieldError {

    private String field;    
    private String message;

    public RestFieldError() {

    }

    // getters and setters
}

public class RestFieldErrorValidation {

    private List<RestFieldError> fieldErrors = new ArrayList<>();

    public RestFieldErrorValidation() {

    }

    public void addFieldError(String path, String message) {
        RestFieldError error = new RestFieldError(path, message);
        fieldErrors.add(error);
    }

}

RestController 代码:

@RestController
@RequestMapping("/api")
public class CustomerRestController {

    // autowire the CustomerService
    @Autowired
    private CustomerService customerService;

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {
        System.out.println("Entered init binder");
        StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);
        dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
    }

// add the mapping for POST/customers (add a new customer)
    @PostMapping("/customers")
    @ResponseBody
    public Customer addCustomer(@Valid @RequestBody Customer theCustomer) {
        System.out.println("theCustomer :"+theCustomer.getFirstName());

        theCustomer.setId(0);
        customerService.saveCustomer(theCustomer);

        return theCustomer;
    }

}

异常处理类:

@ControllerAdvice
public class GlobalExceptionHandler {


    // Adding Validation Support on REST APIs--------------------------------------------------------->
        private MessageSource messageSource;

        @Autowired
        public GlobalExceptionHandler(MessageSource messageSource) {
            this.messageSource = messageSource;
        }   

        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseStatus(HttpStatus.BAD_REQUEST)
        @ResponseBody
        public RestFieldErrorValidation processValidationError(MethodArgumentNotValidException ex) {
            BindingResult result = ex.getBindingResult();
            List<FieldError> fieldErrors = result.getFieldErrors();

            return processFieldErrors(fieldErrors);
        }

        private RestFieldErrorValidation processFieldErrors(List<FieldError> fieldErrors) {
            RestFieldErrorValidation dto = new RestFieldErrorValidation();

            for (FieldError fieldError: fieldErrors) {
                String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);
                dto.addFieldError(fieldError.getField(), localizedErrorMessage);
            }

            return dto;
        }

        private String resolveLocalizedErrorMessage(FieldError fieldError) {
            Locale currentLocale =  LocaleContextHolder.getLocale();
            String localizedErrorMessage = messageSource.getMessage(fieldError, currentLocale);

            //If the message was not found, return the most accurate field error code instead.
            //You can remove this check if you prefer to get the default error message.
            if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) {
                String[] fieldErrorCodes = fieldError.getCodes();
                localizedErrorMessage = fieldErrorCodes[0];
            }

            return localizedErrorMessage;
        }

}

如果可以查看代码,这里是项目的google驱动链接:

https://drive.google.com/open?id=1QSFVMi3adHGkc7BqXsqAY0P_tO2UfT2I

这是我关注的文章:

https://www.petrikainulainen.net/programming/spring-framework/spring-from-the-trenches-adding-validation-to-a-rest-api/

【问题讨论】:

    标签: java spring spring-mvc spring-restcontroller hibernate-validator


    【解决方案1】:

    我假设您在这里使用的是普通 Spring,而不是 Spring Boot。

    问题是:您究竟想将RestFieldErrorValidation object 转换成什么? XML? JSON?

    对于任何一种情况,您都需要在类路径中使用适当的第三方库,以便 Spring 可以自动进行转换。

    对于 JSON,您可能希望将此依赖项添加到您的项目中。

      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.10.2</version>
      </dependency>
    

    【讨论】:

    • 是的,我只使用普通弹簧。此外,我的 pom.xml 文件中已经有了这个库依赖项
    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    相关资源
    最近更新 更多