Spring MVC - как вернуть простую строку в качестве JSON в контроллере Rest
мой вопрос по сути является продолжением этого вопроса.
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
в приведенном выше, Spring добавит "Hello World" в тело ответа. Как я могу вернуть строку в качестве ответа JSON? Я понимаю, что могу добавить цитаты, но это больше похоже на взлом.
пожалуйста, приведите любые примеры, чтобы помочь объяснить эту концепцию.
Примечание: Я не хочу, чтобы это было написано прямо в тело ответа HTTP, я хочу вернуть строку в формате JSON (я использую свой контроллер с RestyGWT который требует, чтобы ответ был в действительном JSON формат.)
10 ответов:
вернуть
text/plain
(например,возвращает только строковое сообщение от Spring MVC 3 Controller) или обернуть строку какой-то объектpublic class StringResponse { private String response; public StringResponse(String s) { this.response = s; } // get/set omitted... }
Установите тип ответаapplication/json
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
и у вас будет JSON, который выглядит как
{ "response" : "your string value" }
JSON по существу является строкой в контексте PHP или JAVA. Это означает, что строка является допустимым JSON может быть возвращен в ответ. Следующее должно работать.
@RequestMapping(value="/user/addUser", method=RequestMethod.POST) @ResponseBody public String addUser(@ModelAttribute("user") User user) { if (user != null) { logger.info("Inside addIssuer, adding: " + user.toString()); } else { logger.info("Inside addIssuer..."); } users.put(user.getUsername(), user); return "{\"success\":1}"; }
это нормально для простого ответа строки. Но для сложного ответа JSON вы должны использовать класс-оболочку, как описано Шоном.
Так как я разместил этот вопрос, я начал использовать JSONObject (maven информация о зависимости). Особенно работая с командой, мне легче ожидать, что строка будет возвращена, а не какой-то объект-оболочка, когда все, что я хочу, - это простая строка.
Пример Использования:
@RestController public class TestController { @RequestMapping("/getString") public String getString() { return JSONObject.quote("Hello World"); } }
вы можете легко вернуть
JSON
СString
в собственностьresponse
следующим образом@RestController public class TestController { @RequestMapping((value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE) public Map getString() { return Collections.singletonMap("response", "Hello World"); } }
просто отмените регистрацию по умолчанию
StringHttpMessageConverter
например:@Configuration public class WebMvcConfiguration extends WebMvcConfigurationSupport { /** * Unregister the default {@link StringHttpMessageConverter} as we want Strings * to be handled by the JSON converter. * * @param converters List of already configured converters * @see WebMvcConfigurationSupport#addDefaultHttpMessageConverters(List) */ @Override protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.stream() .filter(c -> c instanceof StringHttpMessageConverter) .findFirst().ifPresent(converters::remove); } }
протестировано как с методами обработчика действий контроллера, так и с обработчиками исключений контроллера:
@RequestMapping("/foo") public String produceFoo() { return "foo"; } @ExceptionHandler(FooApiException.class) public String fooException(HttpServletRequest request, Throwable e) { return e.getMessage(); }
конечные ноты:
extendMessageConverters
доступен с весны 4.1.3, если вы работаете на предыдущей версии вы можете реализовать ту же технику с помощьюconfigureMessageConverters
, Он просто занимает немного больше работы.- это был один из многих других возможных подходов, если ваш приложение только когда-либо возвращает JSON и никаких других типов контента, вам лучше пропустить конвертеры по умолчанию и добавить один конвертер Джексона. Другой подход заключается в добавлении конвертеров по умолчанию, но в другом порядке, так что конвертер Джексона находится перед строковым. Это должно позволить методам действий контроллера диктовать, как они хотят, чтобы строка была преобразована в зависимости от типа носителя ответа.
добавить
produces = "application/json"
in@RequestMapping
аннотация как:@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
Подсказка: в качестве возвращаемого значения, я рекомендую использовать
ResponseEntity<List<T>>
тип. Потому что полученные данные в теле JSON должны быть массив или объект в соответствии с его спецификациями, а не один простой строка. Это может иногда вызывать проблемы (например, наблюдаемые в Angular2).отличия:
вернулся
String
в формате JSON:"example"
вернулся
List<String>
как json:["example"]
Я знаю, что этот вопрос старый, но я тоже хочу внести свой вклад:
основное различие между другими ответами-это возврат hashmap.
@GetMapping("...") @ResponseBody public HashMap<String, Object> endPointExample(...) { HashMap<String, Object> rtn = new LinkedHashMap<String, Object>(); rtn.put("pic", image); rtn.put("potato", "King Potato"); return rtn; }
это вернется:
{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
в spring MVC 4 тип ответа по умолчанию для объектов-JSON. Так что все, что вам нужно сделать, это обернуть строку в какой-то объект.
public class StringResponse { private String response; public StringResponse(String s) { this.response = s; } // getters and setters }
никаких изменений в контроллере, кроме возврата
StringResponse
вместо строки.