webservice开发二:使用CXF开发webservice
1.部署webservice服务端
下载CXF框架: 
 首先 http://cxf.apache.org/download.html 从此目录下载 apache-cxf-2.7.18.zip 包,并导入新建项目
新建一个接口HelloWebService,并且定义一个方法,书写注解
package com.xiaomacloud.sei;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface HelloWebService {
    @WebMethod
    String getName(String name);
} 
为接口写一个实现类,并加上webservice注解
package com.xiaomacloud.sei.impl;
import javax.jws.WebService;
import com.xiaomacloud.sei.HelloWebService;
@WebService
public class HelloWebServiceImpl implements HelloWebService{
    @Override
    public String getName(String name) {
        return "我的名字是" + name;
    }
} 
编写发布webservice类
package com.xiaomacloud.service;
import javax.xml.ws.Endpoint;
import com.xiaomacloud.sei.impl.HelloWebServiceImpl;
public class HelloWBS {
    public static void main(String[] args) {
        //客户端发送web service请求的url
        String address = "http://192.168.1.108:8081/webserviceDemo/helloWBS";
        //处理请求的SEI对象
        HelloWebServiceImpl service = new HelloWebServiceImpl();
        //发布web service
        Endpoint.publish(address , service);
        System.out.println("webservice发布成功...");
    }
} 
打开浏览器,在部署webservice请求url后加上?wsdl:http://192.168.1.108:8081/webserviceDemo/helloWBS?wsdl
2.开发webservice客户端
步骤如下 
 1、新建一个Java项目 
 2、通过 cmd 命令行进入到项目源码真实路径(一般到src目录) 
 3、使用命令行wsdl2java -keep url(webservice访问路径) 
 4、refresh项目 
 新建一个客户端类:
package com.xiaomacloud.client;
import com.xiaomacloud.sei.HelloWebService;
import com.xiaomacloud.sei.impl.HelloWebServiceImplService;
public class HelloWebServiceCilent {
    public static void main(String[] args) {
        HelloWebServiceImplService factory = new HelloWebServiceImplService();
        HelloWebService hellWebServiceImplPort = factory.getHelloWebServiceImplPort(); 
        String name = hellWebServiceImplPort.getName("小明");
        System.out.println(name);
    }
} 
执行后打印 我是小明 表示调用WebService接口成功
3.开发webservice拦截器
3.1为什么设计拦截器? 
 1.为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
3.2拦截器分类: 
 1.按所处的位置分:服务器端拦截器,客户端拦截器 
 2.按消息的方向分:入拦截器,出拦截器 
 3.按定义者分:系统拦截器,自定义拦截器
3.3编码实现拦截器——使用自定义拦截器,实现用户名与密码的检验 
 1.先编写服务端(入)拦截器 
 把验证信息通过header传递到服务端,所以需要先定义好header协议,此次拦截器协议为
<xiaoming>
        <name>xiaojm</name>
        <password>123456</password>
    </xiaoming> 
服务端拦截器代码为:
package com.xiaomacloud.interceptor;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    public CheckUserInterceptor() {
        super(Phase.PRE_PROTOCOL);
    }
    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        Header header = message.getHeader(new QName("xiaoming"));
        if(header!=null) {
            Element xiaomingEle = (Element) header.getObject();
            String name = xiaomingEle.getElementsByTagName("name").item(0).getTextContent();
            String password = xiaomingEle.getElementsByTagName("password").item(0).getTextContent();
            if("xiaojm".equals(name) && "123456".equals(password)) {
                System.out.println("Server 通过拦截器....");
                return;
            }
        }
        //不能通过
        System.out.println("Server 没有通过拦截器....");
        throw new Fault(new RuntimeException("请求需要一个正确的用户名和密码!"));
    }
} 
2.修改webservice发布信息
package com.xiaomacloud.service;
import java.util.List;
import javax.xml.ws.Endpoint;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxws22.EndpointImpl;
import org.apache.cxf.message.Message;
import com.xiaomacloud.interceptor.CheckUserInterceptor;
import com.xiaomacloud.sei.impl.HelloWebServiceImpl;
public class HelloWBS {
    public static void main(String[] args) {
        //客户端发送web service请求的url
        String address = "http://192.168.1.108:8081/webserviceDemo/helloWBS";
        //处理请求的SEI对象
        HelloWebServiceImpl service = new HelloWebServiceImpl();
        //发布web service
        Endpoint endpoint = Endpoint.publish(address , service);
        EndpointImpl endpointImpl  = (EndpointImpl) endpoint;
        System.out.println("webservice发布成功...");
        //服务端的日志入拦截器
        List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors();
        inInterceptors.add(new CheckUserInterceptor());
    }
} 
3.编写客户端(出)拦截器
package com.xiaomacloud.interceptor;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private String name;
    private String password;
    public AddUserInterceptor(String name, String password) {
        super(Phase.PRE_PROTOCOL);//准备协议化时拦截
        this.name = name;
        this.password = password;
    }
    @Override
    public void handleMessage(SoapMessage msg) throws Fault {
        List<Header> headers = msg.getHeaders();
        /* * header <xiaoming> <name>xiaojm</name> <password>123456</password> </xiaoming> */
        Document document = DOMUtils.createDocument();
        Element rootEle = document.createElement("xiaoming");
        Element nameELe = document.createElement("name");
        nameELe.setTextContent(name);
        rootEle.appendChild(nameELe);
        Element passwordELe = document.createElement("password");
        passwordELe.setTextContent(password);
        rootEle.appendChild(passwordELe);
        headers.add(new Header(new QName("xiaoming"), rootEle));
        //System.out.println("client handleMessage()....");
    }
} 
4.修改客户端代码
package com.xiaomacloud.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import com.xiaomacloud.interceptor.AddUserInterceptor;
import com.xiaomacloud.sei.HelloWebService;
import com.xiaomacloud.sei.impl.HelloWebServiceImplService;
public class HelloWebServiceCilent {
    public static void main(String[] args) {
        HelloWebServiceImplService factory = new HelloWebServiceImplService();
        HelloWebService hellWebServiceImplPort = factory.getHelloWebServiceImplPort(); 
        Client client = ClientProxy.getClient(hellWebServiceImplPort);
        //添加客户端的out拦截器
        client.getOutInterceptors().add(new AddUserInterceptor("xiaojm", "123456"));
        String name = hellWebServiceImplPort.getName("小明");
        System.out.println(name);
    }
} 
同样,输出结果为 我是小明
在客户端修改 拦截器的用户名或者密码 client.getOutInterceptors().add(new AddUserInterceptor(“xiaojm”, “1123456”)); 输出结果为: **Exception in thread “main” javax.xml.ws.soap.SOAPFaultException: 请求需要一个正确的用户名和密码! at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:158) at com.sun.proxy.$Proxy29.getName(Unknown Source) at com.xiaomacloud.client.HelloWebServiceCilent.main(HelloWebServiceCilent.java:18) Caused by: org.apache.cxf.binding.soap.SoapFault: 请求需要一个正确的用户名和密码!** 表示拦截器成功使用。
