您的位置:首页 > 编程语言 > Java开发

Spring整合CXF,发布RSETful 风格WebService

2015-09-25 17:37 537 查看
http://www.cnblogs.com/hoojo/archive/2012/07/23/2605219.html

这篇文章是承接之前CXF整合Spring的这个项目示例的延伸,所以有很大一部分都是一样的。关于发布CXFWebServer和Spring整合CXF这里就不再多加赘述了。如果你对Spring整合CXFWebService不了解,具体你可以参看这两篇文章:

/article/4791840.html

/article/4791924.html

如果你不了解restful风格的WebService,你可以参考:

http://www.oracle.com/technetwork/articles/javase/index-137171.html

SpringMVC对RESTful的支持:

/article/4791883.html

使用Jersey框架,搭建RESTfulWebService(这个也比较简单)

http://www.ibm.com/developerworks/cn/web/wa-aj-tomcat/

官方文档:http://jersey.java.net/nonav/documentation/latest/user-guide.html#d4e8

其中,比较常用的RESTful框架就有Jersey、SpringREST、CXFRESTful,这些都可以很好的整合Spring框架,发布也相当的简单。且简单、易用、易上手,文档也比较丰富。

开发环境:

System:Windows

JavaEEServer:tomcat6

JavaSDK:jdk6+

IDE:eclipse、MyEclipse6.6

开发依赖库:

JDK6、JavaEE5、CXF-2.3.3、Spring3.0.4

Email:hoojo_@126.com

Blog:http://blog.csdn.net/IBM_hoojo

http://hoojo.cnblogs.com/

http://hoojo.blogjava.net

下面我们就接着/article/4791840.html这篇文章,开始我们CXFRESTfulWebService的旅程,enjoy~!^_*

准备工作

首先,你需要添加相关的jar包





其中,jsr331-api-1.1.1.jar是必须的,利用CXF发布REST服务得用到它,在cxf的lib库中可以找到这个jar。

下载地址:http://www.apache.org/dyn/closer.cgi?path=/cxf/2.3.11/apache-cxf-2.3.11.zip

其它的jar包都是非必须的!

JavaEntity

packagecom.hoo.entity;


importjava.util.Map;

importjavax.xml.bind.annotation.XmlRootElement;


/**

*<b>function:</b>MapBean封装Map集合元素

*@authorhoojo

*@createDate2012-7-20下午01:22:31

*@fileMapBean.java

*@packagecom.hoo.entity

*@projectCXFWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

@XmlRootElement

publicclassMapBean{

privateMap<String,User>map;


//@XmlElement(type=User.class)

publicMap<String,User>getMap(){

returnmap;

}

publicvoidsetMap(Map<String,User>map){

this.map=map;

}

}


packagecom.hoo.entity;


importjava.util.HashMap;

importjava.util.List;

importjavax.xml.bind.annotation.XmlRootElement;


/**

*<b>function:</b>UsersEntity

*@authorhoojo

*@createDate2011-3-18上午09:27:31

*@fileUsers.java

*@packagecom.hoo.entity

*@projectCXFWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

@XmlRootElement(name="UserInfos")

publicclassUsers{

privateList<User>users;


privateUser[]userArr;


privateHashMap<String,User>maps;



//getter/setter

}


packagecom.hoo.entity;


importjava.io.Serializable;

importjavax.xml.bind.annotation.XmlRootElement;


/**

*<b>function:</b>UserEntity

*@authorhoojo

*@createDateDec16,201010:20:02PM

*@fileUser.java

*@packagecom.hoo.entity

*@projectAxisWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

@XmlRootElement(name="UserInfo")

publicclassUserimplementsSerializable{

privatestaticfinallongserialVersionUID=677484458789332877L;

privateintid;

privateStringname;

privateStringemail;

privateStringaddress;


//getter/setter


@Override

publicStringtoString(){

returnthis.id+"#"+this.name+"#"+this.email+"#"+this.address;

}

}


一、定义你的WebService的接口RESTSample.java,代码如下

packagecom.hoo.service;


importjava.io.IOException;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjavax.ws.rs.Consumes;

importjavax.ws.rs.DELETE;

importjavax.ws.rs.GET;

importjavax.ws.rs.POST;

importjavax.ws.rs.PUT;

importjavax.ws.rs.Path;

importjavax.ws.rs.PathParam;

importjavax.ws.rs.Produces;

importjavax.ws.rs.core.Context;

importjavax.ws.rs.core.MediaType;


importcom.hoo.entity.MapBean;

importcom.hoo.entity.User;

importcom.hoo.entity.Users;



/*

注释(Annotation):在javax.ws.rs.*中定义,是JAX-RS(JSR311)规范的一部分。

@Path:定义资源基URI。由上下文根和主机名组成,资源标识符类似于http://localhost:8080/RESTful/rest/hello。

@GET:这意味着以下方法可以响应HTTPGET方法。

@Produces:以纯文本方式定义响应内容MIME类型。


@Context:使用该注释注入上下文对象,比如Request、Response、UriInfo、ServletContext等。

@Path("{contact}"):这是@Path注释,与根路径“/contacts”结合形成子资源的URI。

@PathParam("contact"):该注释将参数注入方法参数的路径,在本例中就是联系人id。其他可用的注释有@FormParam、@QueryParam等。

@Produces:响应支持多个MIME类型。在本例和上一个示例中,APPLICATION/XML将是默认的MIME类型。

*/

/**

*<b>function:</b>CXFRESTful风格WebService

*@authorhoojo

*@createDate2012-7-20下午01:23:04

*@fileRESTSampleSource.java

*@packagecom.hoo.service

*@projectCXFWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

@Path(value="/sample")

publicinterfaceRESTSample{


@GET

@Produces(MediaType.TEXT_PLAIN)

publicStringdoGet();


@GET

@Produces(MediaType.TEXT_PLAIN)

@Path("/request/{param}")

publicStringdoRequest(@PathParam("param")Stringparam,

@ContextHttpServletRequestservletRequest,@ContextHttpServletResponseservletResponse);


@GET

@Path("/bean/{id}")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicUsergetBean(@PathParam("id")intid);


@GET

@Path("/list")

@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})

publicUsersgetList();


@GET

@Path("/map")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicMapBeangetMap();


/*

@Consumes:声明该方法使用HTMLFORM。

@FormParam:注入该方法的HTML属性确定的表单输入。

@Response.created(uri).build():构建新的URI用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。

您可以使用http://localhost:8080/Jersey/rest/contacts/<id>访问新联系人

*/

@POST

@Path("/postData")

publicUserpostData(Useruser)throwsIOException;


@PUT

@Path("/putData/{id}")

@Consumes(MediaType.APPLICATION_XML)

publicUserputData(@PathParam("id")intid,Useruser);


@DELETE

@Path("/removeData/{id}")

publicvoiddeleteData(@PathParam("id")intid);

}


二、RESTSample接口的实现,这里我们只是简单的实现下,并不是涉及实际的具体业务

packagecom.hoo.service;


importjava.io.IOException;

importjava.util.ArrayList;

importjava.util.HashMap;

importjava.util.List;

importjava.util.Map;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjavax.ws.rs.DELETE;

importjavax.ws.rs.GET;

importjavax.ws.rs.POST;

importjavax.ws.rs.PUT;

importjavax.ws.rs.Path;

importjavax.ws.rs.PathParam;

importjavax.ws.rs.Produces;

importjavax.ws.rs.core.Context;

importjavax.ws.rs.core.MediaType;

importjavax.ws.rs.core.Request;

importjavax.ws.rs.core.UriInfo;

importcom.hoo.entity.MapBean;

importcom.hoo.entity.User;

importcom.hoo.entity.Users;



/*

注释(Annotation):在javax.ws.rs.*中定义,是JAX-RS(JSR311)规范的一部分。

@Path:定义资源基URI。由上下文根和主机名组成,资源标识符类似于http://localhost:8080/RESTful/rest/hello。

@GET:这意味着以下方法可以响应HTTPGET方法。

@Produces:以纯文本方式定义响应内容MIME类型。


@Context:使用该注释注入上下文对象,比如Request、Response、UriInfo、ServletContext等。

@Path("{contact}"):这是@Path注释,与根路径“/contacts”结合形成子资源的URI。

@PathParam("contact"):该注释将参数注入方法参数的路径,在本例中就是联系人id。其他可用的注释有@FormParam、@QueryParam等。

@Produces:响应支持多个MIME类型。在本例和上一个示例中,APPLICATION/XML将是默认的MIME类型。

*/

/**

*<b>function:</b>CXFRESTful风格WebService

*@authorhoojo

*@createDate2012-7-20下午01:23:04

*@fileRESTSampleSource.java

*@packagecom.hoo.service

*@projectCXFWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

@Path(value="/sample")

publicclassRESTSampleSourceimplementsRESTSample{


@Context

privateUriInfouriInfo;


@Context

privateRequestrequest;



@GET

@Produces(MediaType.TEXT_PLAIN)

publicStringdoGet(){

return"thisisgetrestrequest";

}


@GET

@Produces(MediaType.TEXT_PLAIN)

@Path("/request/{param}")

publicStringdoRequest(@PathParam("param")Stringparam,

@ContextHttpServletRequestservletRequest,@ContextHttpServletResponseservletResponse){

System.out.println(servletRequest);

System.out.println(servletResponse);

System.out.println(servletRequest.getParameter("param"));

System.out.println(servletRequest.getContentType());

System.out.println(servletResponse.getCharacterEncoding());

System.out.println(servletResponse.getContentType());

return"success";

}


@GET

@Path("/bean/{id}")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicUsergetBean(@PathParam("id")intid){

System.out.println("####getBean#####");

System.out.println("id:"+id);

System.out.println("Method:"+request.getMethod());

System.out.println("uri:"+uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());


Useruser=newUser();

user.setId(id);

user.setName("JojO");

returnuser;

}


@GET

@Path("/list")

@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})

publicUsersgetList(){

System.out.println("####getList#####");

System.out.println("Method:"+request.getMethod());

System.out.println("uri:"+uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());


List<User>list=newArrayList<User>();

Useruser=null;

for(inti=0;i<4;i++){

user=newUser();

user.setId(i);

user.setName("JojO-"+i);

list.add(user);

}

Usersusers=newUsers();

users.setUsers(list);

returnusers;

}


@GET

@Path("/map")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicMapBeangetMap(){

System.out.println("####getMap#####");

System.out.println("Method:"+request.getMethod());

System.out.println("uri:"+uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());


Map<String,User>map=newHashMap<String,User>();

Useruser=null;

for(inti=0;i<4;i++){

user=newUser();

user.setId(i);

user.setName("JojO-"+i);

map.put("key-"+i,user);

}

MapBeanbean=newMapBean();

bean.setMap(map);

returnbean;

}


/*

@Consumes:声明该方法使用HTMLFORM。

@FormParam:注入该方法的HTML属性确定的表单输入。

@Response.created(uri).build():构建新的URI用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。

您可以使用http://localhost:8080/Jersey/rest/contacts/<id>访问新联系人

*/

@POST

@Path("/postData")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicUserpostData(Useruser)throwsIOException{

System.out.println(user);

user.setName("jojo##12321321");

returnuser;

}


@PUT

@Path("/putData/{id}")

@Produces({MediaType.APPLICATION_XML})

publicUserputData(@PathParam("id")intid,Useruser){

System.out.println("#####putData#####");

System.out.println(user);

user.setId(id);

user.setAddress("hoojo#gz");

user.setEmail("hoojo_@126.com");

user.setName("hoojo");

System.out.println(user);

returnuser;

}


@DELETE

@Path("/removeData/{id}")

publicvoiddeleteData(@PathParam("id")intid){

System.out.println("#######deleteData#######"+id);

}

}


三、配置我们的WebService,修改applicationContext-server.xml。这里主要是添加jaxrs标签的支持,修改头部文件如下:

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:jaxws="http://cxf.apache.org/jaxws"

xmlns:jaxrs="http://cxf.apache.org/jaxrs"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

'target='_blank'>http://www.springframework.org/schema/beans/spring-beans-3.0.xsd[/code]
'target='_blank'>http://www.springframework.org/schema/context[/code]
'target='_blank'>http://www.springframework.org/schema/context/spring-context-3.0.xsd[/code]
http://cxf.apache.org/jaxws

'target='_blank'>http://cxf.apache.org/schemas/jaxws.xsd[/code]
http://cxf.apache.org/jaxrs

http://cxf.apache.org/schemas/jaxrs.xsd">


特别注意上面加粗带下划线的部分,这是新增加的配置。我们发布restfulWebService需要用到它。
然后在配置文件中添加如下配置

<importresource="classpath:META-INF/cxf/cxf.xml"/>

<importresource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>

<importresource="classpath:META-INF/cxf/cxf-servlet.xml"/>

<beanid="restSample"class="com.hoo.service.RESTSampleSource"/>

<!--这里的地址很重要,客户端需要通过这个地址来访问WebService-->

<jaxrs:serverid="restServiceContainer"address="/rest">

<jaxrs:serviceBeans>

<refbean="restSample"/>

</jaxrs:serviceBeans>

<jaxrs:extensionMappings>

<entrykey="json"value="application/json"/>

<entrykey="xml"value="application/xml"/>

</jaxrs:extensionMappings>

<jaxrs:languageMappings>

<entrykey="en"value="en-gb"/>

</jaxrs:languageMappings>

</jaxrs:server>


这样服务器端就完成了CXFRESTfulWebService的发布,启动你的tomcat。然后在浏览器中服务地址:http://localhost:8000/CXFWebService/(其实这里请求的是CXFServlet,你可以看看上一篇Spring整合CXF文章的web.xml的配置)

你就可以看到我们这里刚刚发布的RESTSamplerest的WebService





你也可以看看里面的xml,也就是WebService的wsdl文件内容。我们找一个GET方式的WebService的方法,在浏览器中调用一下试试

http://localhost:8000/CXFWebService/rest/sample/bean/123

这个url对应到下面这个方法

@GET

@Path("/bean/{id}")

@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

publicUsergetBean(@PathParam("id")intid)


结果如下





一篇xml文档内容。

四、编写客户端代码,调用RESTfulWebService

packagecom.hoo.client;


importjava.io.IOException;

importjavax.ws.rs.core.MediaType;

importorg.apache.cxf.jaxrs.client.WebClient;

importorg.junit.After;

importorg.junit.Before;

importorg.junit.Test;

importorg.springframework.context.ApplicationContext;

importorg.springframework.context.support.ClassPathXmlApplicationContext;

importcom.hoo.entity.MapBean;

importcom.hoo.entity.User;

importcom.hoo.entity.Users;

importcom.hoo.service.RESTSample;


/**

*<b>function:</b>RESTful风格WebService

*@authorhoojo

*@createDate2012-7-20下午03:31:03

*@fileRSETServiceClient.java

*@packagecom.hoo.client

*@projectCXFWebService

*@blog'target='_blank'>http://blog.csdn.net/IBM_hoojo[/code]
*@emailhoojo_@126.com

*@version1.0

*/

publicclassRSETServiceClient{


privatestaticWebClientclient;


@Before

publicvoidinit(){

//手动创建webClient对象,注意这里的地址是发布的那个/rest地址

//Stringurl="http://localhost:8000/CXFWebService/rest/";

//client=WebClient.create(url);


//从SpringIoc容器中拿webClient对象

ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext-client.xml");

client=ctx.getBean("webClient",WebClient.class);

}


@After

publicvoiddestory(){

}


@Test

publicvoidtestGet(){

System.out.println(client.path("sample").accept(MediaType.TEXT_PLAIN).get(String.class));

}


@Test

publicvoidtestRequest(){

System.out.println(client.path("sample/request/234234").accept(MediaType.TEXT_PLAIN).get(String.class));

}


@Test

publicvoidtestBean(){

Useruser=client.path("sample/bean/{id}",25).accept(MediaType.APPLICATION_XML).get(User.class);

System.out.println(user);

}


@Test

publicvoidtestList(){

System.out.println(client.path("sample/list").accept(MediaType.APPLICATION_XML).get(Users.class).getUsers());

}


@Test

publicvoidtestMap(){

System.out.println(client.path("sample/map").accept(MediaType.APPLICATION_XML).get(MapBean.class).getMap());

}


@Test

publicvoidtestDeleteData(){

client.path("sample/removeData/23").delete();

}


@Test

publicvoidtestPostData(){

Useruser=newUser();

user.setId(21432134);

user.setAddress("hoojo#gz");

user.setEmail("hoojo_@126.com");

user.setName("hoojo");

System.out.println(client.path("sample/postData").accept(MediaType.APPLICATION_XML).post(user,User.class));

}


@Test

publicvoidtestPutData(){

Useruser=newUser();

user.setId(21432134);

System.out.println(client.path("sample/putData/1").accept(MediaType.APPLICATION_XML).put(user).getEntity());

}

}


如果你喜欢用Spring的方式,还需要在applicationContext-client.xml中增加如下配置

<?xmlversion="1.0"encoding="UTF-8"?>

<beansxmlns="http://www.springframework.org/schema/beans"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:jaxws="http://cxf.apache.org/jaxws"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

'target='_blank'>http://www.springframework.org/schema/beans/spring-beans-3.0.xsd[/code]
'target='_blank'>http://www.springframework.org/schema/context[/code]
'target='_blank'>http://www.springframework.org/schema/context/spring-context-3.0.xsd[/code]
http://cxf.apache.org/jaxws

'target='_blank'>http://cxf.apache.org/schemas/jaxws.xsd">[/code]

<beanid="webClient"class="org.apache.cxf.jaxrs.client.WebClient"factory-method="create">

<constructor-argtype="java.lang.String"value="http://localhost:8000/CXFWebService/rest/"/>

</bean>


</beans>


这种是利用WebClient对象来调用WebService,还有一种方法也可以调用WebService,代码如下:

//手动创建

//RESTSamplesample=JAXRSClientFactory.create("http://localhost:8000/CXFWebService/rest",RESTSample.class);


//从SpringIoc容器中拿webClient对象

ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext-client.xml");

RESTSamplesample=ctx.getBean("restSampleBean",RESTSample.class);


System.out.println(sample);


System.out.println(sample.doGet());

//System.out.println(sample.doRequest("haha",null,null));

System.out.println(sample.getBean(22));

System.out.println(sample.getList());

System.out.println(sample.getMap().getMap());

Useruser=newUser();

user.setId(21432134);

user.setAddress("hoojo#gz");

user.setEmail("hoojo_@126.com");

user.setName("hoojo");

System.out.println(sample.postData(user));

System.out.println(sample.putData(111,user));

sample.deleteData(2);


这种方式相对比WebClient要简单,直接使用接口中的方法即可。同样如果你要整合到Spring可以在applicationContext-client.xml中增加配置如下:

<beanid="restSampleBean"class="org.apache.cxf.jaxrs.client.JAXRSClientFactory"factory-method="create">

<constructor-argtype="java.lang.String"value="http://localhost:8000/CXFWebService/rest/"/>

<constructor-argtype="java.lang.Class"value="com.hoo.service.RESTSample"/>

</bean>


执行以上方法可以看到控制台打印结果如下:

clientconsole

org.apache.cxf.jaxrs.client.ClientProxyImpl@1cf7491

thisisgetrestrequest

22#JojO#null#null

com.hoo.entity.Users@16eb6bc

{key-0=0#JojO-0#null#null,key-1=1#JojO-1#null#null,key-2=2#JojO-2#null#null,key-3=3#JojO-3#null#null}

21432134#jojo##12321321#hoojo_@126.com#hoojo#gz

111#hoojo#hoojo_@126.com#hoojo#gz


serverconsole

####getBean#####

id:22

Method:GET

uri:sample/bean/22

{id=[22]}

####getList#####

Method:GET

uri:sample/list

{}

####getMap#####

Method:GET

uri:sample/map

{}

21432134#hoojo#hoojo_@126.com#hoojo#gz

#####putData#####

21432134#hoojo#hoojo_@126.com#hoojo#gz

111#hoojo#hoojo_@126.com#hoojo#gz

#######deleteData#######2


就这样,整合restfulWebService成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: