CXF开发RESTful风格的Web Service
来源:互联网 发布:平平无奇 古天乐 知乎 编辑:程序博客网 时间:2024/06/05 11:04
http://www.itnose.net/detail/6160699.html
一、配置Spring的配置文件
1、需要引入新的 jar 包。
2、配置 applicationContext-server.xml 文件。使用 jaxrs:server ,记得引入jaxrs 的schema 约束。
1)address:为地址,如 http://localhost:8080/Java_WS_Server/rest/
2)serviceBeans:暴露的ws服务类。也可以使用“#beanId”,引入。
<!-- REST WebService 接口--> <jaxrs:server id="restfulServer" address="/rest"> <jaxrs:inInterceptors> </jaxrs:inInterceptors> <jaxrs:serviceBeans> <bean class="cn.rest.rest.SurpolicyEntrence"></bean> </jaxrs:serviceBeans> <jaxrs:extensionMappings> <entry key="json" value="application/json" /> <entry key="xml" value="application/xml" /> </jaxrs:extensionMappings> <jaxrs:languageMappings> <entry key="en" value="en-gb"/> </jaxrs:languageMappings></jaxrs:server>
1、在 javax.ws.rs.* 中定义,都是一些注解,是 JAX-RS (JSR 311) 规范的一部分。
2、具体的注解如下:
1)@Path:定义资源基 URI。由上下文根和主机名组成,如:
http://localhost:8080/Java_WS_Server/rest/surpolicy
2)@GET/@POST:这意味着以下方法可以响应 HTTP GET 或是 HTTP POST方法。
3)@Produces:响应内容 MIME 类型。如
@Produces(MediaType.TEXT_PLAIN)@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
4)@Context: 使用该注释注入上下文对象,比如 Request、Response、UriInfo、ServletContext 等。
@Context HttpServletRequest servletRequest@Context HttpServletResponse servletResponse @Context private UriInfo uriInfo;
5)@PathParam("contact"):该注释将参数注入方法参数的路径。其他可用的注释有 @FormParam、@QueryParam 等。
3、一般来说,服务类与方法上应该分别标注注解 @Path,用于区分访问路径。
@Path(value = "/surpolicy")public class SurpolicyEntrence {}@Path("/sendXml")public String sendXml(String requestXML) {}
三、简单的 RESTful 服务
1、服务类代码:
/** * 简单服务方法 * @param input * 访问地址:http://localhost:8080/Java_WS_Server/rest/surpolicy/sendString/queryParams_aa * @return */@GET@Path("/sendString/{input}")// @Produces("text/plain")@Produces(MediaType.TEXT_PLAIN)public String sendStringParam(@PathParam("input") String input) {System.out.println("接收的参数: \r\n" + input);String tReturn = "成功返回";return tReturn;}
启动服务后,访问 http://localhost:8080/Java_WS_Server,有Available RESTful services的内容,说明发布成功。
2、分析:
1)前提:服务类的path定义为如下,故所有的方法的访问地址都为
http://localhost:8080/Java_WS_Server/rest/surpolicy/ + "方法自己的地址"。/rest 为在配置文件中配置的address地址
@Path(value = "/surpolicy")public class SurpolicyEntrence {}
2)@Path("/sendString/{input}") :用浏览器的rest 工具访问的时候,必须把参数放在url地址后面。如:
http://localhost:8080/Java_WS_Server/rest/surpolicy/sendString/queryParams_aa
3)访问的结果如下:
后台显示:表示成功。返回的信息可以在 RestClient 中查看。
接收的参数: queryParams_aa
3、客户端代码:本文中的客户端统一使用 org.apache.cxf.jaxrs.client.WebClient 实现。
其他实现方式见:
HTTP访问的两种方式(HttpClient和HttpURLConnection)
利用HttpURLConnection和WebClient发布REST风格的WebService客户端(解决超时问题)
1)WebClient 可以使用spring注入,也可以手工创建:
// 手动创建webClient对象,注意这里的地址是发布的那个/rest地址// String url = "http://localhost:8080/Java_WS_Server/rest/";// client = WebClient.create(url);// 从Spring Ioc容器中拿webClient对象,或者直接用注入ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");client = ctx.getBean("webClient", WebClient.class);
<bean id="webClient" class="org.apache.cxf.jaxrs.client.WebClient" factory-method="create"> <constructor-arg type="java.lang.String" value="http://localhost:8080/Java_WS_Server/rest/" /> </bean>
2)先初始化 webClient对象
public void init() {// 手动创建webClient对象,注意这里的地址是发布的那个/rest地址// String url = "http://localhost:8080/Java_WS_Server/rest/";// client = WebClient.create(url);// 从Spring Ioc容器中拿webClient对象,或者直接用注入ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");client = ctx.getBean("webClient", WebClient.class);}
3)简单服务的访问方法:
/** * 测试服务端的简单方法 */public void sendString(){String tResponseMsg = client.path("surpolicy/ping/{input}","我来ping一下。。").accept(MediaType.TEXT_PLAIN).get(String.class);System.out.println(tResponseMsg);}
4)显示:
服务端:接收的参数: 我来ping一下。。客户端:成功返回
四、以XML为交互内容的 RESTful 服务
(一)需要使用 jaxb 来映射Xml与javaBean。
1、接收的javaBean 代码。
package cn.rest.bean;import java.util.List;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlElementWrapper;import javax.xml.bind.annotation.XmlRootElement;/** * * UserBean.java * * @title User的传输数据类 * @description * @author SAM-SHO * @Date 2014-11-25 */@XmlRootElement(name = "USER")public class UserBean {private String name;private String age;private UserAddress userAddress;//地址private List<UserPhone> phoneList ;//手机@XmlElement(name="NAME")public String getName() {return name;}public void setName(String name) {this.name = name;}@XmlElement(name = "AGE")public String getAge() {return age;}public void setAge(String age) {this.age = age;}@XmlElement(name = "UserAddress")public UserAddress getUserAddress() {return userAddress;}public void setUserAddress(UserAddress userAddress) {this.userAddress = userAddress;}@XmlElementWrapper(name = "PhoneList")@XmlElement(name = "UserPhone")public List<UserPhone> getPhoneList() {return phoneList;}public void setPhoneList(List<UserPhone> phoneList) {this.phoneList = phoneList;}}
package cn.rest.bean;public class UserPhone {private String type;//电话号码类型private String num;//电话号码public String getType() {return type;}public void setType(String type) {this.type = type;}public String getNum() {return num;}public void setNum(String num) {this.num = num;}}
package cn.rest.bean;import javax.xml.bind.annotation.XmlElement;public class UserAddress {private String homeAddress;//家庭地址private String workAddress;//公司地址@XmlElement(name = "HomeAddress")public String getHomeAddress() {return homeAddress;}public void setHomeAddress(String homeAddress) {this.homeAddress = homeAddress;}@XmlElement(name = "WorkAddress")public String getWorkAddress() {return workAddress;}public void setWorkAddress(String workAddress) {this.workAddress = workAddress;}}
2、返回的javaBean 代码。
package cn.rest.bean.response;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;/** * 返回商城退保结果对象 * @author SAM * */@XmlRootElement(name = "RETURN")public class ReturnDTO {protected String code;protected String msg;@XmlElement(name="Code")public String getCode() {return code;}public void setCode(String code) {this.code = code;}@XmlElement(name="MSG")public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}
3、转换工具类。
package cn.rest.util;import java.io.StringReader;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;import org.xml.sax.InputSource;import cn.rest.bean.UserBean;/** * * ObjectAndXmlHandle.java * * @title jaxb处理xml解析 * @description * @author SAM-SHO * @Date 2014-11-25 */public class ObjectAndXmlHandle {public static UserBean parseXml2OUserBean(String xml) {try {JAXBContext context = JAXBContext.newInstance(UserBean.class);InputSource is = new InputSource();StringReader xmlStr = new StringReader(xml);is.setCharacterStream(xmlStr);Unmarshaller unmarshaller = context.createUnmarshaller();UserBean user = (UserBean) unmarshaller.unmarshal(is);return user;} catch (JAXBException e) {e.printStackTrace();return null;}}public static void Object2Xml(Object object) {//FileWriter writer = null; try { JAXBContext context = JAXBContext.newInstance(object.getClass()); Marshaller marshal = context.createMarshaller(); marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshal.setProperty("jaxb.encoding", "utf-8"); marshal.marshal(object, System.out); // writer = new FileWriter("shop.xml"); // marshal.marshal(object, writer); } catch (Exception e) { e.printStackTrace(); } }}
(二)、服务端方法代码
1、把 xml 以 String 的方法传输。
/** * 接受XML ,推荐使用。 * 地址:http://localhost:8080/Java_WS_Server/rest/surpolicy/sendXml * 设置 Content-Type: APPLICATION/XML(可以不设) * body 中设置 xml内容 */@POST@Path("/sendXml")@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })public String sendXml(String requestXML) {System.out.println("接收的参数:\r\n " + requestXML);UserBean tUserBean = ObjectAndXmlHandle.parseXml2OUserBean(requestXML);String tReturn = tUserBean.getName()+ " 你好,你的请求成功返回";return tReturn;}
2、RESTClient 工具访问,xml放在 Body 中,可以不设置 Content-Type
3、客户端访问代码:
/** * 发送XML报文 */private void sendRequestXml() {String tRequestXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><USER><AGE>27</AGE><NAME>SAM-SHO</NAME><PhoneList><UserPhone><num>13612345678</num><type>移动</type></UserPhone><UserPhone><num>13798765432</num><type>联通</type></UserPhone></PhoneList><UserAddress><homeAddress>苏州高新区</homeAddress><workAddress>苏州园区</workAddress></UserAddress></USER>";String tResponseMsg = client.path("surpolicy/sendXml").accept(MediaType.APPLICATION_XML).post(tRequestXml, String.class);System.out.println("返回的信息: \r\n" + tResponseMsg);}
1、服务端方法代码
/** *接收Bean * * @param user * http://localhost:8080/Java_WS_Server/rest/surpolicy/sendBean * 需要设置 Content-Type: application/xml * body 中设置 xml内容 * @return */@POST@Path("/sendBean")@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })public ReturnDTO sendBean(UserBean user) {//转成报文ObjectAndXmlHandle.Object2Xml(user);System.out.println(user.getUserAddress().getHomeAddress());ReturnDTO tReturnDTO = new ReturnDTO();tReturnDTO.setCode("1");tReturnDTO.setMsg(user.getName()+ " ,请求成功,已返回");return tReturnDTO;}
2、RESTClient访问
1)一定要设置 headers信息,设置 Content-Type: application/xml ,不然访问不了。
2)需要设置 Content-Type。
3)正确访问:
5)成功返回:
3、客户端访问:
/** * 发送Bean */private void sendRequestBean() {UserBean tUserBean = new UserBean();tUserBean.setName("SAM-SHO");tUserBean.setAge("27");UserAddress tUserAddress = new UserAddress();tUserAddress.setWorkAddress("苏州园区");tUserAddress.setHomeAddress("苏州高新区");tUserBean.setUserAddress(tUserAddress);List<UserPhone> phoneList = new ArrayList<UserPhone>();UserPhone tUserPhone = new UserPhone();tUserPhone.setType("移动");tUserPhone.setNum("13612345678");phoneList.add(tUserPhone);tUserPhone = new UserPhone();tUserPhone.setType("联通");tUserPhone.setNum("13798765432");phoneList.add(tUserPhone);tUserBean.setPhoneList(phoneList);ClientConfiguration config = WebClient.getConfig(client);config.getHttpConduit().getClient().setReceiveTimeout(90000);//设置超时ReturnDTO tReturnDTO = client.path("surpolicy/sendBean").accept(MediaType.APPLICATION_XML).acceptEncoding("utf-8").post(tUserBean,ReturnDTO.class );System.out.println("返回的数据:" + tReturnDTO.getMsg());}
六、服务端与客户端完整代码如下:
1、服务端
package cn.rest.rest;import javax.ws.rs.GET;import javax.ws.rs.POST;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;import cn.rest.bean.UserBean;import cn.rest.bean.response.ReturnDTO;import cn.rest.util.ObjectAndXmlHandle;/** * * SurpolicyEntrence.java * * @title CXF RESTful风格WebService * @description * @author SAM-SHO * @Date 2014-11-24 */@Path(value = "/surpolicy")public class SurpolicyEntrence {/** * 简单服务方法 * @param input * 访问地址:http://localhost:8080/Java_WS_Server/rest/surpolicy/sendString/queryParams_aa * @return */@GET@Path("/sendString/{input}")// @Produces("text/plain")@Produces(MediaType.TEXT_PLAIN)public String sendStringParam(@PathParam("input") String input) {System.out.println("接收的参数: \r\n" + input);String tReturn = "成功返回";return tReturn;}/** * 接受XML ,推荐使用。 * 地址:http://localhost:8080/Java_WS_Server/rest/surpolicy/sendXml * 设置 Content-Type: APPLICATION/XML(可以不设) * body 中设置 xml内容 */@POST@Path("/sendXml")@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })public String sendXml(String requestXML) {System.out.println("接收的参数:\r\n " + requestXML);UserBean tUserBean = ObjectAndXmlHandle.parseXml2OUserBean(requestXML);String tReturn = tUserBean.getName()+ " 你好,你的请求成功返回";return tReturn;}/** *接收Bean * * @param user * http://localhost:8080/Java_WS_Server/rest/surpolicy/sendBean * 需要设置 Content-Type: application/xml * body 中设置 xml内容 * @return */@POST@Path("/sendBean")@Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })public ReturnDTO sendBean(UserBean user) {//转成报文ObjectAndXmlHandle.Object2Xml(user);System.out.println(user.getUserAddress().getHomeAddress());ReturnDTO tReturnDTO = new ReturnDTO();tReturnDTO.setCode("1");tReturnDTO.setMsg(user.getName()+ " ,请求成功,已返回");return tReturnDTO;}}
2、客户端
package cn.rest.client;import java.util.ArrayList;import java.util.List;import javax.ws.rs.core.MediaType;import org.apache.cxf.jaxrs.client.ClientConfiguration;import org.apache.cxf.jaxrs.client.WebClient;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.rest.bean.UserAddress;import cn.rest.bean.UserBean;import cn.rest.bean.UserPhone;import cn.rest.bean.response.ReturnDTO;public class RestClient {private static WebClient client;/** * @param args */public static void main(String[] args) {RestClient tRestClient = new RestClient();tRestClient.init();//1-简单测试//tRestClient.sendString();// 2-发送XML报文//tRestClient.sendRequestXml();// 2-发送BeantRestClient.sendRequestBean();}public void init() {// 手动创建webClient对象,注意这里的地址是发布的那个/rest地址// String url = "http://localhost:8080/Java_WS_Server/rest/";// client = WebClient.create(url);// 从Spring Ioc容器中拿webClient对象,或者直接用注入ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");client = ctx.getBean("webClient", WebClient.class);}/** * 测试服务端的简单方法 */public void sendString(){String tResponseMsg = client.path("surpolicy/sendString/{input}","我来ping一下。。").accept(MediaType.TEXT_PLAIN).get(String.class);System.out.println(tResponseMsg);}/** * 发送XML报文 */private void sendRequestXml() {String tRequestXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><USER><AGE>27</AGE><NAME>SAM-SHO</NAME><PhoneList><UserPhone><num>13612345678</num><type>移动</type></UserPhone><UserPhone><num>13798765432</num><type>联通</type></UserPhone></PhoneList><UserAddress><homeAddress>苏州高新区</homeAddress><workAddress>苏州园区</workAddress></UserAddress></USER>";String tResponseMsg = client.path("surpolicy/sendXml").accept(MediaType.APPLICATION_XML).post(tRequestXml, String.class);System.out.println("返回的信息: \r\n" + tResponseMsg);}/** * 发送Bean */private void sendRequestBean() {UserBean tUserBean = new UserBean();tUserBean.setName("SAM-SHO");tUserBean.setAge("27");UserAddress tUserAddress = new UserAddress();tUserAddress.setWorkAddress("苏州园区");tUserAddress.setHomeAddress("苏州高新区");tUserBean.setUserAddress(tUserAddress);List<UserPhone> phoneList = new ArrayList<UserPhone>();UserPhone tUserPhone = new UserPhone();tUserPhone.setType("移动");tUserPhone.setNum("13612345678");phoneList.add(tUserPhone);tUserPhone = new UserPhone();tUserPhone.setType("联通");tUserPhone.setNum("13798765432");phoneList.add(tUserPhone);tUserBean.setPhoneList(phoneList);ClientConfiguration config = WebClient.getConfig(client);config.getHttpConduit().getClient().setReceiveTimeout(90000);//设置超时ReturnDTO tReturnDTO = client.path("surpolicy/sendBean").accept(MediaType.APPLICATION_XML).acceptEncoding("utf-8").post(tUserBean,ReturnDTO.class );System.out.println("返回的数据:" + tReturnDTO.getMsg());}}
- CXF开发RESTful风格的Web Service
- CXF开发RESTful风格的Web Service
- Web Service笔记(五):CXF开发RESTful风格的Web Service
- Web Service笔记(五):CXF开发RESTful风格的Web Service(实战)
- Web Service笔记(五):CXF开发RESTful风格的Web Service
- Web Service笔记(五):CXF开发RESTful风格的Web Service
- Java CXF RestFul风格的web service发布与调用
- Apache CXF实战之三 构建RESTful风格 Web Service
- Spring+CXF开发RESTful风格的WebService
- RestFul(一)WebService之CXF的RestFul风格开发
- (五)CXF整合Spring发布RESTful风格的Web服务
- Java Web Service-CXF -基于Restful的Web服务
- 应用CXF开发RESTful风格的WebService入门实例
- 使用CXF开发RestFul风格WebService
- 使用Apache CXF搭建REST风格的Web Service
- 开发RESTful web Service
- 搭建一个RESTFUL风格的Web Service (Maven版本)
- 使用Restful风格的Web Service(Maven版本)
- 插入与归并(25)
- 华为机试题目整理
- 使具有物理按键的手机能够显示Action Bar overflow
- JAVA List<> 合并去重
- python模拟Get请求保存网易歌曲的url
- CXF开发RESTful风格的Web Service
- 4103: [Thu Summer Camp 2015]异或运算
- 黑马程序员--NSArray,NSString,NSSet,NSDictionary,NSNumber,NSValue 及其可变(NSMutable..)
- 单一职责原则-和-开放-封闭原则-和-依赖倒转原则
- 数据源,动态代理
- 各种编码UNICODE、UTF-8、ANSI、ASCII、GB2312、GBK详解
- onCreate()方法中获取View的宽高
- Android中Fragment的知识
- python定时器爬取豆瓣音乐Top榜歌名