Как вернуть статус ошибки и ошибки проверки с этого контроллера Spring MVC? - PullRequest
8 голосов
/ 18 февраля 2012

У меня есть метод действия, определенный следующим образом на одном из моих контроллеров:

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Post create(@Valid Post post, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        // how to return an error status + error messages from here?
    } else {
        postRepository.persist(post);
        return post;
    }
}

Когда сообщение успешно сохраняется, я возвращаю сообщение обратно клиенту. Но когда он имеет ошибки проверки, я хочу вернуть клиенту код состояния ошибки и все сообщения об ошибках проверки.

Какой лучший способ сделать это?

Ответы [ 3 ]

6 голосов
/ 18 февраля 2012

Так как вы определяете API REST, вам нужно создать свой собственный Pojo (он же Ресурс), который будет представлять странное поведение или ошибки проверки, как заявлено horaceman.Я покажу вам, как мы это делаем в нашем приложении.

Поскольку мы используем JSON в качестве представления данных, мы хотим получить следующую информацию, если произойдет непредвиденное исключение.

{ "status" : "EXCEPTION", "exceptionName" : "MyCustomException", "exceptionMsg" : "ex.unsupportedOperation" }

Этопример конечно.Хорошим решением является то, что мы можем рассматривать exceptionMsg как ключ в нашем интерфейсе для отображения правильного i18n сообщения или отображения его пользователю как есть (в этом случае мы используем больше описательных сообщений).

Теперь, когда все в порядке, мы делаем что-то вроде этого:

{ "status" : "OK", "data" : {(...)} }

Data элемент является необязательным.Мы можем отправить все, что нам нужно, чтобы уведомить интерфейс или пропустить его полностью.

Последний сценарий будет вашим - ошибки проверки.В этом случае мы обычно отправляем следующее содержимое:

{ "status" : "VALIDATION_FAILED", "errors" : [ "fieldName" : "username", "errorCode" : "validation.requiredField", "errorMsg" : "Username is required."] }

Таким образом, клиенты API получат информацию о том, что проверка не прошла, и в соответствующих полях - точные сведения о том, что пошло не так.Конечно, errors - это массив (или List), поэтому мы всегда предоставляем столько деталей, сколько необходимо.

Как мне это сделать? Легко, эти объекты - простые POJOS, которыепереведены в JSON с использованием Jackson.Это дает мне неограниченные возможности представления в формате JSON.Я готовлю POJO, представляющий ошибки валидации (например), и добавляю его как Model к моему ModelAndView экземпляру.Тогда я просто полагаюсь на Spring для правильного маршалинга JSON.

В вашем случае у вас есть @ResponseBody аннотация с вашим экземпляром Post, так что, насколько я знаю, вы не сможете этого сделать.Ваша настройка говорит: «Что бы ни случилось, всегда возвращайте экземпляр Post».Что вам нужно сделать, это заменить его на простой ModelAndView, предоставить ему правильный Model на основе проверки и вернуть его клиентскому API.

4 голосов
/ 25 февраля 2012

Для @ResponseBody я бы удалил BindigResult из сигнатуры метода и разрешил исключение BindException.Затем я использовал бы метод @ExceptionHandler для возврата объекта, который содержит ошибки, как описано Ликачем.

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody Post create(@Valid Post post) {
    postRepository.persist(post);
    return post;
}

@ExceptionHandler
public ValidationErrors handleException(BindException ex) {
  // ...
}
3 голосов
/ 18 февраля 2012

Я думаю, что вы хотите сделать AJAX-вызов в вашем контроллере. вы возвращаете объект post в методе, поэтому невозможно вернуть другой объект (например, сообщение об ошибке с кодом). как насчет возврата вместо ExecutionResult?

ExecutionResult{
 private int statusCode;
 private String message;
 private Object yourPost;
 //get and set methods here...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...