设为首页 收藏本站
查看: 777|回复: 0

[经验分享] 【转】Apache CXF入门范例以及对传递List类型的疑惑

[复制链接]

尚未签到

发表于 2017-1-13 07:34:27 | 显示全部楼层 |阅读模式
  转自:http://icecrystal.iteye.com/blog/532743
  在选择WebService框架的过程中,偶最终选择了Apache CXF,純粹伿諟銦爲听说它与Spring的无缝整合
  想当初用Axis的时候,因为没有太好的办法让Spring能够集成Axis,只好平白无故地多出一个WebService代理类,让偶的感觉很是不爽
  偶要在此记载一下CXF的一些入门知识
  首珗,倌網哋址諟http://cxf.apache.org/,里面可以找到User's Guide和download地址,偶的版本是目前最新的
  apache-cxf-2.2.5
  先来做一个最简单的入门级别例子吧,也就是经典的HelloWord
  Server端代码
  WebService接口HelloService.java

Java代码 DSC0000.gif   DSC0001.png





  • package cfx.server;   
  •   

  • import javax.jws.WebMethod;   

  • import javax.jws.WebParam;   

  • import javax.jws.WebService;   
  •   

  • @WebService  

  • public interface HelloService {   

  •     @WebMethod  

  •     String sayHi(@WebParam String name);   
  • }  



package cfx.server;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloService {
@WebMethod
String sayHi(@WebParam String name);
}

  实现类HelloServiceImpl.java

Java代码   DSC0002.gif





  • public class HelloServiceImpl implements HelloService {   

  •     public String sayHi(String name) {   

  •         System.out.println("HelloServiceImpl.sayHi called");   

  •         return "Hello"+name;   
  • }  



public class HelloServiceImpl implements HelloService {
public String sayHi(String name) {
System.out.println("HelloServiceImpl.sayHi called");
return "Hello"+name;
}
  WebService配置文件:cxf-servlet.xml(可放置于WEB-INF目录下)

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:jaxws="http://cxf.apache.org/jaxws"  

  •       xmlns:soap="http://cxf.apache.org/bindings/soap"  

  •       xsi:schemaLocation="   
  • http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  • http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd   
  • http://cxf.apache.org/jaxws   

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

  •   <jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">  

  •     <jaxws:serviceBean>  

  •         <bean class="cfx.server.HelloServiceImpl" />  

  •     </jaxws:serviceBean>  

  •   </jaxws:server>  

  • </beans>  



<?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:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">
<jaxws:serviceBean>
<bean class="cfx.server.HelloServiceImpl" />
</jaxws:serviceBean>
</jaxws:server>
</beans>

  web.xml代码,用于添加CXFServlet这个处理webservice请求的控制器类

Xml代码  





  • <?xml version="1.0" encoding="UTF-8"?>  

  • <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

  •   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    

  •     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  •      

  •   <servlet>  

  •     <description>Apache CXF Endpoint</description>  

  •     <display-name>cxf</display-name>  

  •     <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>/services/*</url-pattern>  

  •   </servlet-mapping>  

  •   <session-config>  

  •     <session-timeout>60</session-timeout>  

  •   </session-config>  

  • </web-app>  



<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<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>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
  Client端测试代码

Java代码  





  • public class CXF {   

  •     public static void main(String[] args) {   

  •         JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();   

  •         factory.getInInterceptors().add(new LoggingInInterceptor());   

  •         factory.getOutInterceptors().add(new LoggingOutInterceptor());   

  •         factory.setServiceClass(HelloService.class);   

  •         factory.setAddress("http://localhost:8080/cxf/services/hello");   
  •         HelloService client = (HelloService) factory.create();   

  •         String reply = client.sayHi("特蕾莎");   

  •         System.out.println("Server said: " + reply);   
  • }  



public class CXF {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setServiceClass(HelloService.class);
factory.setAddress("http://localhost:8080/cxf/services/hello");
HelloService client = (HelloService) factory.create();
String reply = client.sayHi("特蕾莎");
System.out.println("Server said: " + reply);
}
  *****************************************************************************
  怎么样,是不是很简单啊!现在再来一个和Spring整合的例子
  注意,Server端和Client端都要通过Spring-bean的方式整合
  Server端现在有四个文件,假设是
  HelloService.java
  HelloServiceImpl.java
  HelloDao.java
  HelloDaoImpl.java
  在HelloServiceImpl中存在一个HelloDao的属性,代码省略如下

Java代码  





  • public class HelloServiceImpl implements HelloService {   

  •     private HelloDao dao;   

  •     public String sayHi(String name) {   

  •         System.out.println("HelloServiceImpl.sayHi called");   

  •         return dao.getString(name);   
  •     }   
  • }  



public class HelloServiceImpl implements HelloService {
private HelloDao dao;
public String sayHi(String name) {
System.out.println("HelloServiceImpl.sayHi called");
return dao.getString(name);
}
}
  HelloDaoImpl用于处理持久化,代码省略咯
  需要修改的是配置文件,此时可以这样改
  首先在web.xml里加入Spring监听器

Xml代码  





  • <?xml version="1.0" encoding="UTF-8"?>  

  • <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  

  •   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee    

  •     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  

  •   <listener>  

  •     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  

  •   </listener>  

  •   <context-param>  

  •     <param-name>contextConfigLocation</param-name>  

  •     <param-value>classpath:applicationContext*.xml</param-value>  

  •   </context-param>  

  •   <servlet>  

  •     <description>Apache CXF Endpoint</description>  

  •     <display-name>cxf</display-name>  

  •     <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>/services/*</url-pattern>  

  •   </servlet-mapping>  

  •   <session-config>  

  •     <session-timeout>60</session-timeout>  

  •   </session-config>  

  • </web-app>  



<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<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>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
  橪銗WEB-INF/cxf-servlet這個忟件可以省略咯
  把一个标准的spring-bean文件放在src下(即classes目录下),要让人一看就知道spring大哥进来咯
  applicationContext.xml

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:jaxws="http://cxf.apache.org/jaxws"  

  •   xsi:schemaLocation="   
  • http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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="helloDao" class="cfx.server.HelloDaoImpl" />  

  •   <jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">  

  •     <jaxws:serviceBean>  

  •       <bean id="helloService" class="cfx.server.HelloServiceImpl">  

  •         <property name="dao" ref="helloDao" />  

  •       </bean>  

  •     </jaxws:serviceBean>  

  •   </jaxws:server>  

  • </beans>  



<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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="helloDao" class="cfx.server.HelloDaoImpl" />
<jaxws:server id="jaxwsService" serviceClass="cfx.server.HelloService" address="/hello">
<jaxws:serviceBean>
<bean id="helloService" class="cfx.server.HelloServiceImpl">
<property name="dao" ref="helloDao" />
</bean>
</jaxws:serviceBean>
</jaxws:server>
</beans>
  這樣啟動服務器的时候,spring就自动进行bean的注入以及WebService服务的发布了
  接下来是客户端代码
  銦爲諟普通Java,所以就简单配一下愙戸端的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:jaxws="http://cxf.apache.org/jaxws"  

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

  • http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">  
  •   

  •   <bean id="HelloService" class="cfx.server.HelloService" factory-bean="clientFactory" factory-method="create" />  

  •   <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">  

  •     <property name="serviceClass" value="cfx.server.HelloService" />  

  •     <property name="address" value="http://localhost:8080/cxf/services/hello" />  

  •   </bean>  
  •   

  • </beans>  



<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="HelloService" class="cfx.server.HelloService" factory-bean="clientFactory" factory-method="create" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="cfx.server.HelloService" />
<property name="address" value="http://localhost:8080/cxf/services/hello" />
</bean>
</beans>
  CXFClientTest.java

Java代码  





  • public static void main(String[] args) {   

  •     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "cfx/client/client-beans.xml" });   

  •     HelloService client = (HelloService) context.getBean("HelloService");   
  •     testString(client);   
  • }   

  • static void testString(HelloService client) {   

  •     String reply = client.sayHi("特蕾莎");   

  •     System.out.println("Server said: " + reply);   
  • }  



public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "cfx/client/client-beans.xml" });
HelloService client = (HelloService) context.getBean("HelloService");
testString(client);
}
static void testString(HelloService client) {
String reply = client.sayHi("特蕾莎");
System.out.println("Server said: " + reply);
}
  *************************************************************************
  然后是复杂数据类型的问题,经过测试,发觉基本数据类型和List都是没有问题的,我的测试方法包括

Java代码  





  • @WebMethod  

  • String sayHi(@WebParam String name);   
  •   

  • @WebMethod  

  • List<Integer> getList(@WebParam List<String> strs);   
  •        

  • @WebMethod  
  • List<User> getJavaBean();  



@WebMethod
String sayHi(@WebParam String name);
@WebMethod
List<Integer> getList(@WebParam List<String> strs);
@WebMethod
List<User> getJavaBean();
  但是传递Map时,就出现问题了,所以参照了user's guide,得到如下解决办法
  测试某个方法的参数和返回值都是Map类型

Java代码  





  • @WebMethod  

  • @XmlJavaTypeAdapter(MapAdapter.class)   

  • Map<String, String> getMap(@WebParam @XmlJavaTypeAdapter(MapAdapter.class) Map<String, String> map);  



@WebMethod
@XmlJavaTypeAdapter(MapAdapter.class)
Map<String, String> getMap(@WebParam @XmlJavaTypeAdapter(MapAdapter.class) Map<String, String> map);
  MapAdapter是我自己写的用於數據類型轉換的适配器类,代码如下

Java代码  





  • public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {   
  •   

  •     @Override  

  •     public MapConvertor marshal(Map<String, Object> map) throws Exception {   

  •         MapConvertor convertor = new MapConvertor();   

  •         for(Map.Entry<String, Object> entry:map.entrySet()){   

  •             MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);   
  •             convertor.addEntry(e);   
  •         }   

  •         return convertor;   
  •     }   
  •   

  •     @Override  

  •     public Map<String, Object> unmarshal(MapConvertor map) throws Exception {   

  •         Map<String, Object> result = new HashMap<String,Object>();   

  •         for(MapConvertor.MapEntry e :map.getEntries()){   
  •             result.put(e.getKey(), e.getValue());   
  •         }   

  •         return result;   
  •     }   
  •   
  • }  



public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {
@Override
public MapConvertor marshal(Map<String, Object> map) throws Exception {
MapConvertor convertor = new MapConvertor();
for(Map.Entry<String, Object> entry:map.entrySet()){
MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);
convertor.addEntry(e);
}
return convertor;
}
@Override
public Map<String, Object> unmarshal(MapConvertor map) throws Exception {
Map<String, Object> result = new HashMap<String,Object>();
for(MapConvertor.MapEntry e :map.getEntries()){
result.put(e.getKey(), e.getValue());
}
return result;
}
}
  MapConvertor.java Map格式转换类

Java代码  





@XmlType(name = "MapConvertor")   


@XmlAccessorType(XmlAccessType.FIELD)   


public class MapConvertor {   

       


    private List<MapEntry> entries = new ArrayList<MapEntry>();   

       


    public void addEntry(MapEntry entry){   

        entries.add(entry);   

    }   

       


    public static class MapEntry{   


        public MapEntry() {   


            super();   

        }   


        public MapEntry(Map.Entry<String,Object> entry) {   


            super();   


            this.key = entry.getKey();   


            this.value = entry.getValue();   

        }   


        public MapEntry(String key,Object value) {   


            super();   


            this.key = key;   


            this.value = value;   

        }   


        private String key;   


        private Object value;   


        public String getKey() {   


            return key;   
</

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-327640-1-1.html 上篇帖子: clipse加载maven工程提示pom.xml无法解析org.apache.maven.plugins:maven-resources-plugin: 下篇帖子: Apache CXF 在 WebLogic 9.2 上的问题定位分析及权宜之计
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表