Cxf WebService实战
在前一篇转载的关于cxf webservice的实现思路中向大家介绍了实现webservice的思路,但并没有给出具体的实现代码,在本文中我将通过介绍借助于spring实现webservice的方式,在本文中同时将向大家介绍在我实现的过程中遇到的一些问题。
1.搭建webservice服务端:
(1.1)新建java web工程,同时在web.xml中进行spring的相关配置,如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>cxfService</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxfService</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/classes/spring/spring.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>(1.2)相关spring文件的具体内容,spring.xml文件的内容,
<?xml version="1.0" encoding="UTF-8"?> <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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <import resource="spring-util-cxf-server.xml" /> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="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 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath*:META-INF/cxf/cxf.xml" /> <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" /> <bean id="personService" class="server.WSServiceImpl" /> <bean id="inMessageInterceptor" class="com.tgb.lk.util.cxf.server.CxfMessageInterceptor"> <constructor-arg value="receive" /> </bean> <bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" /> <!-- 注意下面的address,这里的address的名称就是访问的WebService的name --> <jaxws:server id="personWsServer" serviceClass="server.WSService" address="/changshou"> <jaxws:serviceBean> <!-- 要暴露的 bean 的引用 --> <ref bean="personService" /> </jaxws:serviceBean> <jaxws:inInterceptors> <ref bean="inMessageInterceptor" /> </jaxws:inInterceptors> <jaxws:outInterceptors> <ref bean="outLoggingInterceptor" /> </jaxws:outInterceptors> </jaxws:server> </beans>
(1.3)创建相关类,自定义拦截器MyInterceptor.java
package interceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; public class MyInterceptor extends AbstractPhaseInterceptor<Message> { // 至少要一个带参的构造函数 public MyInterceptor(String phase) { super(phase); } /** * 自定义消息拦截器 */ public void handleMessage(Message message) throws Fault { System.out.println("############handleMessage##########"); System.out.println(message); if (message.getDestination() != null) { System.out.println(message.getId() + "#" + message.getDestination().getMessageObserver()); } if (message.getExchange() != null) { System.out.println(message.getExchange().getInMessage() + "#" + message.getExchange().getInFaultMessage()); System.out.println(message.getExchange().getOutMessage() + "#" + message.getExchange().getOutFaultMessage()); } } }实体对象User:
package com.hoo.entity; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 677484458789332877L; private int id; private String name; private String email; private String address; @Override public String toString() { return this.id + "#" + this.name + "#" + this.email + "#" + this.address; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public static long getSerialversionuid() { return serialVersionUID; } }
实体对象Users
package com.hoo.entity; import java.util.HashMap; import java.util.List; public class Users { private List<User> users; private User[] userArr; private HashMap<String, User> maps; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } public User[] getUserArr() { return userArr; } public void setUserArr(User[] userArr) { this.userArr = userArr; } public HashMap<String, User> getMaps() { return maps; } public void setMaps(HashMap<String, User> maps) { this.maps = maps; } }
创建Webservice接口,WSService.java:
package server; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import com.hoo.entity.User; import com.hoo.entity.Users; @WebService @SOAPBinding(style = Style.RPC) public interface WSService { public void sayHello(String username); /*********传递复杂对象begin***********/ public User getUserByName(@WebParam(name = "name") String name); public void setUser(User user); public Users getUsers(int i); public void setUsers(Users users); /**********传递复杂对象end*************/ }创建Webservice接口的实现类,WSServiceImpl.java
package server; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; import com.hoo.entity.User; import com.hoo.entity.Users; @WebService @SOAPBinding(style = Style.RPC) public class WSServiceImpl implements WSService { @Override public void sayHello(String username) { System.out.println(username); } public User getUserByName(@WebParam(name = "name") String name) { User user = new User(); user.setId(new Date().getSeconds()); user.setName(name); user.setAddress("cangzhou"); user.setEmail(name + "@163.com"); return user; } public void setUser(User user) { System.out.println("############Server setUser###########"); System.out.println("setUser:" + user); } public Users getUsers(int i) { List<User> users = new ArrayList<User>(); for (int j = 0; j <= i; j++) { User user = new User(); user.setId(new Date().getSeconds()); user.setName("jack#" + j); user.setAddress("china"); user.setEmail("jack" + j + "@hoo.com"); users.add(user); } Users u = new Users(); u.setUsers(users); return u; } public void setUsers(Users users) { System.out.println("############Server setUsers###########"); for (User u : users.getUsers()) { System.out.println("setUsers:" + u); } } }将此项目放在tomcat中进行发布,然后通过发布地址测试该webservice是否发布成功,结果如下:
看到此图片证明我们的webservice发布成功,接下来的就让我们搭建客户端对这个webservice进行访问。
2.搭建webservice客户端,如果想在客户端对webservice进行访问我们需要得到webservice发布的接口,这个类我们可以通过jdk自带的命令通过wsdl地址进行导入,具体操作如下:
打开命令窗口,输入如下命令:wsimport -d h: -keep -verbose http://localhost:8080/YCHWebServiceServer/changshou?wsdl,回车即可生成webservice中的相关类(本命令将导出的类放在h盘下的server文件夹中),然后将这些类放入到客户端中,生成的类如下:
新建一个普通的java项目,新建类Client.java,代码如下:
package client; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import client.WSService; public class Client { public static void main(String[] args){ JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(WSService.class); //factory.setAddress("http://localhost:8080/YCHWebServiceServer/changshou/changshou"); factory.setAddress("http://localhost:8080/YCHWebServiceServer/changshou"); WSService service = (WSService) factory.create(); /*******sayHello()*******/ //service.sayHello("xxxx"); /*******getUserByName()方法********/ User user = service.getUserByName("yangchangshou"); // System.out.println(user.getAddress()); // System.out.println(user.getEmail()); // System.out.println(user.getId()); // System.out.println(user.getName()); // System.out.println(user.getClass()); /*******setUser()方法********/ // user.setAddress("China-Guangzhou"); // service.setUser(user); /*******getUsers()方法********/ Users users = service.getUsers(4); for(User u : users.getUsers()){ System.out.println(u.getName()); } } }
然后将通过wsdl生成的类放入到与Client.java类同目录下:
注意无论是在服务端还是在客户端都要导入与CXF相关的jar包,运行Client类中的main()方法,我们可以看到输出结果如下:
通过输出结果我们就完成了对webservice的调用。在做本实例的过程中遇到了一个很让人头疼的问题,其实也算不上是什么大问题,由于我在刚开始的时候将web.xml文件中的cxfservice的url-pattern设置成了/changshou/*,而在spring-util-cxf-server.xml文件中我将访问webservice的name定义成了/changshou,实际的放我那地址应该是:http://http://localhost:8080/YCHWebServiceServer/changshou/changshou,而我在客户端的代码中一直使用http://localhost:8080/YCHWebServiceServer/changshou,这样总是报错,错误信息如下:
导致我找了很长时间才找到解决办法,原来真正的访问地址应该是web.xml文件中配置的cxfservice的url-pattern + spring-util-cxf-server.xml文件中的<jaxws:server>标签中的address属性值,也就是如果在web.xml文件中配置的是/*, spring-util-cxf-server.xml文件中配置的是/changshou,那么webservice的地址应该是:http://localhost:8080/YCHWebServiceServer/changshou,而如果web.xml文件中配置的是/changshou/*,那么webservice的地址则应该是:http://localhost:8080/YCHWebServiceServer/changshou/changshou,希望能对遇到同样问题的兄弟有所帮助。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。