RestEasyでシリアライズ/デシリアライズでBeanをやり取りする
RestEasyから文字列を返す。その文字列はBeanをシリアライズして
Base64エンコードした文字列。
クライアントは文字列を受け取りデシリアライズしてBeanを復元。
Beanの中身で処理を行なう。
というサンプル。
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 java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import org.apache.commons.codec.binary.Base64; import org.jboss.resteasy.annotations.GZIP; import sample.sample.bean.ResponseBean; /** * /sample/sampleSerializeに対するリソース * * @author bose999 * */ @Path("/sampleSerialize") public class SampleSerializeResources { /** * コンストラクタ */ public SampleSerializeResources(){ } /** * GETメソッドを受けてResponseBeanを生成し * シリアライズしてBase64エンコーディング文字列を返す * * @param fileName String * @return String */ @GET @GZIP @Produces("plain/txt") public String getSample(@QueryParam("fileName") String fileName){ String responseBeanString = ""; OutputStream outputStream = null; ObjectOutputStream objectOutputStream = null; try { // fileをbyte[]で取得する byte[] fileBinary = readBinaryFile("/data/sampleBinary/" + fileName); // シリアライズするBeanを生成し、値を詰め込む ResponseBean responseBean = new ResponseBean(); responseBean.returnString = "デシリアライズされて読めてますか?"; responseBean.fileBytes = fileBinary; responseBean.readTime = new Date(); List<Map<Integer,Integer>> maps = new ArrayList<Map<Integer,Integer>>(); for(int i=0;i<50;i++){ Map<Integer,Integer> map = new HashMap<Integer,Integer>(); map.put(i, i*10); maps.add(map); } responseBean.maps = maps; // ResponseBeanをシリアライズしてByteArrayOutputStreamにする outputStream = new ByteArrayOutputStream(); objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(responseBean); ByteArrayOutputStream byteArrayOutputStream = (ByteArrayOutputStream)outputStream; // シリアライズ結果のbyte[]をBase64エンコーディングしてUTF-8文字列にする byte[] encoded = Base64.encodeBase64(byteArrayOutputStream.toByteArray()); responseBeanString = new String(encoded, "UTF-8"); } catch (IOException e) { e.printStackTrace(); }finally{ if(objectOutputStream != null){ try { objectOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if(outputStream != null){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // RestEasyにStringを返してもらう return responseBeanString; } /** * フルパスのファイル名のファイルをbyte[]に変換する * * @param fileName * String * @return byte[] * @throws IOException */ private static byte[] readBinaryFile(String fileName) throws IOException { File file = new File(fileName); int fileLength = (int) file.length(); byte[] bytes = new byte[fileLength]; InputStream inputStream = null; try { inputStream = new FileInputStream(file); inputStream.read(bytes); } finally { if (inputStream != null) { inputStream.close(); } } return bytes; } }
サーバ側Bean
package sample.sample.bean; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Map; @SuppressWarnings("serial") public class ResponseBean implements Serializable{ public byte[] fileBytes; public Date readTime; public List<Map<Integer,Integer>> maps; public String returnString; }
クライアント
package sample.sample.bean.client; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.ws.rs.core.UriBuilder; import org.apache.commons.codec.binary.Base64; 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/sampleSerialize?fileName=xxx * にアクセスしてResponseBeanをデシリアライズする * * @author bose999 * */ public class SampleDeserializeClient { /** * EasyRestのURLにアクセスしてBase64エンコード文字列から * ResponseBeanをデシリアライズする * * @param args */ public static void main(String[] args) { // RESTEasy初期化 RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); // アクセスするURIをパラメータを含めて生成しリクエスト String fileName = "xxx.png"; // http://localhost:8080/sample/sampleSerialize?fileName=xxx.png というURIを生成 String uri = UriBuilder .fromUri("http://localhost:8080/sample/sampleSerialize") .queryParam("fileName", fileName).build().toString(); ClientRequest request = new ClientRequest(uri); request.header("Content-Encoding", "gzip"); InputStream inputStream = null; ObjectInputStream objectInputStream = null; OutputStream outputStream = null; try { // レスポンスからファイルの文字列を取得 ClientResponse<?> response = request.get(String.class); String responseBeanString = (String) response.getEntity(); // UTF-8のBase64文字列からbyte[]を復元 byte[] decode = Base64.decodeBase64(responseBeanString .getBytes("UTF-8")); // byte[]からResponseBeanを復元 inputStream = new ByteArrayInputStream(decode); objectInputStream = new ObjectInputStream(inputStream); ResponseBean responseBean = (ResponseBean) objectInputStream .readObject(); //結果の値を標準出力後、byte[]のフィールド値からファイルを復元 System.out.println(responseBean.returnString); System.out.println(responseBean.readTime); System.out.println("maps value out!"); List<Map<Integer,Integer>> maps = responseBean.maps; for(Map<Integer,Integer> map : maps){ for( Entry<Integer, Integer> set : map.entrySet()){ System.out.println("key:" + set.getKey().toString() + " value:" +set.getValue().toString()); } } // ファイルを生成する File outFile = new File("/data/sampleBinary/" + "return-" + fileName); outputStream = new FileOutputStream(outFile); outputStream.write(responseBean.fileBytes); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (objectInputStream != null) { try { objectInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }