Java 在 Spring Boot 中返回 JSON 对象作为响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44839753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Returning JSON object as response in Spring Boot
提问by iwekesi
I have a sample RestController in Spring Boot:
我在 Spring Boot 中有一个示例 RestController:
@RestController
@RequestMapping("/api")
class MyRestController
{
@GetMapping(path = "/hello")
public JSONObject sayHello()
{
return new JSONObject("{'aa':'bb'}");
}
}
I am using the JSON library org.json
我正在使用 JSON 库 org.json
When I hit API /hello
, I get an exception saying :
当我点击 API 时/hello
,我收到一个异常说:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject] with root cause
java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject
servlet [dispatcherServlet] 的 Servlet.service() 在路径为 [] 的上下文中抛出异常 [请求处理失败;嵌套异常是 java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject] 与根本原因
java.lang.IllegalArgumentException:找不到类型为 org.json.JSONObject 的返回值的转换器
What is the issue? Can someone explain what exactly is happening?
问题是什么?有人能解释一下到底发生了什么吗?
采纳答案by prem kumar
As you are using Spring Boot web, Hymanson dependency is implicit and we do not have to define explicitly. You can check for Hymanson dependency in your pom.xml
in the dependency hierarchy tab if using eclipse.
当您使用 Spring Boot web 时,Hymanson 依赖是隐式的,我们不必明确定义。pom.xml
如果使用 eclipse ,您可以在依赖层次结构选项卡中检查 Hymanson 依赖。
And as you have annotated with @RestController
there is no need to do explicit json conversion. Just return a POJO and Hymanson serializer will take care of converting to json. It is equivalent to using @ResponseBody
when used with @Controller. Rather than placing @ResponseBody
on every controller method we place @RestController
instead of vanilla @Controller
and @ResponseBody
by default is applied on all resources in that controller.
Refer this link:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
正如您所注释的那样,@RestController
无需进行显式的 json 转换。只需返回一个 POJO,Hymanson 序列化程序将负责转换为 json。@ResponseBody
与@Controller一起使用时相当于使用。我们不是放置@ResponseBody
在每个控制器方法上,而是放置在@RestController
原版上,@Controller
并且@ResponseBody
默认情况下应用于该控制器中的所有资源。
请参阅此链接:https : //docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
The problem you are facing is because the returned object(JSONObject) does not have getter for certain properties. And your intention is not to serialize this JSONObject but instead to serialize a POJO. So just return the POJO.
Refer this link:https://stackoverflow.com/a/35822500/5039001
您面临的问题是因为返回的对象(JSONObject)没有某些属性的 getter。您的意图不是序列化这个 JSONObject,而是序列化一个 POJO。所以只需返回POJO。
请参阅此链接:https : //stackoverflow.com/a/35822500/5039001
If you want to return a json serialized string then just return the string. Spring will use StringHttpMessageConverter instead of JSON converter in this case.
如果你想返回一个 json 序列化的字符串,那么只需返回该字符串。在这种情况下,Spring 将使用 StringHttpMessageConverter 而不是 JSON 转换器。
回答by g00glen00b
The reason why your current approach doesn't work is because Hymanson is used by default to serialize and to deserialize objects. However, it doesn't know how to serialize the JSONObject
. If you want to create a dynamic JSON structure, you can use a Map
, for example:
您当前的方法不起作用的原因是因为默认情况下使用 Hymanson 来序列化和反序列化对象。但是,它不知道如何序列化JSONObject
. 如果要创建动态 JSON 结构,可以使用Map
,例如:
@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;
}
This will lead to the following JSON response:
这将导致以下 JSON 响应:
{ "key": "value", "foo": "bar", "aa": "bb" }
This is a bit limited, since it may become a bit more difficult to add child objects. Hymanson has its own mechanism though, using ObjectNode
and ArrayNode
. To use it, you have to autowire ObjectMapper
in your service/controller. Then you can use:
这有点受限制,因为添加子对象可能会变得更加困难。Hymanson 有自己的机制,使用ObjectNode
和ArrayNode
。要使用它,您必须ObjectMapper
在您的服务/控制器中自动装配。然后你可以使用:
@Autowired
ObjectMapper mapper;
(...)
@GetMapping
public ObjectNode sayHello() {
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("key", "value");
objectNode.put("foo", "bar");
objectNode.put("number", 42);
return objectNode;
}
This approach allows you to add child objects, arrays, and use all various types.
这种方法允许您添加子对象、数组并使用所有各种类型。
回答by Sangam Belose
You can either return a response as String
as suggested by @vagaasen or you can use ResponseEntity
Object provided by Spring as below. By this way you can also return Http status code
which is more helpful in webservice call.
您可以String
按照@vagaasen 的建议返回响应,也可以使用ResponseEntity
Spring 提供的对象,如下所示。通过这种方式,您还可以返回Http status code
这对 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);
}
}
回答by Dmitry
@RequestMapping("/api/status")
public Map doSomething()
{
return Collections.singletonMap("status", myService.doSomething());
}
PS. Works only for 1 value
附注。仅适用于 1 个值
回答by maximus
you can also use a hashmap for this
您也可以为此使用哈希图
@GetMapping
public HashMap<String, Object> get() {
HashMap<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("results", somePOJO);
return map;
}
回答by Ved Prakash
use ResponseEntity<ResponseBean>
用 ResponseEntity<ResponseBean>
Here you can use ResponseBean or Any java bean as you like to return your api response and it is the best practice. I have used Enum for response. it will return status code and status message of API.
在这里,您可以根据需要使用 ResponseBean 或 Any java bean 来返回 api 响应,这是最佳实践。我使用 Enum 进行响应。它将返回 API 的状态代码和状态消息。
@GetMapping(path = "/login")
public ResponseEntity<ServiceStatus> restApiExample(HttpServletRequest request,
HttpServletResponse response) {
String username = request.getParameter("username");
String password = request.getParameter("password");
loginService.login(username, password, request);
return new ResponseEntity<ServiceStatus>(ServiceStatus.LOGIN_SUCCESS,
HttpStatus.ACCEPTED);
}
for response ServiceStatus or(ResponseBody)
用于响应 ServiceStatus 或(ResponseBody)
public enum ServiceStatus {
LOGIN_SUCCESS(0, "Login success"),
private final int id;
private final String message;
//Enum constructor
ServiceStatus(int id, String message) {
this.id = id;
this.message = message;
}
public int getId() {
return id;
}
public String getMessage() {
return message;
}
}
Spring REST API should have below key in response
Spring REST API 应该具有以下键作为响应
- Status Code
- Message
- 状态码
- 信息
you will get final response below
您将在下面得到最终答复
{
"StatusCode" : "0",
"Message":"Login success"
}
you can use ResponseBody(java POJO, ENUM,etc..) as per your requirement.
您可以根据您的要求使用 ResponseBody(java POJO、ENUM 等)。