2014-04-22 13 views
7

Tôi có một bộ điều khiển Spring Rest đơn giản với một số xác nhận hợp lệ. Sự hiểu biết của tôi là thất bại xác nhận sẽ ném một MethodArgumentNotValidException. Tuy nhiên, mã của tôi ném một BindException thay thế. Trong thông báo gỡ lỗi, tôi cũng thấy ứng dụng trả về một ModelAndView rỗng.BindException được ném thay vì MethodArgumentNotValidException trong ứng dụng REST

Tại sao trình điều khiển còn lại sẽ ném BindException hoặc trả về một ModelAndView rỗng?

Lưu ý: Tôi đang thử nghiệm ứng dụng web của tôi sử dụng curl và làm cho một HTTP POST

curl -X POST http://localhost:8080/tasks 

Tôi cố tình bỏ qua "cái tên" tham số mà là một trường bắt buộc được đánh dấu bằng @NotNull và @NotBlank chú thích.

điều khiển của tôi:

@RestController 
public class TasksController { 

    private static Logger logger = Logger.getLogger(TasksController.class); 

    @Autowired 
    private MessageSource messageSource; 

    @Autowired 
    private Validator validator; 

    @InitBinder 
    protected void initBinder(WebDataBinder binder){ 
     binder.setValidator(this.validator); 
    }   


    @RequestMapping(value = "/tasks", method = RequestMethod.POST) 
    public Task createTask(@Valid TasksCommand tasksCommand){ 

     Task task = new Task(); 
     task.setName(tasksCommand.getName()); 
     task.setDue(tasksCommand.getDue()); 
     task.setCategory(tasksCommand.getCategory()); 

     return task; 
    } 
} 

class "lệnh" của tôi (có chứa chú thích xác nhận)

public class TasksCommand { 

    @NotBlank 
    @NotNull 
    private String name; 

    private Calendar due; 

    private String category; 

    ... getters & setters ommitted ... 
} 

lớp RestErrorHandler của tôi:

@ControllerAdvice 
public class RestErrorHandler { 

    private static Logger logger = Logger.getLogger(RestErrorHandler.class); 

    @Autowired 
    private MessageSource messageSource; 

    @ExceptionHandler(MethodArgumentNotValidException.class) 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    @ResponseBody 
    public ErrorsList processErrors(MethodArgumentNotValidException ex){ 
     logger.info("error handler invoked ..."); 
     BindingResult result = ex.getBindingResult(); 
     List<FieldError> fieldErrorList = result.getFieldErrors(); 

     ErrorsList errorsList = new ErrorsList(); 
     for(FieldError fieldError: fieldErrorList){ 
      Locale currentLocale = LocaleContextHolder.getLocale(); 
      String errorMessage = messageSource.getMessage(fieldError, currentLocale); 

      logger.info("adding error message - " + errorMessage + " - to errorsList"); 
      errorsList.addFieldError(fieldError.getField(), errorMessage); 
     } 

     return errorsList; 
    } 
} 

Phương pháp processErrors được đánh dấu bằng @ExceptionHandler (...) chú thích không bao giờ được gọi. Nếu tôi cố gắng nắm bắt một BindException bằng cách sử dụng chú thích @ExceptionHandler (...), thì phương thức xử lý đó sẽ được gọi.

Tôi có một vài lớp hỗ trợ - Tác vụ, TaskCommand, Lỗi và Danh sách lỗi - tôi có thể đăng mã nếu cần.

+0

Tôi gặp vấn đề tương tự trong '@ RestController' của tôi. Nó hoạt động khi tôi sử dụng '@ Controller' kết hợp với' @ RequestBody' và '@ ResponseBody'. Bạn có làm việc này bằng bất kỳ cơ hội nào không? – Dormouse

+0

Tôi vừa trả lời câu trả lời của tôi. Vui lòng xem bên dưới. Mặc dù vấn đề của bạn có thể khác. Nó sẽ hoạt động theo một trong hai cách. – Jigish

Trả lời

2

Sự cố xảy ra với lệnh curl của tôi.

curl -d gửi loại nội dung "application/x-www-form-urlencoded". Kết quả là, Spring giải thích dữ liệu dưới dạng dữ liệu biểu mẫu web (thay vì JSON). Spring sử dụng FormHttpMessageConverter để chuyển đổi phần thân của POST thành đối tượng miền và kết quả trong một BindException.

Điều chúng tôi muốn là Spring xử lý dữ liệu POST dưới dạng JSON và sử dụng MappingJackson2HttpMessageConverter để phân tích cú pháp nội dung POST thành đối tượng. Điều này có thể được thực hiện bằng cách xác định "Content-Type" tiêu đề với lệnh curl:

curl -X POST -H "Content-Type: application/json" -d '{"name":"name1", "due":"2014-DEC-31 01:00:00 PDT", "category":"demo"}' http://localhost:8080/tasks 

Xem bài đăng này cho làm thế nào để gửi dữ liệu JSON sử dụng curl: How to POST JSON data with Curl from Terminal/Commandline to Test Spring REST?

Ngoài ra, đây là tài liệu Mùa xuân có liên quan về MessageConverters: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestbody http://docs.spring.io/spring/docs/current/spring-framework-reference/html/remoting.html#rest-message-conversion

Các vấn đề liên quan