Java 通过 Spring MVC 在 REST 服务中将对象转换为 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29076210/
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
Convert a object into JSON in REST service by Spring MVC
提问by Roul
I'm trying to create a REST service using Spring MVC and it's working if I'm returning a plain string. My requirement is to return a JSON string of the Java object. Don't know how to achieve this by implicit conversion.
我正在尝试使用 Spring MVC 创建一个 REST 服务,如果我返回一个纯字符串,它就可以工作。我的要求是返回 Java 对象的 JSON 字符串。不知道如何通过隐式转换来实现这一点。
Here is my code:
这是我的代码:
StudentService.java
学生服务.java
package com.spring.schoolmanagement.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.spring.schoolmanagement.dao.CourseDAOImpl;
import com.spring.schoolmanagement.dao.StateDAOImpl;
import com.spring.schoolmanagement.dao.StudentDAOImpl;
import com.spring.schoolmanagement.model.Student;
@Controller
@RequestMapping("/rest/student")
public class StudentService {
@Autowired
private CourseDAOImpl courseService;
@Autowired
private StudentDAOImpl studentService;
@Autowired
private StateDAOImpl stateService;
@RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = "Accept=*/*")
@ResponseBody
public Student home(@PathVariable int id) {
return this.studentService.getById(id);
}
@RequestMapping(method = RequestMethod.GET, headers = "Accept=*/*")
@ResponseBody
public List<Student> getAll() throws Exception {
return this.studentService.getAll();
}
@RequestMapping(value = "/test", method = RequestMethod.GET, headers = "Accept=*/*")
@ResponseBody
public String test() {
return "Test REST Service!!!";
}
}
Student.java
学生.java
package com.spring.schoolmanagement.model;
import java.util.Date;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
public class Student extends Contact{
private int id;
@NotEmpty
@Size(max = 30)
private String firstName, lastName;
//private String lastName;
@DateTimeFormat(pattern="MM/dd/yyyy")
private Date DOB, DOA;
//private Date DOA;
@NotEmpty
@Email
private String email;
private String password;
private int courseID;
private String courseName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date dOB) {
DOB = dOB;
}
public Date getDOA() {
return DOA;
}
public void setDOA(Date dOA) {
DOA = dOA;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getCourseID() {
return courseID;
}
public void setCourseID(int courseID) {
this.courseID = courseID;
}
public String getCourseName() {
return courseName;
}
public void setCourseName(String courseName) {
this.courseName = courseName;
}
}
Here http://localhost:8080/schoolmangement/rest/student/testURL is returning "Test REST Service!!!"
这里http://localhost:8080/schoolmangement/rest/student/testURL 返回“测试 REST 服务!!!”
But, http://localhost:8080/schoolmangement/rest/student/1URL throwing HTTP Status code 406 with error message:
但是,http://localhost:8080/schoolmangement/rest/student/1URL 抛出 HTTP 状态代码 406 和错误消息:
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
此请求标识的资源只能生成具有根据请求“接受”标头不可接受的特征的响应。
采纳答案by Roul
Finally I got solution using Hymanson library along with Spring MVC. I got this solution from an example of Journal Dev( http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-Hymanson-and-client-program)
最后我得到了使用 Hymanson 库和 Spring MVC 的解决方案。我从 Journal Dev(http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-Hymanson-and-client-program)的一个例子中得到了这个解决方案
So, the code changes I have done are:
所以,我所做的代码更改是:
- Include the library in Maven.
- Add JSON conversion Servlet into servlet-context.xml.
- Change the Model into Serializable.
- 在 Maven 中包含库。
- 将 JSON 转换 Servlet 添加到 servlet-context.xml 中。
- 将模型更改为可序列化。
I didn't made any changes to my REST service controller. By default it converts into JSON.
我没有对 REST 服务控制器进行任何更改。默认情况下,它会转换为 JSON。
回答by Gyan
You can always add the @Produces("application/json")
above your web method or specify produces="application/json"
to return json. Then on top of the Student
class you can add @XmlRootElement
from javax.xml.bind.annotation
package.
您可以随时添加@Produces("application/json")
上述 Web 方法或指定produces="application/json"
返回 json。然后在Student
类的顶部,您可以@XmlRootElement
从javax.xml.bind.annotation
包中添加。
Please note, it might not be a good idea to directly return model classes. Just a suggestion.
请注意,直接返回模型类可能不是一个好主意。只是一个建议。
HTH.
哈。
回答by Boyan
The Json conversion should work out-of-the box. In order this to happen you need add some simple configurations:
First add a contentNegotiationManager into your spring config file. It is responsible for negotiating the response type:
Json 转换应该是开箱即用的。为了实现这一点,您需要添加一些简单的配置:
首先将 contentNegotiationManager 添加到您的 spring 配置文件中。它负责协商响应类型:
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="ignoreAcceptHeader" value="true" />
<property name="useJaf" value="false" />
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager" />
<context:annotation-config />
Then add Hymanson2jars (Hymanson-databind and Hymanson-core) in the service's class path. Hymanson is responsible for the data serialization to JSON. Spring will detect these and initialize the MappingHymanson2HttpMessageConverterautomatically for you. Having only this configured I have my automatic conversion to JSON working. The described config has an additional benefit of giving you the possibility to serialize to XML if you set accept:application/xmlheader.
然后在服务的类路径中添加Hymanson2jars(Hymanson-databind 和 Hymanson-core)。Hymanson 负责将数据序列化为 JSON。Spring 将检测这些并自动为您初始化MappingHymanson2HttpMessageConverter。仅此配置后,我就可以自动转换为 JSON 工作。如果您设置了accept:application/xml标头,那么所描述的配置还有一个额外的好处,就是让您可以序列化为 XML 。
回答by Sudip Bhandari
Spring framework itself handles json conversion when controller is annotated properly.
当控制器被正确注释时,Spring 框架本身会处理 json 转换。
For eg:
例如:
@PutMapping(produces = {"application/json"})
@ResponseBody
public UpdateResponse someMethod(){ //do something
return UpdateResponseInstance;
}
Here spring internally converts the UpdateResponse object to corresponding json string and returns it. In order to do it spring internally uses Hymanson library.
这里spring内部将UpdateResponse对象转换为对应的json字符串并返回。为了做到这一点,spring 在内部使用了Hymanson 库。
If you require a json representation of a model object anywhere apart from controller then you can use objectMapper provided by Hymanson. Model should be properly annotated for this to work.
如果您需要除控制器之外的任何地方的模型对象的 json 表示,那么您可以使用 Hymanson 提供的 objectMapper。应该正确注释模型以使其正常工作。
Eg:
例如:
ObjectMapper mapper = new ObjectMapper();
SomeModelClass someModelObject = someModelRepository.findById(idValue).get();
mapper.writeValueAsString(someModelObject);
回答by PraBhu
Another simple solution is to add Hymanson-databind dependency in POM.
另一个简单的解决方案是在 POM 中添加 Hymanson-databind 依赖项。
<dependency>
<groupId>com.fasterxml.Hymanson.core</groupId>
<artifactId>Hymanson-databind</artifactId>
<version>2.8.1</version>
</dependency>
Keep Rest of the code as it is.
保留其余代码原样。