Spring MVCを使用してRESTサービスを作成しようとしていますが、プレーン文字列を返す場合は機能しています。私の要件はJava object。暗黙の変換によってこれを達成する方法がわかりません。
ここに私のコードがあります:
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;
}
}
ここでhttp:// localhost:8080/schoolmangement/rest/student/testURLは「Test RESTサービス!!!」
ただし、http:// localhost:8080/schoolmangement/rest/student/1エラーが発生したHTTPステータスコード406のURLメッセージ:
このリクエストで識別されたリソースは、リクエストの「accept」ヘッダーに従って受け入れられない特性を持つレスポンスのみを生成できます。
最後に、Spring MVCとともにJacksonライブラリを使用してソリューションを得ました。 Journal Dev( http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program の例からこのソリューションを得ました=)
したがって、私が行ったコード変更は次のとおりです。
RESTサービスコントローラーに変更を加えていません。デフォルトではJSONに変換されます。
Webメソッドの上に@Produces("application/json")
を常に追加するか、produces="application/json"
を指定してjsonを返すことができます。次に、Student
クラスの上に、@XmlRootElement
パッケージからjavax.xml.bind.annotation
を追加できます。
モデルクラスを直接返すことはお勧めできません。ただの提案。
HTH。
コントローラに適切に注釈が付けられている場合、Springフレームワーク自体がjson変換を処理します。
例えば:
@PutMapping(produces = {"application/json"})
@ResponseBody
public UpdateResponse someMethod(){ //do something
return UpdateResponseInstance;
}
ここで、SpringはUpdateResponseオブジェクトを対応するjson文字列に内部的に変換して返します。それを行うために、内部で Jacksonライブラリー を使用します
コントローラから離れた場所にあるモデルオブジェクトのJSON表現が必要な場合は、jacksonが提供するobjectMapperを使用できます。これが機能するには、モデルに適切に注釈を付ける必要があります。
例えば:
ObjectMapper mapper = new ObjectMapper();
SomeModelClass someModelObject = someModelRepository.findById(idValue).get();
mapper.writeValueAsString(someModelObject);
Json変換はそのまま使用できます。これを実現するには、いくつかの簡単な構成を追加する必要があります。
最初にcontentNegotiationManagerをspring configファイルに追加します。応答タイプのネゴシエーションを担当します。
<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 />
次に、サービスのクラスパスにJackson2 jar(jackson-databindおよびjackson-core)を追加します。ジャクソンは、JSONへのデータのシリアル化を担当しています。 Springはこれらを検出し、MappingJackson2HttpMessageConverterを自動的に初期化します。これのみを構成すると、JSONへの自動変換が機能します。説明した構成には、accept:application/xml headerを設定した場合にXMLにシリアル化できるという追加の利点があります。
別の簡単な解決策は、Packにjackson-databind依存関係を追加することです。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
残りのコードはそのままにします。