Как SpringBoot возвращает errorResponse в формате JSON? - PullRequest
0 голосов
/ 04 февраля 2020

Я новичок ie в реализации SpringBoot + RestfulWebservice.В моем проекте исключения обрабатываются глобально с использованием @ControllerAdvice, и создается пользовательский класс для установки кода ошибки и сообщения об ошибке в формате String. Мы передаем объект ошибки в HTTPResponse и получение ответа. Но мне интересно, как сообщения об ошибках преобразуются в формат JSON, поскольку мы не используем явно httpMessageConverter.

- Is Spring Boot internally do the conversion?

Пожалуйста, помогите мне понять поведение. Дайте мне некоторые идеи, хотя вы чувствуете, что это основной вопрос

.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

По умолчанию springboot регистрирует следующее HttpMessageConverters при запуске:

ByteArrayHttpMessageConverter – converts byte arrays
StringHttpMessageConverter – converts Strings
ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
SourceHttpMessageConverter – converts javax.xml.transform.Source
FormHttpMessageConverter – converts form data to/from a MultiValueMap<String, String>.
Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML (added only if JAXB2 is present on the classpath)
MappingJackson2HttpMessageConverter – converts JSON (added only if Jackson 2 is present on the classpath)
MappingJacksonHttpMessageConverter – converts JSON (added only if Jackson is present on the classpath)
AtomFeedHttpMessageConverter – converts Atom feeds (added only if Rome is present on the classpath)
RssChannelHttpMessageConverter – converts RSS feeds (added only if Rome is present on the classpath)

Таким образом, если вы возвращаете объект из совета контроллера, Spring по умолчанию автоматически вызовет конвертер Джексона для преобразования объекта. в действительный ответ Json.

По сути, Springboot проверяет тип MIME, чтобы решить, какую реализацию HttpMessageConverter использовать. Кроме того, решение о типе данных будет зависеть от заголовка "Accept". что ожидает вызывающая сторона. Если это запрос, полученный springboot, будет использовать заголовок «Content-type» для определения типа отправляемых данных.

0 голосов
/ 04 февраля 2020

По умолчанию Spring Boot по умолчанию JSON для всех вещей, когда вы не предоставляете подробности о согласовании типа контента.

Согласно весенней загрузочной документации по обработке ошибок здесь с использованием @ControllerAdvice по умолчанию выдает JSON отформатированные ошибки. Из документов:

Вы также можете определить класс, аннотированный @ControllerAdvice, чтобы настроить документ JSON для возврата для определенного контроллера и / или типа исключения, как показано в следующем примере:

На этой странице на mkyong.com есть хорошая статья о том, как настроить обработку ошибок ControllerAdvice.

В качестве примера использования JSON это контроллер очень голых костей сделает все возможное для отображения любого POJO как JSON (обратите внимание, если вы просто предоставите примитив, такой как long, он просто вернет примитив в тексте, но установит тип содержимого как application/json)

@RequestMapping("api/time")
@RestController
public class TestApi {

    @GetMapping
    public Map<String, Long> time(){
        Map<String, Long> res = new HashMap<String, Long>();
        res.put("time_in_nanos", System.nanoTime());
        return res;
    }
}

пример:

$ curl -v http://localhost:8080/api/time
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/time HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Tue, 04 Feb 2020 04:18:35 GMT
<
* Connection #0 to host localhost left intact
{"time_in_nanos":47078744054692}

Это для запросов по умолчанию (ie no Accept header или Accept: */*), если вы укажете application/xml или что-то еще, обычно это не будет работать:

$ curl -v http://localhost:8080/api/time --header 'Accept: application/xml'
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/time HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.1
> Accept: application/xml
>
< HTTP/1.1 406
< Content-Length: 0
< Date: Tue, 04 Feb 2020 04:17:38 GMT
<
* Connection #0 to host localhost left intact
* Closing connection 0
...