Простая строка как возвращаемое значение JSON в контроллере останова spring
Посмотрим на следующий простой тестовый контроллер (используется с Spring 4.0.3):
@RestController
public class TestController
{
@RequestMapping("/getList")
public List<String> getList()
{
final List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
return list;
}
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
В теории оба метода контроллера должны возвращать действительный JSON. Вызов первого метода контроллера действительно возвращает следующий массив JSON:
$ curl -i -H "Accept: application/json" http://localhost:8080/getList
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
["1","2"]
Но второй метод контроллера возвращает строку без кавычек, которая не является допустимой строкой JSON:
$ curl -i -H "Accept: application/json" http://localhost:8080/getString
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Hello World
Почему это так? Может ли он быть настроен? Это ошибка? Или особенность, которую я не понимаю?
Ответы
Ответ 1
Когда вы возвращаете объект String
, Spring MVC интерпретирует это как содержимое, чтобы помещать тело ответа и не модифицирует его дальше. Если вы хотите, чтобы фактическая строка была ответом JSON, вам нужно либо процитировать ее самостоятельно, либо явно запустить через Джексона.
Ответ 2
Вы можете удалить StringHttpMessageConverter
, который был зарегистрирован перед преобразователем jackson, - как указано в комментарии.
/**
* Unregister the default {@link StringHttpMessageConverter} as we want
* Strings to be handled by the JSON converter.
*
* Our MappingJackson2HttpMessageConverter will deal with strings.
*
* @param converters
* List of already configured converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
while (iterator.hasNext()) {
HttpMessageConverter<?> converter = iterator.next();
if (converter instanceof StringHttpMessageConverter) {
iterator.remove();
}
}
}
Ответ 3
Если вы хотите вернуть объект String, Spring MVC интерпретирует это как содержимое, которое нужно поместить в тело ответа и не будет изменять его дальше. Если вы хотите, чтобы фактическая строка была ответом JSON, вам нужно либо процитировать ее самостоятельно, либо явно запустить через Джексона.
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
Ответ 4
Вот шаги, которые я сделал для этого:
-
Добавить зависимость в файле pom:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.3</version>
</dependency>
-
Поместите @ResponseBody
аннотацию на свой метод следующим образом:
@RequestMapping(value = "/getCountries", method = RequestMethod.GET)
@ResponseBody
public List<Country> getCountries() {
return countryDAO.list();
}