Devolver el objeto JSON como respuesta en Spring Boot

Tengo un controlador de descanso de ejemplo en el arranque de spring:

@RestController @RequestMapping("/api") class MyRestController { @GetMapping(path = "/hello") public JSONObject sayHello() { return new JSONObject("{'aa':'bb'}"); } } 

Estoy usando la biblioteca json: org.json

Cuando presiono api / hola, recibo una excepción que dice:

Servlet.service () para servlet [dispatcherServlet] en contexto con path [] lanzó excepción [Falló el proceso de solicitud; la excepción anidada es java.lang.IllegalArgumentException: no se encontró un convertidor para el valor de retorno de tipo: clase org.json.JSONObject] con causa raíz

java.lang.IllegalArgumentException: No se ha encontrado un convertidor para el valor devuelto de tipo: class org.json.JSONObject

Cual es el problema. ¿Alguien puede explicar qué está pasando exactamente? Soy nuevo en SpringBoot.

Gracias por adelantado 🙂

Como está utilizando la web de arranque de spring, la dependencia de jackson es implícita y no es necesario que definamos explícitamente. Puede verificar la dependencia de jackson en su pom.xml en la pestaña de jerarquía de dependencias si usa eclipse.

Y como has anotado con @RestController no hay necesidad de hacer una conversión json explícita. Simplemente devuelva un POJO y el serializador de jackson se encargará de convertir a json. Es equivalente a usar @ResponseBody cuando se usa con @Controller. En lugar de colocar @ResponseBody en cada método de control colocamos @RestController lugar de vanilla @Controller y @ResponseBody por defecto 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 al que se 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 serial json, simplemente devuelva la cadena. Spring usará StringHttpMessageConverter en lugar del convertidor JSON en este caso.

La razón por la que 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 sayHello() { HashMap 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 el 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 varios tipos.

Puede devolver una respuesta como String según lo sugerido por @vagaasen o puede usar el Objeto ResponseEntity proporcionado por Spring de la siguiente manera. De esta forma, también puede devolver el Http status code que es más útil en la llamada al servicio web.

 @RestController @RequestMapping("/api") public class MyRestController { @GetMapping(path = "/hello", produces=MediaType.APPLICATION_JSON_VALUE) public ResponseEntity sayHello() { List entities = new ArrayList(); for (Entity n : entityList) { JSONObject entity = new JSONObject(); entity.put("aa", "bb"); entities.add(entity); } return new ResponseEntity(entities, HttpStatus.OK); } } 

también puedes usar un hashmap para esto

 @GetMapping public HashMap get() { HashMap 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

Intereting Posts