java - responseentity - Devolver objeto JSON como respuesta en Spring Boot
spring rest ejemplo (5)
Como está utilizando Spring Boot web, la dependencia de Jackson es implícita y no tenemos que definirla explícitamente.
Puede verificar la dependencia de Jackson en su
pom.xml
en la pestaña de jerarquía de dependencia si usa eclipse.
Y como ha anotado con
@RestController
no hay necesidad de hacer una conversión json explícita.
Simplemente devuelva un POJO y el serializador jackson se encargará de convertirlo a json.
Es equivalente a usar
@ResponseBody
cuando se usa con @Controller.
En lugar de colocar
@ResponseBody
en cada método de controlador, colocamos
@RestController
lugar de vanilla
@Controller
y
@ResponseBody
de forma predeterminada se aplica a todos los recursos en ese controlador.
Consulte este enlace:
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
El problema que enfrenta es porque el objeto devuelto (JSONObject) no tiene getter para ciertas propiedades.
Y su intención no es serializar este JSONObject, sino serializar un POJO.
Así que solo devuelve el POJO.
Consulte este enlace:
https://stackoverflow.com/a/35822500/5039001
Si desea devolver una cadena serializada json, simplemente devuelva la cadena. Spring usará StringHttpMessageConverter en lugar del convertidor JSON en este caso.
Tengo una muestra RestController en Spring Boot:
@RestController
@RequestMapping("/api")
class MyRestController
{
@GetMapping(path = "/hello")
public JSONObject sayHello()
{
return new JSONObject("{''aa'':''bb''}");
}
}
Estoy usando la biblioteca JSON
org.json
Cuando llego a API
/hello
, recibo una excepción que dice:
Servlet.service () para servlet [dispatcherServlet] en contexto con la ruta [] arrojó una excepción [Error al procesar la solicitud; la excepción anidada es java.lang.IllegalArgumentException: no se ha encontrado ningún convertidor para el valor de retorno de tipo: clase org.json.JSONObject] con causa raíz
java.lang.IllegalArgumentException: no se ha encontrado ningún convertidor para el valor de retorno de tipo: clase org.json.JSONObject
¿Cual es el problema? ¿Alguien puede explicar qué está sucediendo exactamente?
La razón por la cual su enfoque actual no funciona es porque Jackson se usa por defecto para serializar y deserializar objetos.
Sin embargo, no sabe cómo serializar el
JSONObject
.
Si desea crear una estructura JSON dinámica, puede usar un
Map
, por ejemplo:
@GetMapping
public Map<String, String> sayHello() {
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
map.put("foo", "bar");
map.put("aa", "bb");
return map;
}
Esto conducirá a la siguiente respuesta JSON:
{ "key": "value", "foo": "bar", "aa": "bb" }
Esto es un poco limitado, ya que puede ser un poco más difícil agregar objetos secundarios.
Sin embargo, Jackson tiene su propio mecanismo, utilizando
ObjectNode
y
ArrayNode
.
Para usarlo, debe conectar automáticamente
ObjectMapper
en su servicio / controlador.
Entonces puedes usar:
@GetMapping
public ObjectNode sayHello() {
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("key", "value");
objectNode.put("foo", "bar");
objectNode.put("number", 42);
return objectNode;
}
Este enfoque le permite agregar objetos secundarios, matrices y usar los distintos tipos.
Puede devolver una respuesta como
String
como lo sugiere @vagaasen o puede usar el objeto
ResponseEntity
proporcionado por Spring como se muestra a continuación.
De esta manera, también puede devolver el
Http status code
que es más útil en llamadas de servicio web.
@RestController
@RequestMapping("/api")
public class MyRestController
{
@GetMapping(path = "/hello", produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> sayHello()
{
//Get data from service layer into entityList.
List<JSONObject> entities = new ArrayList<JSONObject>();
for (Entity n : entityList) {
JSONObject entity = new JSONObject();
entity.put("aa", "bb");
entities.add(entity);
}
return new ResponseEntity<Object>(entities, HttpStatus.OK);
}
}
también puedes usar un hashmap para esto
@GetMapping
public HashMap<String, Object> get() {
HashMap<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("results", somePOJO);
return map;
}
@RequestMapping("/api/status")
public Map doSomething()
{
return Collections.singletonMap("status", myService.doSomething());
}
PD. Funciona solo por 1 valor