Spring 3 MVC の HttpMessageConverter 機能を使って RESTful な Web サービスを作成する

Spring は Java EE (Java™ Platform, Enterprise Edition) アプリケーションを作成するためのフレームワークとしてよく知られています。この Spring が、MVC (Model-View-Controller) 層で REST (Representational State Transfer) をサポートするようになりました。RESTful な Web サービスでは、クライアントのリクエストに基づいて多様な表現を作成することが重要です。この記事では、HttpMessageConverter を使用して多様な表現を作成する方法を学びます。この記事のコード・サンプルには、HttpMessageConverterRestTemplate とを組み合わせることでサービスと通信する方法が示されています。また、Spring の API とアノテーションを使用して、よく使われる表現 (Atom フィード、XML、JSON (JavaScript Object Notation) など) を生成する RESTful な Web サービスを作成する方法も学びます。

Yi Ming Huang, Software Engineer, IBM  

Yi Ming Huang は、China Development Lab で Lotus Mashups に取り組んでいるソフトウェア・エンジニアです。ポートレット/ウィジェット関連の Web 開発で経験を積んだ彼は、REST、OSGi、および Spring 技術に興味を持っています。



2010年 9月 07日

はじめに

この記事と似たテーマを取り上げた「Spring 3 を使って RESTful な Web サービスを作成する」(「参考文献」を参照) でも、Spring を使って RESTful な Web サービスを作成する方法を紹介しました。またその記事では、ContentNegotiatingViewResolver を使って多様な表現を作成する方法を説明しました。多様な表現を作成できることは、RESTful な Web サービスの重要な機能の 1 つです。この記事では、多様な表現を作成するための方法として、HttpMessageConverter を使用する方法を説明します。この記事で紹介するサンプル・コードでは、HttpMessageConverterRestTemplate とを組み合わせてサービスと通信する方法を示します。


Spring MVC での REST のサポート

このセクションでは、Spring の重要な機能、つまり RESTful な Web サービスをサポートするアノテーションの概要を説明します。

@Controller
@Controller アノテーションを使用すると、MVC のコントローラーとなるクラスにアノテーションを付け、HTTP リクエストを処理することができます。
@RequestMapping
@RequestMapping アノテーションを使用すると、特定の HTTP メソッド、URI、HTTP ヘッダーを処理する関数にアノテーションを付けることができます。このアノテーションは Spring の REST サポートにとって非常に重要です。@RequestMapping アノテーションの method パラメーターを変更すると、他の HTTP メソッドを処理することができます。

例えば以下のようにします。

@RequestMapping(method=RequestMethod.GET, value="/emps", 
headers="Accept=application/xml, application/json")
@PathVariable
@PathVariable アノテーションを使用すると、URI のパス変数をパラメーターとして注入することができます。

例えば以下のようにします。

@RequestMapping(method=RequestMethod.GET, value="/emp/{id}")
public ModelAndView getEmployee(@PathVariable String id) { … }
他の便利なアノテーション
@RequestParam を使用すると、URL パラメーターをメソッドの中に注入することができます。

@RequestHeader を使用すると、特定の HTTP ヘッダーをメソッドの中に注入することができます。

@RequestBody を使用すると、HTTP リクエストの本体をメソッドの中に注入することができます。

@ResponseBody を使用すると、コンテンツまたはオブジェクトを HTTP レスポンスの本体として返すことができます。

HttpEntity<T> をパラメーターとして使用すると、メソッドの中に HttpEntity<T> を自動的に注入することができます。

ResponseEntity<T> を使用すると、カスタムのステータスまたはヘッダーを持つ HTTP レスポンスを返すことができます

例えば以下のようにします。

public @ResponseBody Employee getEmployeeBy(@RequestParam("name") 
String name, @RequestHeader("Accept") String accept, @RequestBody String body) {…} 
public ResponseEntity<String> method(HttpEntity<String> entity) {…}

メソッドに注入できるアノテーションやオブジェクトとしてサポートされているものの完全な一覧は、Spring のドキュメントを参照してください (「参考文献」を参照)。

多様な表現のサポート

同じリソースを多様な MIME タイプで表現できることは、RESTful な Web サービスの重要な側面の 1 つです。通常、異なる表現によるリソースを取得するために、HTTP ヘッダーの Accept の値のみが異なる、同じ URI を使用します。また、異なる URI を使用することも、異なるリクエスト・パラメーターを持つ URI を使用することもできます。

「Spring 3 を使って RESTful な Web サービスを作成する」(「参考文献」を参照) では ContentNegotiatingViewResolver を紹介しました。ContentNegotiatingViewResolver を使って異なるビュー・リゾルバーを選択することで、(Accept ヘッダーの異なる) 同じ URI を扱うことができます。つまり ContentNegotiatingViewResolver を使用することで、多様な表現を作成することができます。

また、多様な表現を作成するための別の方法として、HttpMessageConverter@ResponseBody アノテーションとを組み合わせる方法があります。この方法を使う場合には、ビュー技術を使う必要はありません。


HttpMessageConverter

HTTP のリクエストとレスポンスはテキスト・ベースです。つまりブラウザーとサーバーはそのままのテキストを交換して通信します。しかし Spring では、コントローラー・クラスのメソッドは純粋な String 型と、ドメイン・モデル (または他の Java 埋め込みオブジェクト) を返します。Spring では、オブジェクトとそのままのテキストとの間で、どのようにしてシリアライズまたはデシリアライズするのでしょう。その処理を行うのが HttpMessageConverter です。Spring には、一般的な用途に合った実装がバンドルされています。表 1 はその一例です。

表 1. HttpMessageConverter の例
実装の種類機能
StringHttpMessageConverterリクエストとレスポンスのストリングを読み書きします。デフォルトで、メディア・タイプ text/* をサポートし、text/plain という Content-Type で書き込みます。
FormHttpMessageConverterリクエストとレスポンスのデータを読み書きします。デフォルトで、メディア・タイプ application/x-www-form-urlencoded を読み取り、MultiValueMap<String,String> にデータを書き込みます。
MarshallingHttpMessageConverterSpring のマーシャラーとアンマーシャラーを使って XML データを読み書きします。メディア・タイプ application/xml のデータを変換します。
MappingJacksonHttpMessageConverterJackson の ObjectMapper を使って JSON データを読み書きします。メディア・タイプ application/json のデータを変換します。
AtomFeedHttpMessageConverterROME の Feed API を使って Atom フィードを読み書きします。メディア・タイプ application/atom+xml のデータを変換します。
RssChannelHttpMessageConverterROME の Feed API を使って RSS フィードを読み書きします。メディア・タイプ application/rss+xml のデータを変換します。

RESTful な Web サービスを作成する

このセクションでは、多様な表現を生成できる、単純で RESTful な Web サービスを作成する方法を学びます。このサンプル・アプリケーションで使用するリソースの一部は「Spring 3 を使って RESTful な Web サービスを作成する」(「参考文献」を参照) の中で作成したものです。このアプリケーションのサンプル・コードはダウンロードすることもできます。

まず、HttpMessageConverter を構成する必要があります。多様な表現を生成するためには、いくつかの HttpMessageConverter インスタンスをカスタマイズし、多様なメディア・タイプにオブジェクトを変換します。このセクションでは、メディア・タイプが JSON、Atom、XML の場合について説明します。

JSON

まず、最も単純な例から始めましょう。JSON は人間が容易に読み書きできる軽量なデータ交換フォーマットです。リスト 1 は JSON コンバーターを構成するためのコードを示しています。

リスト 1. rest-servlet.xml で HttpMessageConverter を構成する
<bean class="org.springframework.web.servlet.mvc.annotation
.AnnotationMethodHandlerAdapter">
   <property name="messageConverters">
       <list>
           <ref bean="jsonConverter" />
   <ref bean="marshallingConverter" />
   <ref bean="atomConverter" />
       </list>
   </property>
</bean>

<bean id="jsonConverter" 
            class="org.springframework.http.converter.json
.MappingJacksonHttpMessageConverter">
   <property name="supportedMediaTypes" value="application/json" />
</bean>

この構成の中では、3 つのコンバーターが登録されています。MappingJacksonHttpMessageConverter は、オブジェクトから JSON への変換と、その逆変換に使われています。この組み込みのコンバーターは Jackson の ObjectMapper を使って JSON を JavaBean にマッピングします。そのため、以下の Jackson JAR ファイルをクラスパスに追加する必要があります。

  • org.codehaus.jackson.jar
  • org.codehaus.jackson.mapper.jar

次のステップでは、JSON 表現を要求するリクエストを扱うメソッドを作成します。リスト 2 にその詳細を示します。

リスト 2. EmployeeController で定義された JSON リクエストを扱う
@RequestMapping(method=RequestMethod.GET, value="/emp/{id}", 
		headers="Accept=application/json")
public @ResponseBody Employee getEmp(@PathVariable String id) {
Employee e = employeeDS.get(Long.parseLong(id));
return e;
}
	
@RequestMapping(method=RequestMethod.GET, value="/emps", 
		headers="Accept=application/json")
public @ResponseBody EmployeeListinggetAllEmp() {
List<Employee> employees = employeeDS.getAll();
EmployeeListinglist = new EmployeeList(employees);
return list;
}

@ResponseBody アノテーションを使用することで、返されるオブジェクト (Employee または EmployeeList) をレスポンス本体に含めるようにし、そのレスポンス本体の内容を MappingJacksonHttpMessageConverter によって JSON にマッピングしています。

HttpMessageConverter@ResponseBody を使用すると、Spring のビュー技術を使用せずに多様な表現を実装することができ、この点は ContentNegotiatingViewResolver を使用する方法よりも優れています。

これで、curl、または RESTClient というFirefox プラグインを使ってリクエストを呼び出すことができます。HTTP ヘッダーとして Accept=application/json を追加するのを忘れないでください。リスト 3 は、想定されるレスポンスを JSON フォーマットで表現したものです。

リスト 3. getEmp() と getAllEmp() の結果の JSON 表現
Response for /rest/service/emp/1
{"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"}

Response for /rest/service/emps
{"count":2,
"employees":[
{"id":1,"name":"Huang Yi Ming","email":"huangyim@cn.ibm.com"},
{"id":2,"name":"Wu Dong Fei","email":"wudongf@cn.ibm.com"}
]}

XML

Spring に組み込まれたコンバーター、MarshallingHttpMessageConverter は、オブジェクトと XML との間のマッピング (OXM) に使用されます。下記の例では MarshallingHttpMessageConverter のマーシャラーとアンマーシャラーとして JAXB 2 を使用しています。リスト 4 にこの構成を示します。

リスト 4. MarshallingHttpMessageConverter を構成する
<bean id="marshallingConverter" 
class="org.springframework.http.converter.xml
		.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
    <property name="supportedMediaTypes" value="application/xml"/>
      </bean>

      <bean id="jaxbMarshaller" 
      class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
      
    <property name="classesToBeBound">
	  <list>
	    <value>dw.spring3.rest.bean.Employee</value>
	    <value>dw.spring3.rest.bean.EmployeeList</value>
	  </list>
    </property>
    
</bean>

JAXB 2 では java.util.List<T> から XML へのマッピングのサポートが十分なものではないことを理解しておくことが重要です。一般的な方法としては、オブジェクトの集合に対するラッパー・クラスを追加します。この、JAXB でアノテーションが付けられたクラスの詳細については、「Spring 3 を使って RESTful な Web サービスを作成する」(「参考文献」を参照) を参照するか、あるいはソース・コードをダウンロードしてください。

コントローラーの中でリクエストを処理するメソッドについてはどうなのでしょう。前に戻ってリスト 2 のコードを見てください。当然ですが、ここには何もコードを追加する必要がありません。単純に、サポートされているもう 1 つのメディア・タイプを下記のように Accept ヘッダーに追加すればよいのです。

headers=”Accept=application/json, application/xml”

MarshallingHttpMessageConverter により、オブジェクトは要求されたタイプ (JSON または XML) に適切にマッピングされます。リスト 5 は application/xml 表現を要求した場合に想定される結果を示しています。

リスト 5. getEmp() と getAllEmp() の結果の XML 表現
Response for /rest/service/emp/1
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <employee>
   <email>huangyim@cn.ibm.com</email>
   <id>1</id>
   <name>Huang Yi Ming</name>
 </employee>
Response for /rest/service/emps
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <employees>
  <count>2</count>
    <employee>
      <email>huangyim@cn.ibm.com</email>
      <id>1</id>
      <name>Huang Yi Ming</name>
    </employee>
    <employee>
      <email>wudongf@cn.ibm.com</email>
      <id>2</id><name>Wu Dong Fei</name>
    </employee>
 </employees>

Atom フィード

RESTful な Web サービスでデータを交換するためのフォーマットとして、Atom フィードもよく使われています。Atom フィード文書は Atom フィードの表現であり、その中には、そのフィードに関するメタデータと、そのフィードに関連付けられた一部のエントリーまたはすべてのエントリーが含まれています。Atom フィードのルートは atom:feed 要素です。また、Atom 出版プロトコル (Atom Publish Protocol: APP) を使って交換フォーマットと動作を定義する方法もあります。(この記事では Atom フォーマットや APP フォーマットの定義については省略します。これらのフォーマットの詳細については「参考文献」を参照してください。)

下記の例では AtomFeedHttpMessageConverter を使用して Atom フィードを変換しています。この Atom フィードには ROME の Atom API を使用しています。そのため、sun.syndication.jar という JAR ファイルをクラスパスに含める必要があります。リスト 6 に、このコンバーターの構成を示します。

リスト 6. AtomFeedHttpMessageConverter を構成する
<bean id="atomConverter" 
class="org.springframework.http.converter.feed
		.AtomFeedHttpMessageConverter">
<property name="supportedMediaTypes" value="application/atom+xml" />
</bean>

リスト 7 に Atom リクエストとフィードの生成を扱うコードを示します。

リスト 7. EmployeeControllerの getEmpFeed() と、AtomUtil クラス
@RequestMapping(method=RequestMethod.GET, value="/emps", 
		headers="Accept=application/atom+xml")
public @ResponseBody Feed getEmpFeed() {
	List<Employee> employees = employeeDS.getAll();
	return AtomUtil.employeeFeed(employees, jaxb2Mashaller);
}

public static Feed employeeFeed(
	List<Employee> employees, Jaxb2Marshaller marshaller) {
Feed feed = new Feed();
feed.setFeedType("atom_1.0");
feed.setTitle("Employee Atom Feed");
		
List<Entry> entries = new ArrayList<Entry>();
for(Employee e : employees) {
	StreamResult result = new StreamResult(
	new ByteArrayOutputStream());
	marshaller.marshal(e, result);
	String xml = result.getOutputStream().toString();
			
	Entry entry = new Entry();
	entry.setId(Long.valueOf(e.getId()).toString());
	entry.setTitle(e.getName());
	Content content = new Content();
	content.setType(Content.XML);
	content.setValue(xml);
	
	List<Content> contents = new ArrayList<Content>();
	contents.add(content);
	entry.setContents(contents);
	entries.add(entry);
}
feed.setEntries(entries);
return feed;
}

上記のコードでは以下に注意してください。

  • getEmpFeed() メソッドは getAllEmp() と同じ URI を扱いますが、Accept ヘッダーは異なります。
  • employeeFeed() メソッドを使って Employee オブジェクトを XML にマーシャリングし、その XML をフィードのエントリーの <content> 要素に追加しています。

リスト 8 は /rest/service/emps という URI の application/atom+xml 表現を要求した場合の出力を示しています。

リスト 8. application/atom+xml を要求した場合の /rest/service/emps の出力
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Employee Atom Feed</title>

 <entry>
    <title>Huang Yi Ming</title>
    <id>1</id>
  <content type="xml">
    <employee>
            <email>huangyim@cn.ibm.com</email>
            <id>1</id>
            <name>Huang Yi Ming</name>
    </employee>
  </content>
</entry>

  <entry>
    <title>Wu Dong Fei</title>
    <id>2</id>
  <content type="xml">
    <employee>
            <email>wudongf@cn.ibm.com</email>
            <id>2</id>
            <name>Wu Dong Fei</name>
     </employee>
   </content>
 </entry>
 
</feed>

POST、PUT、DELETE を実装する

ここまでに示した例では、いくつかのメソッドを実装して HTTP の GET メソッドの処理を行いました。リスト 9 に、POSTPUTDELETE メソッドの実装を示します。

リスト 9. EmployeeController の POST、PUT、DELETE メソッド
@RequestMapping(method=RequestMethod.POST, value="/emp")
public @ResponseBody Employee addEmp(@RequestBody Employee e) {
employeeDS.add(e);
return e;
}
	
@RequestMapping(method=RequestMethod.PUT, value="/emp/{id}")
public @ResponseBody Employee updateEmp(
	@RequestBody Employee e, @PathVariable String id) {
employeeDS.update(e);
return e;
}
	
@RequestMapping(method=RequestMethod.DELETE, value="/emp/{id}")
public @ResponseBody void removeEmp(@PathVariable String id) {
employeeDS.remove(Long.parseLong(id));
}

@RequestBody アノテーションは addEmp() メソッドと updateEmp() メソッドに使われています。@RequestBody アノテーションは HTTP リクエストの本体を引数に取り、登録された HttpMessageConverter を使ってその引数をオブジェクト・クラスに変換します。次のセクションでは、これらのサービスとの通信を、RestTemplate を使って行います。


RestTemplate を使って REST サービスと通信する

「Spring 3 を使って RESTful な Web サービスを作成する」(「参考文献」を参照) では、curl と RESTClient を使って REST サービスをテストする方法を紹介しました。プログラミング・レベルでは、通常は Jakarta Commons の HttpClient を使って REST サービスをテストします (ただし、それについてはこの記事では省略します)。RestTemplate という、Spring の REST クライアントを使うこともできます。RestTemplate は概念的に、JdbcTemplateJmsTemplate といった Spring の他のテンプレート・クラスと似ています。

RestTemplateHttpMessageConverter を使用します。リクエストの中でオブジェクト・クラスを渡すと、コンバーターによってマッピングの処理が行われます。

RestTemplate を構成する

リスト 10 は RestTemplate の構成を示しています。この構成にも、先ほど紹介した 3 つのコンバーターを使用しています。

リスト 10. RestTemplate を構成する
<bean id="restTemplate" 
class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
	<list>
	<ref bean="marshallingConverter" />
	<ref bean="atomConverter"  />
	<ref bean="jsonConverter" />
	</list>
</property>
</bean>

この記事の例では、サーバーとの通信を単純化するメソッドの一部のみを使用しました。RestTemplate は他にも以下のようなメソッドをサポートしています。

  • exchange: リクエスト本体を使って HTTP メソッドを実行し、レスポンスを取得します。
  • getForObject: HTTP GET メソッドを実行し、レスポンスをオブジェクトとして取得します。
  • postForObject: リクエスト本体を使って HTTP POST メソッドを実行します。
  • put: リクエスト本体を使って HTTP PUT メソッドを実行します。
  • delete: URI に対して HTTP DELETE メソッドを実行します。

コード・サンプル

以下のコード・サンプルは RestTemplate の使い方を説明しています。ここで使用している API の詳細な説明は RestTemplate の API (「参考文献」を参照) を参照してください。

リスト 11 は、リクエストにヘッダーを追加した後、そのリクエストを呼び出す方法を示しています。MarshallingHttpMessageConverter を使用すると、レスポンスを取得した後、指定のクラスに変換することができます。異なるメディア・タイプを使用すると、他の表現をテストすることができます。

リスト 11. XML 表現を要求する例
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<EmployeeList> response = restTemplate.exchange(
"http://localhost:8080/rest/service/emps", 
HttpMethod.GET, entity, EmployeeList.class);
EmployeeListingemployees = response.getBody();
// handle the employees

リスト 12 は新しい従業員 (employee) をサーバーに POST する方法を示しています。サーバー・サイドのサービス addEmp() は、メディア・タイプが application/xml と application/json のデータを受け付けます。

リスト 12. 新しい従業員を POST する
Employee newEmp = new Employee(99, "guest", "guest@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
ResponseEntity<Employee> response = restTemplate.postForEntity(
"http://localhost:8080/rest/service/emp", entity, Employee.class);
Employee e = response.getBody();
// handle the employee

リスト 13 は、従業員に対する変更を PUT して、その従業員の元のデータを更新する方法を示しています。またリスト 13 には、リクエスト URI の中でプレース・ホルダー ({id}) として使用できる機能も示されています。

リスト 13. PUT を使用して従業員のデータを更新する
Employee newEmp = new Employee(99, "guest99", "guest99@ibm.com");
HttpEntity<Employee> entity = new HttpEntity<Employee>(newEmp);
restTemplate.put(
	"http://localhost:8080/rest/service/emp/{id}", entity, "99");

リスト 14 は既存の従業員のデータを DELETE する方法を示しています。

リスト14. 既存の従業員のデータを DELETE する
restTemplate.delete(
	"http://localhost:8080/rest/service/emp/{id}", "99");

まとめ

この記事では、Spring 3 で導入された HttpMessageConverter について学びました。HttpMessageConverter を使用することで、クライアント・サイドとサーバー・サイドの両方で、多様な表現をサポートすることができます。この記事で提供しているソース・コードを利用すると、この記事で説明した HttpMessageConverter の実装と、「Spring 3 を使って RESTful な Web サービスを作成する」で説明した ContentNegotiatingViewResolver を使用した実装との違いを調べることができます。


ダウンロード

内容ファイル名サイズ
Article source codesrc_code.zip11KB

参考文献

学ぶために

  • この記事と合わせて、Spring を使って RESTful な Web サービスを作成する方法を紹介した「Spring 3 を使って RESTful な Web サービスを作成する」(developerWorks、2010年7月) を読んでください。
  • REST の紹介、その他関連のリンクをウィキペディアで見てください。
  • Spring MVC 3 Showcase を調べ、この技術によって何を実現できるかを理解してください。このサイトには、サンプル・プロジェクトを始め、この技術を解説したスライド・プレゼンテーションやスクリーンキャストも用意されています。
  • Spring 3 のすべてについて学んでください。
  • RestTemplate API について調べてください。
  • JAXB リファレンス実装プロジェクトについての資料を読んでください。
  • Atom/RSS のための一連の Java ユーティリティー、ROME について調べてください。ROME を使うことで、ほとんどの配信フォーマットを Java で容易に処理することができます。
  • Atom についての資料を読んでください。
  • developerWorks の連載記事、「Atom 出版プロトコルを知る」(2006年10月) を読んでください。Atom プロトコルの上位レベルの概要と Atom の基本的な操作と機能が解説されています。
  • 高速でオープンソースの JSON プロセッサー、Jackson について学んでください。

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development, SOA and web services
ArticleID=550587
ArticleTitle=Spring 3 MVC の HttpMessageConverter 機能を使って RESTful な Web サービスを作成する
publish-date=09072010