RestEasy実装サンプルのまとめ。
ここの所触ってきたRestEasy2.0.1.GAのまとめのサンプルコードになります。
使用頻度の高そうなものをサンプルコードで触れるようにしました。
このコードで下記の実装方法がだいたいわかるかと思います。
ここに載せているのはRestEasyのクラスやメソッドの使い方なので、
あとは実際にRESTの仕様にのっとった自分が必要とするRESTサービスを
作ってみるといいかと思います。
●クライアントからの各メソッドのRequestにおけるリクエストヘッダ、
Form値、QueryString値、URLパラメータの送信方法
●サーバ側でのRequestからのレスポンスヘッダ、Form値、
QueryString値、URLパラメータの取得方法
●サーバ側でのResponseで返すデータ部のxmlやjsonの元になる
Beanの作成方法(簡単なものだけですが。。。)
●サーバ側でのResponseのステータスコードやHTTPヘッダー、
データ部の設定方法
※レスポンスのボディ部をXMLにしたい場合は@Produces("application/json")の部分を
@Produces("application/xml")にしてもらうとXMLでのやり取りに変わります。
pom.xml
<?xml version="1.0" encoding="UTF-16"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>sample</groupId> <artifactId>sample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <!-- TODO project name --> <name>quickstart</name> <description/> <dependencies> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jaxrs</artifactId> <version>2.0.1.GA</version> <!-- filter out unwanted jars --> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> <exclusion> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </exclusion> <exclusion> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jettison-provider</artifactId> <version>2.0.1.GA</version> <exclusions> <exclusion> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </exclusion> <exclusion> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> </exclusion> <exclusion> <groupId>javax.xml.stream</groupId> <artifactId>stax-api</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <repositories> <repository> <id>jboss</id> <name>jboss repo</name> <url>http://repository.jboss.org/nexus/content/groups/public/</url> </repository> </repositories> <build> <resources> <resource> <filtering>false</filtering> <directory>src/main/resources</directory> </resource> <resource> <filtering>false</filtering> <directory>src/main/java</directory> <includes> <include>**</include> </includes> <excludes> <exclude>**/*.java</exclude> </excludes> </resource> </resources> <testResources> <testResource> <filtering>false</filtering> <directory>src/test/java</directory> <includes> <include>**</include> </includes> <excludes> <exclude>**/*.java</exclude> </excludes> </testResource> </testResources> <plugins> <plugin> <inherited>true</inherited> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> <optimize>true</optimize> <debug>true</debug> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <configuration> <downloadSources>true</downloadSources> </configuration> </plugin> </plugins> </build> </project>
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>sample</display-name> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
サーバ側コード
package sample.sample.resources; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import sample.sample.bean.ResponseBean; /** * /sampleに対するリソース * * @author bose999 * */ @Path("/sample") public class SampleResource { /** * コンストラクタ */ public SampleResource() { } /** * /コンテキストルート/sample という形式のURLでPUTコールされた場合の処理 * * @param hTest01 * HTTP Header h-test01 * @param hTest02 * HTTP Header h-test02 * @param inputString * URL Param inputString * @param qTest01 * URL QueryParam(?q-test01=xx) q-test01 * @param qTest02 * URL QueryParam(?q-test02=xx) q-test01 * @return Response */ @GET @Path("/{inputString}") // /コンテキスト名/sample/xxxx という形式のURLでxxxをパラメータとして定義 @Produces("application/json") public Response getSample(@HeaderParam("h-test01") String hTest01, @HeaderParam("h-test02") String hTest02, @PathParam("inputString") String inputString, @QueryParam("q-test01") String qTest01,@QueryParam("q-test02") String qTest02) { // RestEasyにステータスコード200でResponseBeanの内容でXMLを生成して処理を返してもらう return makeResponse(200,hTest01 + hTest02 + inputString + qTest01+ qTest02); } /** * /コンテキストルート/sample という形式のURLでPUTコールされた場合の処理 * * @param hTest01 * HTTP Header h-test01 * @param hTest02 * HTTP Header h-test02 * @param test01 * Form value test01 * @param test02 * Form value test02 * @param inputString * URL Param inputString * @param qTest01 * URL QueryParam(?q-test01=xx) q-test01 * @return Response */ @PUT @Path("/{inputString}") // /コンテキスト名/sample/xxxx という形式のURLでxxxをパラメータとして定義 @Produces("application/json") public Response putSample(@HeaderParam("h-test01") String hTest01, @HeaderParam("h-test02") String hTest02, @FormParam("test01") String test01, @FormParam("test02") String test02, @PathParam("inputString") String inputString, @QueryParam("q-test01") String qTest01) { // RestEasyにステータスコード200でResponseBeanの内容でXMLを生成して処理を返してもらう return makeResponse(200,hTest01 + hTest02 + test01 + test02 + inputString + qTest01); } /** * /コンテキストルート/sample という形式のURLでPUTコールされた場合の処理 * * @param hTest01 * HTTP Header h-test01 * @param hTest02 * HTTP Header h-test02 * @param test01 * Form value test01 * @param test02 * Form value test02 * @param inputString * URL Param inputString * @param qTest01 * URL QueryParam(?q-test01=xx) q-test01 * @return Response */ @POST @Path("/{inputString}") // /コンテキスト名/sample/xxxx という形式のURLでxxxをパラメータとして定義 @Produces("application/json") public Response postSample(@HeaderParam("h-test01") String hTest01, @HeaderParam("h-test02") String hTest02, @FormParam("test01") String test01, @FormParam("test02") String test02, @PathParam("inputString") String inputString, @QueryParam("q-test01") String qTest01) { // RestEasyにステータスコード200でResponseBeanの内容でXMLを生成して処理を返してもらう return makeResponse(200,hTest01 + hTest02 + test01 + test02 + inputString + qTest01); } /** * /コンテキストルート/sample という形式のURLでPUTコールされた場合の処理 * * @param hTest01 * HTTP Header h-test01 * @param hTest02 * HTTP Header h-test02 * @param inputString * URL Param inputString * @param qTest01 * URL QueryParam(?q-test01=xx) q-test01 * @return Response */ @DELETE @Path("/{inputString}") // /コンテキスト名/sample/xxxx という形式のURLでxxxをパラメータとして定義 @Produces("application/json") public Response deleteSample(@HeaderParam("h-test01") String hTest01, @HeaderParam("h-test02") String hTest02, @PathParam("inputString") String inputString, @QueryParam("q-test01") String qTest01) { // RestEasyにステータスコード200でResponseBeanの内容でXMLを生成して処理を返してもらう return makeResponse(200,hTest01 + hTest02 + inputString + qTest01); } /** * statusCodeとreturnStringの内容でレスポンスのXMLを生成する * * @param statusCode int * @param returnString String * @return Response */ private Response makeResponse(int statusCode,String returnString){ ResponseBean responseBean = new ResponseBean(); responseBean.returnString = returnString; // Responseを生成するResponseBuilderをステータスコード200で生成 ResponseBuilder responseBuilder = Response.status(200); // XMLを返す為にResponseBeanを渡す responseBuilder = responseBuilder.entity(responseBean); // HTTPヘッダーに値を追加 responseBuilder.header("ORIGINAL01", "original01"); responseBuilder.header("ORIGINAL02", "original02"); // Responseを生成する Response response = responseBuilder.build(); return response; } }
サーバ側Bean
package sample.sample.bean; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name="response") public class ResponseBean { @XmlElement(name="return") public String returnString; }
クライアント側コード
package sample.sample.bean.client; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Set; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; import org.jboss.resteasy.client.ClientRequest; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.plugins.providers.RegisterBuiltin; import org.jboss.resteasy.spi.ResteasyProviderFactory; import sample.sample.bean.ResponseBean; /** * http://localhost:8080/sample/sampleに * アクセスして結果を標準出力する * * @author bose999 * */ public class SampleClient { /** * RestEasyサーバにアクセスして結果を標準出力へ * * @param args String[] */ public static void main(String[] args) { // RESTEasy初期化 RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); // アクセスするURIをパラメータを含めて生成 String inputString = "xx"; String uri = UriBuilder.fromUri("http://localhost:8080/sample/sample") .path("/{inputString}").build(inputString).toString(); ClientRequest request; String returnString; ResponseBean responseBean; MultivaluedMap<String, String> formMultivaluedMap; MultivaluedMap<String, String> headerMultivaluedMap; try { // GETでアクセスし、HTTPヘッダーとURL Queryの値を渡す request = new ClientRequest(uri); headerMultivaluedMap = request.getHeaders(); headerMultivaluedMap.add("h-test01", "header-test01"); headerMultivaluedMap.add("h-test02", "header-test02"); request.queryParameter("q-test01", "query-test01"); request.queryParameter("q-test02", "query-test02"); // GETの戻りをStringで受けとり結果を標準出力へ printResponse4String(request, "GET"); // GETの戻りをResponseBeanで受けとり結果を標準出力へ printResponse4ResponseBean(request, "GET"); // PUTでアクセスし、HTTPヘッダーとForm、URL Queryの値を渡す request = new ClientRequest(uri); headerMultivaluedMap = request.getHeaders(); headerMultivaluedMap.add("h-test01", "header-test01"); headerMultivaluedMap.add("h-test02", "header-test02"); formMultivaluedMap = request.getFormParameters(); formMultivaluedMap.add("test01", "form-test01"); formMultivaluedMap.add("test02", "fomr-test02"); request.queryParameter("q-test01", "query-test01"); // PUTの戻りをStringで受けとり結果を標準出力へ printResponse4String(request, "PUT"); // PUTの戻りをResponseBeanで受けとり結果を標準出力へ printResponse4ResponseBean(request, "PUT"); // POSTでアクセスし、HTTPヘッダーとForm、URL Queryの値を渡す request = new ClientRequest(uri); headerMultivaluedMap = request.getHeaders(); headerMultivaluedMap.add("h-test01", "header-test01"); headerMultivaluedMap.add("h-test02", "header-test02"); formMultivaluedMap = request.getFormParameters(); formMultivaluedMap.add("test01", "form-test01"); formMultivaluedMap.add("test02", "fomr-test02"); request.queryParameter("q-test01", "query-test01"); // POSTの戻りをStringで受けとり結果を標準出力へ printResponse4String(request, "POST"); // POSTの戻りをResponseBeanで受けとり結果を標準出力へ printResponse4ResponseBean(request, "POST"); // DELETEでアクセスし、HTTPヘッダーとForm、URL Queryの値を渡す request = new ClientRequest(uri); headerMultivaluedMap = request.getHeaders(); headerMultivaluedMap.add("h-test01", "header-test01"); headerMultivaluedMap.add("h-test02", "header-test02"); request.queryParameter("q-test01", "query-test01"); // DELETEの戻りをStringで受けとり結果を標準出力へ printResponse4String(request, "DELETE"); // DELETEの戻りをResponseBeanで受けとり結果を標準出力へ printResponse4ResponseBean(request, "DELETE"); } catch (Exception e) { e.printStackTrace(); } } /** * HTTPヘッダーの内容をすべて標準出力へ * * @param responseHeaderMultivaluedMap MultivaluedMap<String, String> */ private static void printHeader( MultivaluedMap<String, String> responseHeaderMultivaluedMap) { Set<Entry<String, List<String>>> set = responseHeaderMultivaluedMap .entrySet(); Iterator<Entry<String, List<String>>> itr = set.iterator(); while (itr.hasNext()) { Entry<String, List<String>> enrtry = itr.next(); String key = enrtry.getKey(); String value = ""; int count = 0; List<String> list = enrtry.getValue(); for (String str : list) { if (count == 0) { value = value + str; } else { value = value + "," + str; } count++; } System.out.println("HTTP Header:" + key + " value:" + value); } } /** * Stringで受けて内容を標準出力へ * * @param request ClientResponse * @param methodName String * @throws Exception */ private static void printResponse4String(ClientRequest request, String methodName) throws Exception { ClientResponse<?> response = execHTTPMethod(request, methodName, String.class); printHeader(response.getHeaders()); String returnString = (String) response.getEntity(); System.out.println(methodName + " ステータスコード:" + response.getStatus()); System.out.println(methodName + " 戻り値:" + returnString); } /** * ResponseBeanに詰めて受けて内容を標準出力へ * * @param request * @param methodName * @throws Exception */ private static void printResponse4ResponseBean(ClientRequest request, String methodName) throws Exception { ClientResponse<?> response = execHTTPMethod(request, methodName, ResponseBean.class); printHeader(response.getHeaders()); ResponseBean responseBean = (ResponseBean) response.getEntity(); System.out.println(methodName + " ステータスコード:" + response.getStatus()); System.out.println(methodName + " 戻り値 return:" + responseBean.returnString); } /** * HTTPメソッドの種類を引数で特定しClientResponseを生成 * * @param request ClientRequest * @param methodName String * @param retrunClass Class * @return ClientResponse * @throws Exception */ private static ClientResponse<?> execHTTPMethod(ClientRequest request, String methodName, Class<?> retrunClass) throws Exception { ClientResponse<?> response; if (methodName.equals("GET")) { response = request.get(retrunClass); } else if (methodName.equals("PUT")) { response = request.put(retrunClass); } else if (methodName.equals("POST")) { response = request.post(retrunClass); } else if (methodName.equals("DELETE")) { response = request.delete(retrunClass); } else { response = request.get(retrunClass); } return response; } }
このサンプルの標準出力の結果例
HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT GET ステータスコード:200 GET 戻り値:{"response":{"return":"header-test01header-test02xxquery-test01query-test02"}} HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT GET ステータスコード:200 GET 戻り値 return:header-test01header-test02xxquery-test01query-test02 HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT PUT ステータスコード:200 PUT 戻り値:{"response":{"return":"header-test01header-test02form-test01fomr-test02xxquery-test01"}} HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT PUT ステータスコード:200 PUT 戻り値 return:header-test01header-test02form-test01fomr-test02xxquery-test01 HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT POST ステータスコード:200 POST 戻り値:{"response":{"return":"header-test01header-test02form-test01fomr-test02xxquery-test01"}} HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:55 GMT POST ステータスコード:200 POST 戻り値 return:header-test01header-test02form-test01fomr-test02xxquery-test01 HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:57 GMT DELETE ステータスコード:200 DELETE 戻り値:{"response":{"return":"header-test01header-test02xxquery-test01"}} HTTP Header:Content-Type value:application/json HTTP Header:ORIGINAL02 value:original02 HTTP Header:Transfer-Encoding value:chunked HTTP Header:ORIGINAL01 value:original01 HTTP Header:Server value:Apache-Coyote/1.1 HTTP Header:Date value:Tue, 17 Aug 2010 15:20:57 GMT DELETE ステータスコード:200 DELETE 戻り値 return:header-test01header-test02xxquery-test01