Це питання мене зводило з розуму: Весна - це такий потужний інструмент, і все-таки така проста річ, як написання вихідного рядка, як JSON, здається неможливим без потворних хак.
Моє рішення (в Котліні) про те, що я вважаю найменш настирливим і найпрозорішим - це використовувати поради контролера і перевірити, чи запит підходив до певного набору кінцевих точок (REST API, зазвичай, оскільки ми найчастіше хочемо повернути ВСІ відповіді звідси як JSON і не проводити спеціалізації у фронтені на основі того, чи є повернені дані простою строкою ("Не робіть десеріалізацію JSON!") чи чимось іншим ("Десеріалізація JSON!"). Позитивним аспектом цього є те, що контролер залишається таким же і без злому.
supports
Метод гарантує , що всі запити , які були оброблені з допомогою StringHttpMessageConverter
(наприклад , перетворювача , який обробляє вихідні всіх контролерів , які повертають прості рядки) обробляються і в beforeBodyWrite
методі, ми контролюємо , в яких випадках ми хочемо перервати і перетворити висновок в формат JSON (та змініть заголовки відповідно).
@ControllerAdvice
class StringToJsonAdvice(val ob: ObjectMapper) : ResponseBodyAdvice<Any?> {
override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean =
converterType === StringHttpMessageConverter::class.java
override fun beforeBodyWrite(
body: Any?,
returnType: MethodParameter,
selectedContentType: MediaType,
selectedConverterType: Class<out HttpMessageConverter<*>>,
request: ServerHttpRequest,
response: ServerHttpResponse
): Any? {
return if (request.uri.path.contains("api")) {
response.getHeaders().contentType = MediaType.APPLICATION_JSON
ob.writeValueAsString(body)
} else body
}
}
Я сподіваюся, що в майбутньому ми отримаємо просту анотацію, в якій ми зможемо перекрити те, яке HttpMessageConverter
слід використовувати для отримання результатів.