JAX-RS入门 七: 数据处理(2)
2014-02-24 13:12
411 查看
上节介绍了JAX-RS中怎么与一些基础的对象进行交互,这节介绍JAXB和JSON的使用。
一、JAXB
关于JAXB知识,可以去网上搜搜,或者要入门的话,可以看:http://liugang594.iteye.com/category/201713 。
为了在XML和对象间进行映射,修改一下Customer类,添加JAXB相关的annotations。如下:
Java代码
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlAttribute
protected int id;
@XmlElement
protected String fullname;
public Customer() {}
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
public String getFullName() { return this.fullname; }
public void setFullName(String name} { this.fullname = name; }
}
这里,对应的xml结构大致如下:
Java代码
<customer id="42">
<fullname>Bill Burke</fullname>
</customer>
以上Customer类用JAXB处理,简单的如下:
Java代码
Customer customer = new Customer();
customer.setId(42);
customer.setName("Bill Burke");
JAXBContext ctx = JAXBContext.newInstance(Customer.class);
StringWriter writer = new StringWriter();
ctx.createMarshaller().marshal(customer, writer);
String custString = writer.toString();
customer = ctx.createUnmarshaller().unmarshal(new StringReader(custString));
JAX-RS规范规定:实现者需要自动支持marshalling和unmarshalling由@XmlRootElement或@XmlType约束的类对象,或者是包装在javax.xml.bind.JAXBElement中的对象。例如:
Java代码
@Path("/customers")
public class CustomerResource {
@GET
@Path("{id}")
@Produces("application/xml")
public Customer getCustomer(@PathParam("id") int id) {
Customer cust = findCustomer(id);
return cust;
}
@POST
@Consumes("application/xml")
public void createCustomer(Customer cust) {
...
}
}
这里createCustomer(Customer)方法中的Customer参数即由内置的JAXB的转换来的。
注:内置的JAXB处理器会处理交换类型是 application/xml、text/xml 或 application/*+xml 并且参数/返回值对象含有JAXB注释约束的类;另外,它也负责管理JAXBContext实例的创建和初始化,因为JAXBContext实例的创建是一个耗资源的操作,实现者通过会缓存他们以待下次使用。
二、使用ContextResolvers管理你自己的JAXBContext
你可以通过配置你的JAXBContext实例以得到你想要的输出。JAX-RS内置的JAXB提供器允许你插入你自己的JAXBContext实例,要想这样做,你需要实现一个类似于工厂类的操作javax.ws.rs.ext.ContextResoler,去覆盖缺省的JAXBContext的创建:
Java代码
public interface ContextResolver<T> {
T getContext(Class<?> type);
}
例如:
Java代码
@Provider
@Produces("application/xml")
public class CustomerResolver
implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public CustomerResolver() {
this.ctx = ...; // initialize it the way you want
}
public JAXBContext getContext(Class<?> type) {
if (type.equals(Customer.class)) {
return ctx;
} else {
return null;
}
}
}
自定义的resolver类必须实现ContextResolver接口,并且这个类必须添加@javax.ws.rs.ext.Provider注释去表明它是一个JAX-RS组件。
注:@Produces注释是可选的,它允许你为ContextResolver指定特定的交换数据类型,它允许你以其他格式输入,而非局限于XML。
定义完自己的Resolver类后,就是注册它了。这里需要用到节2 (/article/3840145.html) 中提到的javax.ws.rs.core.Application类,JAXB处理器会顺序查询所有注册的ContextResolver类,并调用它的getContext()方法,如果返回空,则继续找下一个,否则返回对应的JAXBContext对象;如果没有找着,则使用内置的对象。
三、JAXB和JSON
JAXB可以相当灵活以支持其他格式,而不仅限于xml格式。Jettison就是一个开源的JAXB适配器,可以用来输入或输出JSON格式。
JSON是一个基于文本的、可以直接被JavaScript解析的是格式, 它是Ajax应用首选的交换格式。尽管对于JAX-RS并不要求支持JSON,不过多数实现者都会使用Jettison去支持JAXB声明的类对象与JSON之间的转换。
JSON比XMl简单的多。 数据由"{}"包着,包含key/value对,值可以是带引号的字符串,boolean值(true/false),数据或者是这些值的数据类型,例如:
Java代码
{
"id" : 42,
"name" : "Bill Burke",
"married" : true ,
"kids" : [ "Molly", "Abby" ]
}
key/value之间用分号分隔,并以逗号为间隔符。
* 使用BadgerFish进行XML-JSON转换
xml元素名变成key,文本值变成一个内嵌的,key值为"$"的子元素值,例如:
<customer>Bill Burke</customer> 变成 { "customer" : { "$" : "Bill Burke" }}
子元素变成值,例如:
Xml代码
<customer>
<first>Bill</first>
<last>Burke</last>
</customer>
变成:
Js代码
{ "customer" :
{
"first" : { "$" : "Bill"},
"last" : { "$" : "Burke" }
}
}
多个同名元素值变成一个列表:
Xml代码
<customer>
<phone>978-666-5555</phone>
<phone>978-555-2233</phone>
</customer
变成:
Js代码
{ "customer" :
{ "phone" : [ { "$": "978-666-5555"}, { "$":"978-555-2233"} ] }
}
属性变成一个以@开始的值,例如:
Java代码
<customer id="42">
<name>Bill Burke</name>
</customer>
变成:
Xml代码
{ "customer" :
{
"@id" : 42,
"name" : {"$": "Bill Burke"}
}
}
namespace会对应一个@xmlns属性值,缺省的namespace对应"$", 所有子元素和属性都使用namespace的前缀作为他们名字的一部分,例如:
Xml代码
<customer xmlns="urn:cust" xmlns:address="urn:address">
<name>Bill Burke</name>
<address:zip>02115</address:zip>
</customer>
对应:
Java代码
{ "customer" :
{ "@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" } ,
"name" : { "$" : "Bill Burke",
"@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" } },
"address:zip" : { "$" : "02115",
"@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" }}
}
}
* JSON和JSON Schema
BadgerFish对于Javascript程序员来说并不很直观,不建议在XmlSchema和JSon之间进行映射。另一个更好的方式是定义一个JSON的schema来进行java对象和json之间的映射。一个好的框架是Jackson。
四、自定义输出
除了xml和json外,还有很多很多其他的格式,JAX-RS只包含很少的一部分。下面要介绍怎么实现自己的转换器,这里假设没有JAXB,我们自己实现一个。
* MessageBodyWriter
首先实现JAXB-Marshalling支持。要实现java对象和xml之间的自动转换,我们需要创建一个实现javax.ws.rs.ext.MessageBodyWriter的接口:
Java代码
public interface MessageBodyWriter<T> {
boolean isWriteable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType);
long getSize(T t, Class<?> type, Type genericType, Annotation annotations[],
MediaType mediaType);
void writeTo(T t, Class<?> type, Type genericType, Annotation annotations[],
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException;
}
isWriteable()方法决定当前对象是否支持
getSize()方法决定Content-Length的值
writeTo()做最终的写出操作
下面看JAXBMarshaller的实现:
Java代码
@Provider
@Produces("application/xml")
public class JAXBMarshaller implements MessageBodyWriter {
public boolean isWriteable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType) {
return type.isAnnotationPresent(XmlRootElement.class);
}
首先使用@Provider,告诉JAX-RS,这是一个可配置的JAX-RS组件;另外,必须添加@Produces,以告诉JAX-RS,这个MessageBodyWriter支持哪些交换类型。
JAX-RS按照以后算法查找一个合适的MessageBodyWriter来输出一个对象:
首先查看@Produces,以确定是否是支持的交换数据类型
其他查找最优的匹配,例如对于 application/xml,找到三种可用的(application/*,*/*, application/xml),则 application/xml为最优
最后,得到可用列表以后,就会顺序调用MessageBodyWriter.isWriteable()。如果成功,刚输出,否则尝试下一个。
对于getSize()方法,如果不能确定大小,则直接返回-1即可。
增加缩进
默认情况下,所有的空白和特殊字符都被去除。输出内容都在一行上。如果希望以格式化输出,则可以增加@Pretty可以保留缩进,例如:
Java代码
@GET
@Path("{id}")
@Produces("application/xml")
@Pretty
public Customer getCustomer(@PathParam("id") int id) {...}
所以在自定义的Marsheller中需要处理这个annotation:
Java代码
public void writeTo(Object target,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream outputStream) throws IOException
{
try {
JAXBContext ctx = JAXBContext.newInstance(type);
Marshaller m = ctx.createMarshaller();
boolean pretty = false;
for (Annotation ann : annotations) {
if (ann.annotationType().equals(Pretty.class)) {
pretty = true;
break;
}
}
if (pretty) {
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}
m.marshal(target, outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
插入JAXBContext
我们已经了解了怎么插入一个JAXBContext,这里我们需要知道怎么把它加入到自定义的Marshaller.
我们需要找到一种方法,定位到一个ContextResoler类,这个类提供了JAXBContext对象,这个是通过javax.ws.rs.ext.Providers接口实现的:
Java代码
public interface Providers {
<T> ContextResolver<T> getContextResolver(Class<T> contextType,
MediaType mediaType);
<T> MessageBodyReader<T>
getMessageBodyReader(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType);
<T> MessageBodyWriter<T>
getMessageBodyWriter(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType);
<T extends Throwable> ExceptionMapper<T>
getExceptionMapper(Class<T> type);
}
使用Providers.getContextResolver()得到ContextResolver对象。所以我们需要在Marshaller里注入一个Providers对象:
Java代码
@Context
protected Providers providers;
public void writeTo(Object target,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream outputStream) throws IOException
{
try {
JAXBContext ctx = null;
ContextResolver<JAXBContext> resolver =
providers.getContextResolver(JAXBContext.class, mediaType);
if (resolver != null) {
ctx = resolver.getContext(type);
}
if (ctx == null) {
// create one ourselves
ctx = JAXBContext.newInstance(type);
}
ctx.createMarshaller().marshal(target, outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
这样就完成了Marshaller。
* MessageBodyReader
要自定义unmarshall,则需要用到javax.ws.rs.ext.MessageBodyReader接口了:
Java代码
public interface MessageBodyReader<T> {
boolean isReadable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType);
T readFrom(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException;
}
它和上面的Marshaller自定义过程非常类似。不细说:
Java代码
@Provider
@Consumes("application/xml")
public class JAXBUnmarshaller implements MessageBodyReader {
public boolean isReadable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType) {
return type.isAnnotationPresent(XmlRootElement.class);
}
。。。
}
注:这里使用了@Provider和@Consumes annotation。@Provider同上;@Consumes用于指定支持的交换格式。
读如下:
Java代码
Object readFrom(Class<Object>, Type genericType,
Annotation annotations[], MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException {
try {
JAXBContext ctx = JAXBContext.newInstance(type);
return ctx.createUnmarshaller().unmarshal(outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
五、生命周期与环境
默认情况下,每个应用只创建一个MessageBodyReader、MessageBodyWriter和ContextResolver。如果想实例化多个对象,刚需要提供一个public的构造方法,以便JAX-RSS运行时传入所有需要的参数值,可能只需要包含一个以@Context注释的参数即可,例如:
Java代码
@Provider
@Consumes("application/json")
public class MyJsonReader implements MessageBodyReader {
public MyJsonReader(@Context Providers providers) {
this.providers = providers;
}
}
一、JAXB
关于JAXB知识,可以去网上搜搜,或者要入门的话,可以看:http://liugang594.iteye.com/category/201713 。
为了在XML和对象间进行映射,修改一下Customer类,添加JAXB相关的annotations。如下:
Java代码
@XmlRootElement(name="customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlAttribute
protected int id;
@XmlElement
protected String fullname;
public Customer() {}
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
public String getFullName() { return this.fullname; }
public void setFullName(String name} { this.fullname = name; }
}
这里,对应的xml结构大致如下:
Java代码
<customer id="42">
<fullname>Bill Burke</fullname>
</customer>
以上Customer类用JAXB处理,简单的如下:
Java代码
Customer customer = new Customer();
customer.setId(42);
customer.setName("Bill Burke");
JAXBContext ctx = JAXBContext.newInstance(Customer.class);
StringWriter writer = new StringWriter();
ctx.createMarshaller().marshal(customer, writer);
String custString = writer.toString();
customer = ctx.createUnmarshaller().unmarshal(new StringReader(custString));
JAX-RS规范规定:实现者需要自动支持marshalling和unmarshalling由@XmlRootElement或@XmlType约束的类对象,或者是包装在javax.xml.bind.JAXBElement中的对象。例如:
Java代码
@Path("/customers")
public class CustomerResource {
@GET
@Path("{id}")
@Produces("application/xml")
public Customer getCustomer(@PathParam("id") int id) {
Customer cust = findCustomer(id);
return cust;
}
@POST
@Consumes("application/xml")
public void createCustomer(Customer cust) {
...
}
}
这里createCustomer(Customer)方法中的Customer参数即由内置的JAXB的转换来的。
注:内置的JAXB处理器会处理交换类型是 application/xml、text/xml 或 application/*+xml 并且参数/返回值对象含有JAXB注释约束的类;另外,它也负责管理JAXBContext实例的创建和初始化,因为JAXBContext实例的创建是一个耗资源的操作,实现者通过会缓存他们以待下次使用。
二、使用ContextResolvers管理你自己的JAXBContext
你可以通过配置你的JAXBContext实例以得到你想要的输出。JAX-RS内置的JAXB提供器允许你插入你自己的JAXBContext实例,要想这样做,你需要实现一个类似于工厂类的操作javax.ws.rs.ext.ContextResoler,去覆盖缺省的JAXBContext的创建:
Java代码
public interface ContextResolver<T> {
T getContext(Class<?> type);
}
例如:
Java代码
@Provider
@Produces("application/xml")
public class CustomerResolver
implements ContextResolver<JAXBContext> {
private JAXBContext ctx;
public CustomerResolver() {
this.ctx = ...; // initialize it the way you want
}
public JAXBContext getContext(Class<?> type) {
if (type.equals(Customer.class)) {
return ctx;
} else {
return null;
}
}
}
自定义的resolver类必须实现ContextResolver接口,并且这个类必须添加@javax.ws.rs.ext.Provider注释去表明它是一个JAX-RS组件。
注:@Produces注释是可选的,它允许你为ContextResolver指定特定的交换数据类型,它允许你以其他格式输入,而非局限于XML。
定义完自己的Resolver类后,就是注册它了。这里需要用到节2 (/article/3840145.html) 中提到的javax.ws.rs.core.Application类,JAXB处理器会顺序查询所有注册的ContextResolver类,并调用它的getContext()方法,如果返回空,则继续找下一个,否则返回对应的JAXBContext对象;如果没有找着,则使用内置的对象。
三、JAXB和JSON
JAXB可以相当灵活以支持其他格式,而不仅限于xml格式。Jettison就是一个开源的JAXB适配器,可以用来输入或输出JSON格式。
JSON是一个基于文本的、可以直接被JavaScript解析的是格式, 它是Ajax应用首选的交换格式。尽管对于JAX-RS并不要求支持JSON,不过多数实现者都会使用Jettison去支持JAXB声明的类对象与JSON之间的转换。
JSON比XMl简单的多。 数据由"{}"包着,包含key/value对,值可以是带引号的字符串,boolean值(true/false),数据或者是这些值的数据类型,例如:
Java代码
{
"id" : 42,
"name" : "Bill Burke",
"married" : true ,
"kids" : [ "Molly", "Abby" ]
}
key/value之间用分号分隔,并以逗号为间隔符。
* 使用BadgerFish进行XML-JSON转换
xml元素名变成key,文本值变成一个内嵌的,key值为"$"的子元素值,例如:
<customer>Bill Burke</customer> 变成 { "customer" : { "$" : "Bill Burke" }}
子元素变成值,例如:
Xml代码
<customer>
<first>Bill</first>
<last>Burke</last>
</customer>
变成:
Js代码
{ "customer" :
{
"first" : { "$" : "Bill"},
"last" : { "$" : "Burke" }
}
}
多个同名元素值变成一个列表:
Xml代码
<customer>
<phone>978-666-5555</phone>
<phone>978-555-2233</phone>
</customer
变成:
Js代码
{ "customer" :
{ "phone" : [ { "$": "978-666-5555"}, { "$":"978-555-2233"} ] }
}
属性变成一个以@开始的值,例如:
Java代码
<customer id="42">
<name>Bill Burke</name>
</customer>
变成:
Xml代码
{ "customer" :
{
"@id" : 42,
"name" : {"$": "Bill Burke"}
}
}
namespace会对应一个@xmlns属性值,缺省的namespace对应"$", 所有子元素和属性都使用namespace的前缀作为他们名字的一部分,例如:
Xml代码
<customer xmlns="urn:cust" xmlns:address="urn:address">
<name>Bill Burke</name>
<address:zip>02115</address:zip>
</customer>
对应:
Java代码
{ "customer" :
{ "@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" } ,
"name" : { "$" : "Bill Burke",
"@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" } },
"address:zip" : { "$" : "02115",
"@xmlns" : { "$" : "urn:cust",
"address" : "urn:address" }}
}
}
* JSON和JSON Schema
BadgerFish对于Javascript程序员来说并不很直观,不建议在XmlSchema和JSon之间进行映射。另一个更好的方式是定义一个JSON的schema来进行java对象和json之间的映射。一个好的框架是Jackson。
四、自定义输出
除了xml和json外,还有很多很多其他的格式,JAX-RS只包含很少的一部分。下面要介绍怎么实现自己的转换器,这里假设没有JAXB,我们自己实现一个。
* MessageBodyWriter
首先实现JAXB-Marshalling支持。要实现java对象和xml之间的自动转换,我们需要创建一个实现javax.ws.rs.ext.MessageBodyWriter的接口:
Java代码
public interface MessageBodyWriter<T> {
boolean isWriteable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType);
long getSize(T t, Class<?> type, Type genericType, Annotation annotations[],
MediaType mediaType);
void writeTo(T t, Class<?> type, Type genericType, Annotation annotations[],
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException;
}
isWriteable()方法决定当前对象是否支持
getSize()方法决定Content-Length的值
writeTo()做最终的写出操作
下面看JAXBMarshaller的实现:
Java代码
@Provider
@Produces("application/xml")
public class JAXBMarshaller implements MessageBodyWriter {
public boolean isWriteable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType) {
return type.isAnnotationPresent(XmlRootElement.class);
}
首先使用@Provider,告诉JAX-RS,这是一个可配置的JAX-RS组件;另外,必须添加@Produces,以告诉JAX-RS,这个MessageBodyWriter支持哪些交换类型。
JAX-RS按照以后算法查找一个合适的MessageBodyWriter来输出一个对象:
首先查看@Produces,以确定是否是支持的交换数据类型
其他查找最优的匹配,例如对于 application/xml,找到三种可用的(application/*,*/*, application/xml),则 application/xml为最优
最后,得到可用列表以后,就会顺序调用MessageBodyWriter.isWriteable()。如果成功,刚输出,否则尝试下一个。
对于getSize()方法,如果不能确定大小,则直接返回-1即可。
增加缩进
默认情况下,所有的空白和特殊字符都被去除。输出内容都在一行上。如果希望以格式化输出,则可以增加@Pretty可以保留缩进,例如:
Java代码
@GET
@Path("{id}")
@Produces("application/xml")
@Pretty
public Customer getCustomer(@PathParam("id") int id) {...}
所以在自定义的Marsheller中需要处理这个annotation:
Java代码
public void writeTo(Object target,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream outputStream) throws IOException
{
try {
JAXBContext ctx = JAXBContext.newInstance(type);
Marshaller m = ctx.createMarshaller();
boolean pretty = false;
for (Annotation ann : annotations) {
if (ann.annotationType().equals(Pretty.class)) {
pretty = true;
break;
}
}
if (pretty) {
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
}
m.marshal(target, outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
插入JAXBContext
我们已经了解了怎么插入一个JAXBContext,这里我们需要知道怎么把它加入到自定义的Marshaller.
我们需要找到一种方法,定位到一个ContextResoler类,这个类提供了JAXBContext对象,这个是通过javax.ws.rs.ext.Providers接口实现的:
Java代码
public interface Providers {
<T> ContextResolver<T> getContextResolver(Class<T> contextType,
MediaType mediaType);
<T> MessageBodyReader<T>
getMessageBodyReader(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType);
<T> MessageBodyWriter<T>
getMessageBodyWriter(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType);
<T extends Throwable> ExceptionMapper<T>
getExceptionMapper(Class<T> type);
}
使用Providers.getContextResolver()得到ContextResolver对象。所以我们需要在Marshaller里注入一个Providers对象:
Java代码
@Context
protected Providers providers;
public void writeTo(Object target,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream outputStream) throws IOException
{
try {
JAXBContext ctx = null;
ContextResolver<JAXBContext> resolver =
providers.getContextResolver(JAXBContext.class, mediaType);
if (resolver != null) {
ctx = resolver.getContext(type);
}
if (ctx == null) {
// create one ourselves
ctx = JAXBContext.newInstance(type);
}
ctx.createMarshaller().marshal(target, outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
这样就完成了Marshaller。
* MessageBodyReader
要自定义unmarshall,则需要用到javax.ws.rs.ext.MessageBodyReader接口了:
Java代码
public interface MessageBodyReader<T> {
boolean isReadable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType);
T readFrom(Class<T> type, Type genericType,
Annotation annotations[], MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException;
}
它和上面的Marshaller自定义过程非常类似。不细说:
Java代码
@Provider
@Consumes("application/xml")
public class JAXBUnmarshaller implements MessageBodyReader {
public boolean isReadable(Class<?> type, Type genericType,
Annotation annotations[], MediaType mediaType) {
return type.isAnnotationPresent(XmlRootElement.class);
}
。。。
}
注:这里使用了@Provider和@Consumes annotation。@Provider同上;@Consumes用于指定支持的交换格式。
读如下:
Java代码
Object readFrom(Class<Object>, Type genericType,
Annotation annotations[], MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException, WebApplicationException {
try {
JAXBContext ctx = JAXBContext.newInstance(type);
return ctx.createUnmarshaller().unmarshal(outputStream);
} catch (JAXBException ex) {
throw new RuntimeException(ex);
}
}
五、生命周期与环境
默认情况下,每个应用只创建一个MessageBodyReader、MessageBodyWriter和ContextResolver。如果想实例化多个对象,刚需要提供一个public的构造方法,以便JAX-RSS运行时传入所有需要的参数值,可能只需要包含一个以@Context注释的参数即可,例如:
Java代码
@Provider
@Consumes("application/json")
public class MyJsonReader implements MessageBodyReader {
public MyJsonReader(@Context Providers providers) {
this.providers = providers;
}
}
相关文章推荐
- JAX-RS入门 七: 数据处理(2)
- JAX-RS入门 七: 数据处理(2)
- JAX-RS入门 六: 数据处理(1)
- JAX-RS入门 六: 数据处理(1)
- JAX-RS入门 六: 数据处理(1)
- (转)JAX-RS入门 七: 数据处理(2)
- JAX-RS入门 七: 数据处理(2)
- java REST入门:使用 JAX-RS 简化 REST 应用开发(转自代码商人)
- JAX-RS入门 一 :基础
- JAX-RS入门 五: 自动类型转换
- JAX-RS入门 三 :细节
- restful web service学习1-JAX-RS 2.0入门
- JAX-RS入门 八: HTTP响应
- JAX-RS入门 二 :运行
- JAX-RS入门 二 :运行
- 第1章 JAX-RS 2.0 入门
- JAX-RS入门 一 :基础
- JAX-RS入门 十二: 可伸缩的JAX-RS应用
- JAX-RS入门 三 :细节
- JAX-RS入门 一 :基础