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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:18:51  来源:igfitidea点击:

Convert a object into JSON in REST service by Spring MVC

javajsonspringrestspring-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 Studentclass you can add @XmlRootElementfrom javax.xml.bind.annotationpackage.

您可以随时添加@Produces("application/json")上述 Web 方法或指定produces="application/json"返回 json。然后在Student类的顶部,您可以@XmlRootElementjavax.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.

保留其余代码原样。