WebService之CXF笔记

来源:互联网 发布:淘宝降权会通知吗 编辑:程序博客网 时间:2024/05/15 07:22

分为Server和Client两个部分

1.Server端

**1.1如果用Jetty实现,在pom中需要引入jetty和cxf的依赖**,然后要暴露的接口和实现类必须加@WebService注解
  <dependencies>    <dependency>        <groupId>org.apache.cxf</groupId>        <artifactId>cxf-core</artifactId>        <version>3.1.11</version>    </dependency>    <dependency>        <groupId>org.apache.cxf</groupId>        <artifactId>cxf-rt-frontend-jaxws</artifactId>        <version>3.1.11</version>    </dependency>    <dependency>        <groupId>org.apache.cxf</groupId>        <artifactId>cxf-rt-transports-http-jetty</artifactId>        <version>3.1.11</version>    </dependency>  </dependencies>

Server端的server标准模式如下:

import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;import com.java.interceptor.MyInterceptor;import com.java.webservice.HelloWorld;public class Server {    public static void main(String[] args) {        System.out.println("web service start");        HelloWorld implementor=new HelloWorldImpl();        String address="http://本机局域网IP/helloWorld(随意取名字)";        // Endpoint.publish(address, implementor); //1. 利用jdk实现暴露webservice接口        JaxWsServerFactoryBean factoryBean=new JaxWsServerFactoryBean();//2.利用CXF接口暴露webservice的接口        factoryBean.setAddress(address); // 设置暴露地址        factoryBean.setServiceClass(HelloWorld.class); // 接口类        factoryBean.setServiceBean(implementor); // 设置实现类        factoryBean.getInInterceptors().add(new LoggingInInterceptor()); // 添加in拦截器 日志拦截器        factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加out拦截器 日志拦截器        factoryBean.getInInterceptors().add(new MyInterceptor());//添加自定义的拦截器        factoryBean.create(); // 创建webservice接口        System.out.println("web service started");    }}

2.Client端

首先开启server,复制src/main/java的物理路径,DOS环境下进入该目录下,运行如下命令:wsdl2java http://本机局域网IP/helloWorld(随意取名字)?wsdl即可利用cxf工具自动在src/main/java目录下生成代码(包路径就是创建Maven项目时会自动创建),Eclipse中刷新src/main/java即可,然后在客户端可调用server端的方法,代码如下:
import java.util.List;import org.apache.cxf.frontend.ClientProxy;import org.apache.cxf.interceptor.LoggingInInterceptor;import org.apache.cxf.interceptor.LoggingOutInterceptor;import com.java.interceptor.AddHeaderInterceptor;public class Client {    public static void main(String[] args) {        HelloWorldService service=new HelloWorldService();        //获取server的端口        HelloWorld helloWorld=service.getHelloWorldPort();        /*        添加拦截器        */        org.apache.cxf.endpoint.Client client=ClientProxy.getClient(helloWorld);        client.getOutInterceptors().add(new AddHeaderInterceptor("java","123456")); // 添加自定义拦截器        client.getInInterceptors().add(new LoggingInInterceptor()); // 添加In拦截器 日志拦截器        client.getOutInterceptors().add(new LoggingOutInterceptor()); // 添加Out拦截器 日志拦截器        System.out.println(helloWorld.say("java"));        /*User user=new User();        user.setUserName("jack");        user.setPassword("123456");        List<Role> roleList=helloWorld.getRoleByUser(user);        for(Role role:roleList){            System.out.println(role.getId()+","+role.getRoleName());        }*/        MyRoleArray arry=helloWorld.getRoles();        List<MyRole> roleList=arry.item;        for(int i=0;i<roleList.size();i++){            MyRole my=roleList.get(i);            System.out.print(my.key+":");            for(Role r:my.value){                System.out.print(r.getId()+","+r.getRoleName());            }            System.out.println("============");        }    }}

注意:CXF不支持Map类型的数据传输,可以自定义适配,如下:
接口中定义了Map类型的数据,自适配为MapAdapter类

    /**     * 获取所有用户以及对应的角色     * @return     */    @XmlJavaTypeAdapter(MapAdapter.class)    public Map<String,List<Role>> getRoles();

这里必须创建一个MapAdapter的类,完成了数组和Map两者的转换,代码如下:

package com.java.adapter;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.bind.annotation.adapters.XmlAdapter;import com.java.entity.MyRole;import com.java.entity.Role;public class MapAdapter extends XmlAdapter<MyRole[], Map<String,List<Role>>>{    /**     * 适配转换 MyRole[] -> Map<String, List<Role>>     * 这里的Role是一个实体类(含有id和name两个属性),从数组到Map     */    @Override    public Map<String, List<Role>> unmarshal(MyRole[] v) throws Exception {        Map<String, List<Role>> map=new HashMap<String,List<Role>>();        for(int i=0;i<v.length;i++){            MyRole r=v[i];            map.put(r.getKey(), r.getValue());        }        return map;    }    /**     * 适配转换 Map<String, List<Role>> -> MyRole[]     * 从Map到数组     */    @Override    public MyRole[] marshal(Map<String, List<Role>> v) throws Exception {        MyRole[] roles=new MyRole[v.size()];        int i=0;        //如何遍历一个Map类型的数据        for(String key:v.keySet()){            roles[i]=new MyRole();            roles[i].setKey(key);            roles[i].setValue(v.get(key));            i++;        }        return roles;    }}

接口实现类中正常使用

    public Map<String, List<Role>> getRoles() {        Map<String,List<Role>> map=new HashMap<String,List<Role>>();        List<Role> roleList1=new ArrayList<Role>();        roleList1.add(new Role(1,"技术总监"));        roleList1.add(new Role(2,"架构师"));        map.put("java1234", roleList1);        List<Role> roleList2=new ArrayList<Role>();        roleList2.add(new Role(3,"程序员"));        map.put("jack", roleList2);        return map;    }
原创粉丝点击