使用CXF开发RestFul WebService问题解决方案
?最近在项目中,因为几个系统自己需要数据交换,所以采用进来都比较流行的RestFul风格WebService,实现框架采用apache的cxf,apache的东西一直以来都是比较的好用,回话少说,进入正题。 ??????首先,提出两个问题,已经解决方案,后面跟上代码。 ????? 1、cxf中如何实现java中泛型的数据序列化和反序列化(通常使用json、xml格式,cxf默认不支持泛型) ????? 2、cxf后台异常,在前台如何反映 ????? 问题1答案比较简单,cxf中的数据序列化是可以替换掉使用你实现MessageBodyReader<Object>和MessageBodyWriter<Object>接口就可以啦,针对xml,cxf采用stax2、jaxb、xmlschema、Woodstox库,针对json默认使用jettison实现的几乎都是codehaus作品。知道cxf序列化和反序列化方式就比较容易解决问题啦。默认情况下cxf的jettison对泛型序列化存在问题,因为时间紧(一天就要做好restful webservice部署),没有具体去研究实现问题,我只是在之前使用过jackson,去处理json问题,而且cxf拥有jackson的MessageBodyReader和MessageBodyWriter实现类,我只要导入包并告诉cxf使用我指定的json provider就可以了,所以在客户端和服务器端双方都指定json privoder,jackson 库对json序列化实现非常的到位,异常的强大。我们都知道,只要java源码中指定的泛型类我没都可以反射出来,如果使用泛型站位符,就没法反射,因为java中的擦除法的原因(比如List<String>、List<T>,前面是清楚的指定泛型参数类型,后面一种是在运行时指定),我这里讨论的也是指定泛型参数类型情况下,jackson在这种情况下已经支持,所以不需要自己实现MessageBodyReader和MessageBodyWriter接口。如果是使用xml方式,除自己实现接口外,有更简单的方法,那就是在你的泛型类上面指定@XmlSeeAlso({某某类1.class,某某类2.class...}) ????? 问题2同样的比较简单,因为基于http的restful实现时,服务器返回数据的时候都会告诉客户端一个响应状态吗,就是我们常看到的200、404、500等,cxf框架的rs webservice客户端实现是通过判断状态大于等于300时,抛出异常webapplicationexception,所以如果服务器端有异常时,通过设置状态就可以实现,并返回Response(通过实现ExceptionMapper<E extends Throwable>接口,并加入到provider实现),如果客户端需要错误消息(这里不得不说jcp设计的jsr311比较的细腻),可以在Response中设置,客户端catch掉webapplicationexception异常,并可以读取错误消息。cxf到这里还没有完,cxf提供一个ResponseExceptionMapper接口,客户端实现这个接口并加入到provider中,客户端在调用的时候就不用去处理cxf的异常webapplicationexception,而是你自己接口的异常,因为客户端在调用webservice时,cxf创建调用接口的代理,代理在接收到300错误时,他知道服务器是返回webapplicationexception异常,他就是用你的ResponseExceptionMapper处理异常,因为这个接口中唯一方法fromResponse(Response r)返回的是一个异常。也就是说,实现这个类方法时,可以读取webapplicationexception中的Response所包含的消息,并要求返回一次异常对象。这样就达到客户端不用关心webapplicationexception异常而是关系自己接口上面声明的异常。 代码:
|
? ?
<p>
ServiceException
extends
RuntimeException {
</p>
?
<p>
?
serialVersionUID = 7607640803750403555L;
ServiceException() {
super
();
}
</p>
?
<p>
ServiceException(String message) {
(message);
}
</p>
?
<p>
ServiceException(String message,Throwable cause) {
(message,cause);
}
</p>
?
<p>
ServiceException(Throwable cause) {
(cause);
}
}
</p>
|
<span></span>
@Path
(value =
"/customer"
)??
@Produces
({
"application/xml"
"application/json"
})?
interface
CustomerService {?
????
?
@GET
?
"/{id}/info"
)?
Customer findCustomerById(
@PathParam
(
"id"
)String id);?
??????
?
@GET
?
"/search"
)?
Customer findCustomerByName(
@QueryParam
"name"
)String name);?
????
?
@POST
?
"/all"
)?
List<Customer> findAllCustomer();
????
?
@POST
?
"/page"
)?
Page<Customer> findPageCustomer()
throws
ServiceException;
????
?
@POST
?
"/pageMe"
)
Page<Me> findPage();
}
CustomerServiceImpl?
CustomerService {?
??
?
Customer findCustomerById(String id) {?
????????
Customer customer =
Customer();?
customer.setId(id);?
customer.setName(id);?
customer.setBirthday(Calendar.getInstance().getTime());?
customer;?
}?
??????
?
Customer findCustomerByName(String name) {?
Customer();?
customer.setId(name);?
customer.setName(name);?
customer.setBirthday(Calendar.getInstance().getTime());?
customer;?
}
/** (non-Javadoc)
* @see edu.xdev.restful.CustomerService#findAllCustomer()
*/
@Override
public
?
List<Customer> findAllCustomer() {
List<Customer> tar =
LinkedList<Customer>();
Customer();?
customer.setId(
"e24234"
);?
customer.setName(
"張三"
);?
customer.setBirthday(Calendar.getInstance().getTime());
tar.add(customer);
customer =
Customer();?
"324324"
);?
"李四"
);?
customer.setBirthday(Calendar.getInstance().getTime());
tar.add(customer);
tar;
}
/** (non-Javadoc)
* @see edu.xdev.restful.CustomerService#findPageCustomer()
*/
Page<Customer> findPageCustomer()
ServiceException {
????????
?
LinkedList<Customer>();
Customer();?
);?
);?
customer.setBirthday(Calendar.getInstance().getTime());
tar.add(customer);
Customer();?
);?
);?
customer.setBirthday(Calendar.getInstance().getTime());
tar.add(customer);
Page<Customer> page =
Page<Customer>(
2
==
){
throw
new
ServiceException(
"abcd"
);
}
page;
}
/** (non-Javadoc)
* @see edu.xdev.restful.CustomerService#findPage()
*/
Page<Me> findPage() {
List<Me> tar =
LinkedList<Me>();
Me m =
Me();
m.setName(
"中文"
);
tar.add(m);
m =
Me();
"English"
);
tar.add(m);
????????
?
Page<Me> page =
Page<Me>(
page;
}?
115
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!