Невозможно успешно использовать валидации в Spring REST Webservice - PullRequest
0 голосов
/ 19 апреля 2020

Я пытаюсь применить проверки к моему 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 Drive проекта, если вы можете проверить код:

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/

1 Ответ

0 голосов
/ 19 апреля 2020

Я предполагаю, что вы используете здесь простой 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>
...