web-dev-qa-db-fra.com

Convertir un objet en JSON dans REST service par Spring MVC

J'essaie de créer un service REST à l'aide de Spring MVC et cela fonctionne si je retourne une chaîne en clair. Mon exigence est de renvoyer une chaîne JSON de l'objet Java. Je ne sais pas comment y parvenir par conversion implicite.

Voici mon code:

StudentService.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

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;
    }
}

Ici http: // localhost: 8080/schoolmangement/rest/student/test L'URL renvoie "Test REST Service !!!"

Mais, http: // localhost: 8080/schoolmangement/rest/student/1 URL renvoyant le code HTTP 406 avec le message d'erreur:

La ressource identifiée par cette demande est uniquement capable de générer des réponses avec des caractéristiques non acceptables selon les en-têtes "accepter" de la demande.

9
Roul

Enfin, j'ai trouvé une solution utilisant la bibliothèque Jackson avec Spring MVC. J'ai eu cette solution d'un exemple de Journal Dev ( http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program )

Ainsi, les modifications de code que j'ai apportées sont les suivantes:

  • Inclure la bibliothèque dans Maven.
  • Ajoutez le servlet de conversion JSON au fichier servlet-context.xml.
  • Changez le modèle en Serializable.

Je n'ai apporté aucune modification à mon contrôleur de service REST. Par défaut, il est converti en JSON.

6
Roul

Vous pouvez toujours ajouter la @Produces("application/json") au-dessus de votre méthode Web ou spécifier produces="application/json" pour renvoyer json. Ensuite, en plus de la classe Student, vous pouvez ajouter @XmlRootElement à partir du package javax.xml.bind.annotation.

Veuillez noter que ce n’est peut-être pas une bonne idée de renvoyer directement les classes modèles. Juste une suggestion.

HTH.

5
Gyan


La conversion Json devrait fonctionner immédiatement. Pour ce faire, vous devez ajouter quelques configurations simples:
Ajoutez tout d’abord un contentNegotiationManager dans votre fichier de configuration printanier. Il est responsable de la négociation du type de réponse:

<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 />

Ajoutez ensuite Jackson2 jars (jackson-databind et jackson-core) dans le chemin de classes du service. Jackson est responsable de la sérialisation des données en JSON. Spring les détectera et initialisera le MappingJackson2HttpMessageConverter automatiquement pour vous . Cette configuration étant activée, ma conversion automatique en JSON fonctionne. La configuration décrite présente l’avantage supplémentaire de vous donner la possibilité de sérialiser en XML si vous définissez accept: application/xml header.

1
Boyan

La structure Spring elle-même gère la conversion JSON lorsque le contrôleur est correctement annoté.

Par exemple:

   @PutMapping(produces = {"application/json"})
        @ResponseBody
        public UpdateResponse someMethod(){ //do something
return UpdateResponseInstance;
}

Ici spring interprète en interne l'objet UpdateResponse en chaîne json correspondante et la renvoie. Pour ce faire, Spring utilise en interne Jackson library.

Si vous avez besoin d'une représentation json d'un objet de modèle ailleurs que dans le contrôleur, vous pouvez utiliser objectMapper fourni par jackson. Le modèle doit être correctement annoté pour que cela fonctionne.

Par exemple:

ObjectMapper mapper = new ObjectMapper();
SomeModelClass someModelObject = someModelRepository.findById(idValue).get();
mapper.writeValueAsString(someModelObject);
0
Sudip Bhandari

Une autre solution simple consiste à ajouter une dépendance jackson-databind dans POM.

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.1</version>
    </dependency>

Gardez le reste du code tel quel.

0
PraBhu