webservice

来源:互联网 发布:马云开创淘宝 编辑:程序博客网 时间:2024/06/05 20:16

WebService (三)使用CXF框架开发webservice

1CXF框架概念介绍

Apache CXF 是一个开源的 Services 框架,CXF 帮助您来构建和开发 Services 这些 Services 可以支持多种协议,比如:SOAPPOST/HTTPRESTful HTTP CXF 大大简化了 Service可以天然地和 Spring 进行无缝集成。

11ServerFactoryBean来发布web服务

服务类代码如下:

// 注解是无效的

@WebService(name="Hello",targetNamespace="http://icast.cn")

public class HelloWorld {

public String sayHi(String name) {

return "hello---->" + name;

}

}

发布类代码如下:

public static void main(String[] args) {

// 发布服务的类类似Endpoint

ServerFactoryBean serverFactoryBean=new ServerFactoryBean();

// 注册服务器地址和端口

serverFactoryBean.setAddress("http://127.0.0.1:9999/hello");

// 注册哪个类提供服务

serverFactoryBean.setServiceBean(new HelloWorld());

// 发布一个cxf服务

serverFactoryBean.create();

// 一分钟有服务终止

Thread.sleep(1 * 60 * 1000);

// 正常退出程序

System.exit(0);

}

ServerFactoryBean注意事项:

这种方式没有添加webService注解,也就是说没有注解也可以发布webService服务,但是这种方式不是很规范,比如我们不可以通过注解的方式来修改WSDL的标签信息, 

12JaxWsServerFactoryBean来发布web服务

1. JaxWsServerFactoryBeanServerFactoryBean的子类,也是功能扩展类。

2. 此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不出错,但也不会对外暴露任何方法。使用此类生成的wsdl文件更加规范

3. 更重要的是可以通过添加拦截器拦截请求.

客户端代码如下:

@WebService

public class HelloWorld {

public String sayHi(String name) {

return "hello---->" + name;

}

}

发布类代码如下:

public static void main(String[] args)throws Exception {

// 发布服务的类类似Endpoint

JaxWsServerFactoryBean jaxWsServer=new JaxWsServerFactoryBean();

// 注册服务器地址和端口

jaxWsServer.setAddress("http://127.0.0.1:9999/hello");

// 注册哪个类提供服务

jaxWsServer.setServiceBean(new HelloWorld());

// 配置输入输出日志拦截器

jaxWsServer.getInInterceptors().add(new LoggingInInterceptor());

jaxWsServer.getOutInterceptors().add(new LoggingOutInterceptor());

// 发布一个cxf服务

jaxWsServer.create();

// 一分钟有服务终止

Thread.sleep(1 * 60 * 1000);

// 正常退出程序

System.exit(0);

}

访问:http://127.0.0.1:9999/hello?wsdl 控制台第一次握手拦截器日志如下:

----------------------------

ID: 1

Address: http://127.0.0.1:9999/hello?wsdl

Http-Method: GET

Content-Type: 

Headers: {Accept=[*/*], accept-encoding=[gzip, deflate], Accept-Language=[zh-CN], connection=[Keep-Alive], Content-Type=[null], Host=[127.0.0.1:9999], User-Agent=[Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)]}

--------------------------------------

通过Java客户端调用服务类

public static void main(String[] args) {

HelloWorldService helloWorldService=new HelloWorldService();

HelloWorld helloWorld=helloWorldService.getHelloWorldPort();

System.out.println(helloWorld.sayHi("test"));

}

拦截器日志如下:

----------------------------

ID: 1

Address: http://127.0.0.1:9999/hello?wsdl

Http-Method: GET

Content-Type: text/xml

Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[127.0.0.1:9999], Pragma=[no-cache], User-Agent=[Apache CXF 2.4.2]}

--------------------------------------

2013-1-6 11:28:17 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Inbound Message

----------------------------

ID: 2

Address: http://127.0.0.1:9999/hello

Encoding: UTF-8

Http-Method: POST

Content-Type: text/xml; charset=UTF-8

Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[191], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:9999], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.4.2]}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://jaxws.cxf.g.itcast.cn/"><arg0>test</arg0></ns2:sayHi></soap:Body></soap:Envelope>

--------------------------------------

2013-1-6 11:28:17 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Outbound Message

---------------------------

ID: 2

Encoding: UTF-8

Content-Type: text/xml

Headers: {}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHiResponse xmlns:ns2="http://jaxws.cxf.g.itcast.cn/"><return>hello---->test</return></ns2:sayHiResponse></soap:Body></soap:Envelope>

--------------------------------------

13CXFSpring集成发布WebService

前面的服务发布包括创建服务类都是硬编码的方式.是否可以使用配置的方式来发布服务类呢答案是肯定的这就要同Spring集成了由于cxf的项目已经集成了Spring(自带了Spring lib)所以CXF的服务都是在Spring的配置文件中完成的并且我们需要把项目发布到tomcat,所以我们可以创建一个web项目

配置开发环境:

l 建立一个web项目

l 准备所有jar,CXF_HOME\lib项目下的所有jar,全部都拷贝新项目的lib目录下.其中里面已经包含了Sring3.0jar包  其中jetty 服务器的包可以不要.因为我们要部署的tomcat服务器中了

l 在web.xml中配置cxf的核心servletCXFServlet

l 此配置文件的作用类 拦截/ws/*的所有请求 类似Struts2的过滤器 

<servlet>

<servlet-name>cxf</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>cxf</servlet-name>

<url-pattern>/ws/*</url-pattern>

</servlet-mapping>

通过Spring配置文件发布服务

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

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

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

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

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

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

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd

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

<!-- 这样配置自身的服务也可以使用 -->

<bean id="userImpl" class="cn.itcast.i.cxf.spring.ws.UserImpl" />

<!-- id:逻辑名  serviceClass=服务接口类  address:调用的路径  http://localhost:8888/项目名/ws/hello?wsdl> -->

<jaxws:server id="userService" serviceClass="cn.itcast.i.cxf.spring.ws.IUser" address="/hello">

<jaxws:serviceBean>

<ref bean="userImpl" />

</jaxws:serviceBean>

<jaxws:inInterceptors>

<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />

</jaxws:inInterceptors>

<jaxws:outInterceptors>

<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

</jaxws:outInterceptors>

</jaxws:server>

</beans>

服务接口如下:

@WebService

public interface IUser {

public void saveUser(User user);

public User getUser(int uid);

}

服务类如下:

public class UserImpl implements IUser {

private List<User> users=new ArrayList<User>();

 

public User getUser(int uid) {

for(User temp:users){

if(temp.getUid()==uid){

return temp;

}

}

return null;

}

public void saveUser(User user) {

// TODO Auto-generated method stub

users.add(user);

}

}

实体类如下:

public class User {

private int uid;

private String uname;

public int getUid() {

return uid;

}

public void setUid(int uid) {

this.uid = uid;

}

public String getUname() {

return uname;

}

public void setUname(String uname) {

this.uname = uname;

}

}

通过JSP+Servlet调用本地服务:

Servletweb.xml中配置如下:

<servlet>

<servlet-name>cxf</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet>

<servlet-name>UserServlet</servlet-name>

<servlet-class>cn.itcast.i.cxf.servlet.UserServlet</servlet-clas>

</servlet>

Servlet核心代码调用如下:

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

User user = new User();

user.setUid(Integer.parseInt(request.getParameter("uid")));

user.setUname(request.getParameter("uname"));

userImpl.saveUser(user);

}

public void init() throws ServletException {

// Put your code here

WebApplicationContext springContext = WebApplicationContextUtils

.getWebApplicationContext(this.getServletContext());

userImpl = (IUser) springContext.getBean("userImpl");

WEB页面调用代码如下:

<form action="/day01/servlet/UserServlet" method="post">

     用户编号:<input type="text" name="uid" /><br/>

     用户名:<input type="text" name="uname" /><br/>

     <input type="submit" value="提交" />

 </form>

通过Java远程调用访问CXFSpring服务如下:

public static void main(String[] args) {

IUserService userService=new IUserService();

User user=new User();

user.setUid(1);

user.setUname("admin");

userService.getIUserPort().saveUser(user);

User temp=userService.getIUserPort().getUser(1);

System.out.println(temp.getUid() + "|" + temp.getUname());

}

通过ajax远程调用访问CXFSpring服务如下:

<body>

        <button onclick="mobile()">cxf+Spring测试</button>

</body>

<script language="javascript">

// 1:创建XMLHTTP对象

var xhr=null;

function mobile(){

// 声明在访问的ws的地址

var url="http://localhost:8888/day01/ws/hello";

// 书写要发送的XML文件,即 SOAP

var soap='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>' +

'<ns2:getUser xmlns:ns2="http://ws.spring.cxf.i.itcast.cn/"><arg0>1</arg0></ns2:getUser></soap:Body></soap:Envelope>';

// 3:打开连接

xhr.open("POST",url,true);

xhr.setRequestHeader("Content-Type","text/xml; charset=utf-8");

xhr.setRequestHeader("Accept","*/*");

xhr.onreadystatechange=callBack;

xhr.send(soap);

}

function callBack(){

if(xhr.readyState==4){

var a=xhr.responseXML;

alert(xhr.responseXML.getElementsByTagName("uid")[0].text);

alert(xhr.responseXML.getElementsByTagName("uname")[0].text);

}

}

function init(){

xhr=new ActiveXObject("MSXML2.XMLHTTP.3.0");

}

init();

</script>

 

原创粉丝点击