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.
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:
Je n'ai apporté aucune modification à mon contrôleur de service REST. Par défaut, il est converti en JSON.
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.
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.
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);
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.