Spring 3.0 の REST を試してみた。
■ やること
Spring 3.0 で REST がサポートされたというのでやってみる。ただし、余りサンプルを見かけない PUT をやってみる。あとJAXB のバインディングのやり方も確認しておきたい。
以下のような、なんちゃって仕様を実装する。
- http://localhost:8888/hello-rest 以下にリソース Foo がある
- Foo は id で識別され、プロパティを name 持つ。
- たとえば、id=100 の リソース Foo をリクエストの内容で更新する操作は以下のようになる
URL http://localhost:8888/hello-rest/foo/id/100 method PUT 内容 <foo><name>hoge</name></foo> - 実際にリソース更新する変わりに、操作の内容を標準出力に書き出す
■ 使うもの
- Eclipse 3.5 Galileo + WTP + m2eclipse
- Maven 2.2.1
- Tomcat v6.0
■ サーバ
- Java Project を作って、Dynamic Web Project 且つ Maven Project にする。
- POM には 以下の依存を記述
groupId artifactId version org.springframework spring-webmvc 3.0.0.RELEASE org.springframework spring-oxm 3.0.0.RELEASE javax.servlet servlet-api 2.5 - リソース Foo は以下のようなクラスで表現する(以下、パッケージはどれも springmvc.web とした)
@XmlRootElement public class Foo { String name = ""; public Foo() {} public Foo(String name) { this.name = name; } public void setName(String name) { this.name = name; } public String getName() { return name; } }
- コントローラはこんな風になる。
@Controller @RequestMapping("/foo") public class FooController { @RequestMapping( value = "/id/{fooId}", method = RequestMethod.PUT) public View handle( @RequestBody Foo foo, @PathVariable int fooId) throws IOException { System.out.printf( "name of Foo(id=%d) --> %s%n", fooId, foo.getName()); return new StatusOK(); } }
- StatusOK はこんなふうにした。(合ってるかどうか、ちょい不安)
class StatusOK implements View { public String getContentType() { return null; } public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setStatus(200); } }
- これらのクラスをこんな設定ファイルで協調させる。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="springmvc.web" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="unmarshaller" ref="restXmlMarshaller" /> </bean> </list> </property> </bean> <bean id="restXmlMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> <property name="contextPaths"> <list><value>springmvc.web</value></list> </property> </bean> </beans>
- web.xml はほぼ自明なので省略。ただし DispatcherServlet の url-pattern は "/" とする。
- Foo.java と同じフォルダに jaxb.index ファイルを置く。中身は単に、一言 Foo とだけ書く。
■ クライアント
クライアント用の Java プロジェクトを作って、
- Build Path に サーバ側プロジェクトへの依存も含め、
- POM で org.springframework の spring-webmvc の 3.0.0.RELEASE への依存を指定する
public class App { public static void main(String[] args) { final String uri = "http://localhost:8888/hello-rest/foo/id/100"; RestTemplate template = new RestTemplate(); template.put(uri, new Foo("hoge")); } }POM の<dependencies>には org.springframework の spring-webmvc の 3.0.0.RELEASE だけ指定. また、Build Path に サーバ側プロジェクトへの依存も含めておく。
実行すると、サーバ側のConsole ビューに "name of Foo(id=100) --> hoge" と 表示される。
ちなみに TCPMon で見るとこんな感じ
request |
PUT /hello-rest/foo/id/100 HTTP/1.1 Content-Type: application/xml User-Agent: Java/1.6.0_13 Host: 127.0.0.1:8888 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Content-Length: 83 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <foo> <name>hoge</name> </foo> |
response |
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Language: ja-JP Content-Length: 0 Date: Thu, 14 Jan 2010 13:18:45 GMT |
■ 参考サイト
この辺り
- http://www.developer.com/java/web/article.php/10935_3854986_2/Get-RESTful-with-Spring-30.htm
- http://grzegorzborkowski.blogspot.com/2009/03/test-drive-of-spring-30-m2-rest-support.html
0 件のコメント:
コメントを投稿