Синтаксический анализ тела запроса, содержащего строку в кавычках, в формате JSON в Spring Boot 2

#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
)