#java #json #spring #spring-boot
#java #json #spring #spring-boot
Вопрос:
У меня есть приложение, которое предоставляет конечную точку, принимающую PUT
запросы в виде строки в формате JSON, например:
PUT /my/endpoint
"some string"
Моя сигнатура метода конечной точки выглядит примерно так:
@RequestMapping(
path = "/my/endpoint",
consumes = "application/vnd.mycompany.myservice-v1.hal json"
)
public ResponseEntity<MyResponse> myEndpoint(
@RequestBody final String myString
) {
...
}
При использовании Spring Boot 1 (1.5.22.RELEASE) значением myString
приведенного PUT
выше примера будет буквальный текст some string
, но при Spring Boot 2 (2.3.6.RELEASE) Теперь это буквальный текст "some string"
, т. Е. Кажется, что ввод не обрабатывается строго как JSON, потому что кавычки не удаляются.
Я считаю, что строки, заключенные в кавычки, являются допустимыми JSON (а строки без кавычек — нет), точно так же, как объект (в {
и }
) и список (в [
и ]
) были бы.
Я убрал некоторые посторонние детали, которые, на мой взгляд, не имеют значения для рассматриваемой проблемы (например, мы используем CompletableFuture
в качестве возвращаемого значения, у меня @PathVariable
там тоже есть, и выполняется некоторая проверка на основе аннотаций), но я оставил в том, что мы используем пользовательский носитель-введите в случае, если это как-то связано с этим.
Есть идеи, как я могу убедить Spring Boot 2 правильно обрабатывать тело моего запроса как JSON? К сожалению, я не могу переопределить API, потому что у нас уже есть живые клиенты, использующие его.
Ответ №1:
Это может быть не лучшим вариантом, но если ничего другого не помогает при запуске. Вместо String
того, чтобы позволить Spring обрабатывать RequestBody
как Object
. Итак, как:
public ResponseEntity<String> myEndpoint(@RequestBody final Object myString)
При использовании String
Spring может даже не использовать Jackson для синтаксического анализа, а обрабатывать тело как a String
, в котором должны быть все символы в теле, даже если тип содержимого установлен в JSON.
Если вы выполните следующие действия:
String myString2 = new ObjectMapper().readValue(myString, String.class);
вы можете видеть, что это приводит к myString2
отсутствию окружающих двойных кавычек.
For Object
Spring, похоже, обрабатывает это по-другому. Он преобразует его в a String
, но, похоже, рассматривает его как значение JSON (и как String
значение, потому что с окружающими двойными кавычками), в нем не должно быть окружающих двойных кавычек.
Если вы используете Object
, а затем регистрируете myString.getClass()
, вы увидите, что это на самом деле java.lang.String
Комментарии:
1. Гениально, это именно то, что я искал — нужно реализовать несколько защитных мер вокруг этого, но это убеждает Spring правильно обработать входящий запрос. Не уверен, что я бы подумал об этом в одиночку.
Ответ №2:
Вы можете создать объект запроса
public class MyObject{
private String myStr;
}
Используйте класс MyObject в качестве объекта RequestBody с mediaType="application/json"
В вашем контроллере
@RequestMapping(
value= "/my/endpoint", method= RequestMethod.PUT
)
public ResponseEntity<MyResponse> myEndpoint(
@RequestBody final MyObject myObj
)