Я использую Spring MVC для простого JSON API с @ResponseBody
подходом, основанным на следующем. (У меня уже есть сервисный слой, производящий JSON напрямую.)
@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
String json = matchService.getMatchJson(matchId);
if (json == null) {
// TODO: how to respond with e.g. 400 "bad request"?
}
return json;
}
Вопрос в данном сценарии, каков самый простой и чистый способ ответить ошибкой HTTP 400 ?
Я сталкивался с подходами, такими как:
return new ResponseEntity(HttpStatus.BAD_REQUEST);
... но я не могу использовать его здесь, поскольку тип возвращаемого значения моего метода - String, а не ResponseEntity.
java
spring
spring-mvc
http-error
Jonik
источник
источник
ResponseEntity
это. Это прекрасно работает и представляет собой простое изменение исходного кода - спасибо!Нечто подобное должно работать, я не уверен, существует ли более простой способ:
источник
body
иrequest
params.)Не обязательно самый компактный способ сделать это, но довольно чистый ИМО
Редактировать вы можете использовать @ResponseBody в методе обработки исключений, если используете Spring 3.1+, в противном случае используйте a
ModelAndView
или что-то еще.https://jira.springsource.org/browse/SPR-6902
источник
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public controller.TestController$MyError controller.TestController.handleException(controller.TestController$BadThingException) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
что-то отсутствует в ответе?javax.validation.ValidationException
вместо этого. (Весна 3.1.4)Я бы немного изменил реализацию:
Сначала я создаю
UnknownMatchException
:Обратите внимание на использование @ResponseStatus , которое будет распознаваться Spring'ом
ResponseStatusExceptionResolver
. Если выброшено исключение, оно создаст ответ с соответствующим статусом ответа. (Я также позволил себе сменить код состояния,404 - Not Found
который я считаю более подходящим для этого варианта использования, но вы можете придерживаться его,HttpStatus.BAD_REQUEST
если хотите.)Далее я бы изменил,
MatchService
чтобы иметь следующую подпись:Наконец, я хотел бы обновить контроллер и делегат в Spring
MappingJackson2HttpMessageConverter
для автоматической обработки сериализации JSON (добавляются по умолчанию при добавлении Джексона к классам и добавить либо@EnableWebMvc
или<mvc:annotation-driven />
к вашей конфигурации, см ссылочных документов ):Обратите внимание, что очень часто отделить доменные объекты от объектов представления или объектов DTO. Этого легко достичь, добавив небольшую фабрику DTO, которая возвращает сериализуемый объект JSON:
источник
Match
и какой-то другой объект.Вот другой подход. Создайте пользовательский
Exception
аннотированный@ResponseStatus
, как показано ниже.И бросить его, когда это необходимо.
Ознакомьтесь с документацией Spring здесь: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-annotated-exceptions .
источник
Как упоминалось в некоторых ответах, существует возможность создания класса исключений для каждого статуса HTTP, который вы хотите вернуть. Мне не нравится идея создания класса для каждого проекта. Вот что я придумал вместо этого.
Давайте перейдем к коду
Затем я создаю класс совета контроллера
Использовать его
http://javaninja.net/2016/06/throwing-exceptions-messages-spring-mvc-controller/
источник
Я использую это в моем весеннем загрузочном приложении
источник
Самый простой способ это бросить
ResponseStatusException
источник
С Spring Boot я не совсем уверен, почему это было необходимо (я получил
/error
запасной вариант, хотя он@ResponseBody
был определен для@ExceptionHandler
), но следующее само по себе не сработало:Это все еще выдало исключение, очевидно, потому что никакие производимые типы носителей не были определены как атрибут запроса:
Поэтому я добавил их.
И благодаря этому у меня появился «поддерживаемый совместимый тип носителя», но потом он все равно не работал, потому что мой
ErrorMessage
был неисправен:JacksonMapper не считал его «конвертируемым», поэтому мне пришлось добавить геттеры / сеттеры, и я также добавил
@JsonProperty
аннотациюЗатем я получил свое сообщение, как и предполагалось
источник
Вы также можете просто
throw new HttpMessageNotReadableException("error description")
извлечь выгоду из обработки ошибок Spring по умолчанию .Однако, как и в случае с этими ошибками по умолчанию, тело ответа не будет установлено.
Я нахожу это полезным при отклонении запросов, которые могли быть разумно обработаны только вручную, что может указывать на злонамеренное намерение, поскольку они скрывают тот факт, что запрос был отклонен на основе более глубокой пользовательской проверки и ее критериев.
Hth, DTK
источник
HttpMessageNotReadableException("error description")
устарел.Другой подход заключается в использовании
@ExceptionHandler
с@ControllerAdvice
для централизации всех ваших обработчиков в одном классе, если нет, вы должны поместить методы обработчика в каждый контроллер, для которого вы хотите управлять исключением.Ваш класс обработчика:
Ваше пользовательское исключение:
Теперь вы можете генерировать исключения из любого из ваших контроллеров, и вы можете определять другие обработчики внутри вашего класса рекомендации.
источник
Я думаю, что этот поток на самом деле имеет самое простое и чистое решение, которое не жертвует инструментами боевых действий JSON, которые предоставляет Spring:
https://stackoverflow.com/a/16986372/1278921
источник