首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

JAX-RS入门 6: 数据处理(1)

2012-11-10 
JAX-RS入门 六: 数据处理(1)接下来要花两小节来介绍一下JAX-RS中的数据处理(Data Handlers)部分。?一、Steam

JAX-RS入门 六: 数据处理(1)

接下来要花两小节来介绍一下JAX-RS中的数据处理(Data Handlers)部分。

?

一、SteamingOutput

在第一节中(http://zzc1684.iteye.com/blog/1674367),看getCustomer()方法:

Java代码 ?
    public?StreamingOutput?getCustomer(int?id)?{??? ??????final?Customer?customer?=?customerDB.get(id);??? ?? ????if?(customer?==?null)?{??? ?? ????????throw?new?WebApplicationException(Response.Status.NOT_FOUND);??? ?? ????}??? ??????return?new?StreamingOutput()?{??? ?? ????????public?void?write(OutputStream?outputStream)?throws?IOException,??? ?? ????????????????WebApplicationException?{??? ??????????????outputCustomer(outputStream,?customer);??? ??????????}??? ??????};??? ??}????

其中使用了SteamingOutput来写一个原始流的字符流。

?

这是JAX-RS提供的数据处理的其中一种方式,通过回调SteamingOutput的write()方法来写回response。

相对于直接返回一个OutputSteam对象,使用回调对象有以下好处:

    JAX-RS可以自由的,按照它的设想处理输出 当追求性能时,甚至可以使用另一个线程而不是当前调用线程回写 可以很方便的注入拦截器,而使用一个直接的OutputSteam则通常会跳过这些步骤 最后,可以实现异步响应,类AJAX。在Servlet3.0中已经介绍了异常响应的想法。

二、InputSteam/Reader

?

可以使用InputSteam或Reader去处理请求内容,JAX-RS会自动将请求数据转成一个InputSteam/Reader对象,例如:

Inputsteam代码 ?
    @PUT ??@Path("/stuff") ?? public?void?putStuff(InputStream?is)?{ ??????byte[]?bytes?=?readFromStream(is); ??????String?input?=?new?String(bytes); ??????System.out.println(input); ??}???
Reader代码 ?
    @PUT ??@Path("/morestuff") ?? public?void?putMore(Reader?reader)?{ ??????LineNumberReader?lineReader?=?new?LineNumberReader(reader); ??????do?{ ??????????String?line?=?lineReader.readLine(); ??????????if?(line?!=?null)?System.out.println(line); ??????}?while?(line?!=?null); ??}???

除了处理请求,InputSteam/Reader也可以作为响应:

Response代码 ?
    @GET ??@Path("file/{fileName}") ?? @Produces("text/plain") ?? public?Reader?getFileContent(@PathParam("fileName")?String?fileName);??

注:当作为响应时,需要指定@Produces,这样JAX-RS才知道怎么去设置响应的Content-Type头信息

?

三、File

?

File对象也可以用在处理请求或响应中。例如用于请求:

File作为请求参数代码 ?
    @POST ??@Path("/morestuff") ?? public?void?post(File?file)?{ ??????Reader?reader?=?new?Reader(new?FileInputStream(file)); ??????LineNumberReader?lineReader?=?new?LineNumberReader(reader); ??????do?{ ??????????String?line?=?lineReader.readLine(); ??????????if?(line?!=?null)?System.out.println(line); ??????}?while?(line?!=?null); ??}??

这里File作为请求参数使用。

?

注:当使用File作为请求参数时,JAX-RS会在后台生成一个临时文件,以请求的信息体作为这个文件的内容,然后将这个临时文件作为参数传入。

?

用于响应:

Java代码 ?
    private?static?final?String?basePath?=?"..."; ??@GET?? @Path("{filepath:?.*}") ?? @Produces("text/plain") ?? public?File?getFile(@PathParam("filepath")?String?path)?{ ?? ????return?new?File(basePath?+?path); ?? }??????

注:同样的,当File用作响应时,需要指定@Produces,用于告诉JAX-RS怎么转换File内容,即Content-Type。

?

四、byte[]

?

byte[]也可以用在请求或响应,例如:

Java代码 ?
    @GET??@Produces("text/plain") ?? public?byte[]?get()?{ ?? ????return?"hello?world".getBytes(); ?? } ??@POST?? @Consumes("text/plain") ?? public?void?post(byte[]?bytes)?{ ?? ????System.out.println(new?String(bytes)); ?? }??

注:当用作响应时,需要指定@Produces,用于告诉JAX-RS怎么设置响应的Content-Type值。?

?

五、String/Char[]

?

大多数网络数据是基于文件格式的。JAX-RS可以进行任何文件格式的内容与String/Char[]之间的转换。例如:

String/char[]代码 ?
    @GET ??@Produces("application/xml") ?? public?String?get()?{ ??????return?"<customer><name>Bill?Burke</name></customer>"; ?? } ??@POST ??@Consumes("text/plain") ?? public?void?post(String?str)?{ ??????System.out.println(str); ??}??

注:当用作响应时,需要指定@Produces,用于告诉JAX-RS怎么设置响应的Content-Type值。

?

注:JAX-RS规范要求实现者必须处理在Content-Type中指定的charset值,当注入String时,例如:

?

Java代码 ?
    POST?/data ??Content-Type:?application/xml;charset=UTF-8?? <customer>...</customer>??

这里charset为UTF-8,实现者必须保证生成的Java String必须是UTF-8编码的。

?

六、MultivaluedMap<String, String> 和Form

?

在节4(http://liugang594.iteye.com/blog/1496651)中,已经介绍了使用@FormParam去获取提交的Form值。除了使用@FormParam,也可以直接注入MultivaluedMap<String,String>对象来表示所有请求的Form数据,其中Form数据格式是 "application/x-www-form-urlencoded",例如:

?

Java代码 ?
    @POST??@Consumes("application/x-www-form-urlencoded") ?? @Produces("application/x-www-form-urlencoded") ?? public?MultivaluedMap<String,String>?post( ?? ????MultivaluedMap<String,?String>?form)?{ ??????return?form; ?? }??

注:JAX-RS规范并未指明注入的MultivaluedMap是否已经编码;大多数实现者都会自动解码其中的key/value值。如果你想保持编码的格式,则可以使用@javax.ws.rs.Encoded注释。

?

七、javax.xml.transform.Source

?

Source接口代表了一个XML的输入或输出,它通常是用来进行XSLT转换的,例如:

?

Java代码 ?
    @Consumes("application/xml") ??@Produces("application/xml") ?? public?String?post(Source?source)?{ ?? ????javax.xml.transform.TransformerFactory?tFactory?= ??????????javax.xml.transform.TransformerFactory.newInstance(); ??????javax.xml.transform.Transformer?transformer?= ??????????tFactory.newTransformer( ??????????????new?javax.xml.transform.stream.StreamSource("foo.xsl")); ?? ????StringWriter?writer?=?new?StringWriter(); ?? ????transformer.transform(source, ??????????new?javax.xml.transform.stream.StreamResult(writer)); ?? ????return?writer.toString(); ?? }??

除了JAXB(下节讲)外,javax.xml.transform.Source对象是规范中唯一支持的基于XML结构的对象。(甚至不能注入org.w3c.dom.Document对象)

热点排行