webservice开发三:CXF+Spring开发WebService
1.部署webservice服务端
下载CXF框架:
首先 http://cxf.apache.org/download.html 从此目录下载 apache-cxf-2.7.18.zip 包,并导入新建项目
新建一个接口IOrderWebService,并且定义一个方法,书写注解
package com.xiaomacloud.webservice;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface IOrderWebService {
@WebMethod
public String getOrderId(String id);
}
为接口写一个实现类,并加上webservice注解
package com.xiaomacloud.webservice.impl;
import javax.jws.WebService;
import com.xiaomacloud.webservice.IOrderWebService;
@WebService
public class OrderWebServiceImpl implements IOrderWebService {
@Override
public String getOrderId(String id) {
return "orderID为:" + id;
}
}
编写发布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: 请求需要一个正确的用户名和密码!** 表示拦截器成功使用。