java - responsebody - spring boot return json
Spring MVC: cómo devolver una cadena simple como JSON en Rest Controller (11)
Agregar
produces = "application/json"
en la anotación
@RequestMapping
como:
@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
Sugerencia: como valor de retorno, recomiendo usar el tipo
ResponseEntity<List<T>>
.
Debido a que los datos producidos en el cuerpo JSON deben ser una
matriz
o un
objeto de
acuerdo con sus especificaciones, en lugar de una sola
cadena
simple.
A veces puede causar problemas (por ejemplo, Observables en Angular2).
Diferencia:
String
devuelto como json:
"example"
List<String>
devuelta
List<String>
como json:
["example"]
Mi pregunta es esencialmente un seguimiento de this pregunta.
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
En lo anterior, Spring agregaría "Hello World" en el cuerpo de respuesta. ¿Cómo puedo devolver una cadena como respuesta JSON? Entiendo que podría agregar citas, pero eso se siente más como un truco.
Proporcione algunos ejemplos para ayudar a explicar este concepto.
Nota: No quiero que esto se escriba directamente en el cuerpo de Respuesta HTTP, quiero devolver la Cadena en formato JSON (estoy usando mi Controlador con RestyGWT que requiere que la respuesta esté en formato JSON válido).
Agregue esta anotación a su método
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
Agregue la anotación
@ResponseBody
, que escribirá los datos de retorno en la secuencia de salida.
En Spring MVC 4, el tipo de respuesta predeterminado para los objetos es JSON. Entonces, todo lo que necesita hacer es envolver su Cadena en algún Objeto.
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// getters and setters
}
No hay modificaciones en el controlador, excepto devolver el
StringResponse
lugar del String.
En un proyecto abordamos esto usando JSONObject ( información de dependencia de JSONObject ). Elegimos esto porque preferimos devolver una cadena simple en lugar de un objeto contenedor. Una clase auxiliar interna podría usarse fácilmente en su lugar si no desea agregar una nueva dependencia.
Ejemplo de uso:
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
Hacer simple:
@GetMapping("/health")
public ResponseEntity<String> healthCheck() {
LOG.info("REST request health check");
return new ResponseEntity<>("{/"status/" : /"UP/"}", HttpStatus.OK);
}
JSON es esencialmente una cadena en contexto PHP o JAVA. Eso significa que la cadena que es JSON válida se puede devolver en respuesta. Lo siguiente debería funcionar.
@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}";
}
Esto está bien para una respuesta de cadena simple. Pero para una respuesta JSON compleja, debe usar la clase wrapper como la describe Shaun.
O bien devolver
text/plain
(como en
Devolver solo mensaje de cadena del controlador Spring MVC 3
) O ajustar su cadena es algún objeto
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// get/set omitted...
}
Establezca su tipo de respuesta en
MediaType.APPLICATION_JSON_VALUE
(=
"application/json"
)
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
y tendrás un JSON que se parece a
{ "response" : "your string value" }
Puede devolver fácilmente
JSON
con
String
en la
response
propiedad de la siguiente manera
@RestController
public class TestController {
@RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
public Map getString() {
return Collections.singletonMap("response", "Hello World");
}
}
Sé que esta pregunta es antigua, pero también me gustaría contribuir:
La principal diferencia entre otras respuestas es el retorno del 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;
}
Esto devolverá:
{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
Simplemente
StringHttpMessageConverter
el registro de la instancia predeterminada de
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);
}
}
Probado con ambos métodos de controlador de acción de controlador y controladores de excepción de controlador:
@RequestMapping("/foo")
public String produceFoo() {
return "foo";
}
@ExceptionHandler(FooApiException.class)
public String fooException(HttpServletRequest request, Throwable e) {
return e.getMessage();
}
Notas finales
-
extendMessageConverters
está disponible desde Spring 4.1.3, si se está ejecutando en una versión anterior, puede implementar la misma técnica usandoconfigureMessageConverters
, solo requiere un poco más de trabajo. - Este fue un enfoque de muchos otros enfoques posibles, si su aplicación solo devuelve JSON y ningún otro tipo de contenido, es mejor omitir los convertidores predeterminados y agregar un solo convertidor jackson. Otro enfoque es agregar los convertidores predeterminados pero en un orden diferente para que el convertidor jackson sea anterior al de la cadena. Esto debería permitir que los métodos de acción del controlador dicten cómo quieren que se convierta la Cadena dependiendo del tipo de medio de la respuesta.