WebService 基础学习-2
CXF支持的数据类型
- 基本数据类型,如int、float等
- 引用类型:String、集合(Map、List等)、自定义类型
一次Web Service请求的流程
- 客户端向服务端发送一个soap消息(http+xml)(根据wsdl)
- 服务端处理完成之后,给客户端返回一个soap消息
CXF拦截器
org.apache.cxf.interceptor
——为了在WebService请求过程中,动态地操作请求和响应数据(消息)
分类(从不同角度)
- 服务端、客户端拦截器
- 入拦截器、出拦截器
- 系统拦截器、自定义拦截器(继承
AbstractPhaseInterceptor
)
public interface Interceptor<T extends Message> { void handleMessage(T message) throws Fault; void handleFault(T message); }
|
Endpoint发布之后有一个返回值, 其类型(Endpoint)可转为org.apache.cxf.jaxws22.EndpointImpl
系统拦截器——访问日志
如添加日志入拦截器:
List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInterceptors(); inInterceptors.add(new LoggingInInterceptor());
|
客户端代码中添加日志出拦截器
XXXImplService implservice = new XXXImplService(); Client client = ClientProxy.getClient(implservice.getXXXImplPort()); List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
|
自定义拦截器——用户名和密码检查
参考:Apache CXF Web Service Development
继承AbstractPhaseInterceptor<SoapMessage>
(抽象过程拦截器,或直接AbstractSoapInterceptor
)
soap消息头类似:
<soap:Header> <OrderCredentials> <username>John</username> <password>password</password> </OrderCredentials> </soap:Header>
|
客户端发送(out),将用户名和密码信息添加到SOAP header中
public class clientHandlerInterceptor extends AbstractSoapInterceptor { private String name; private String password; public myInterceptor(String name, String password){ super(Phase.PRE_PROTOCOL); this.name = name; this.password = password; 44 } @Override public void handleMessage(SoapMessage message) throws Fault { List<Header> headers = message.getHeaders(); Document document = DOMUtils.createDocument(); Element root = document.createElement("OrderCredentials"); Element nameEl = document.createElement("name"); Element pwEl = document.createElement("pw"); nameEl.setTextContent(name); pwEl.setTextContent(password); root.appendChild(nameEl); root.appendChild(pwEl); headers.add(new Header(new QName("OrderCredentials"),root)); } }
|
添加(参考上面日志拦截器)
服务端检查
public class checkInterceptor extends AbstractSoapInterceptor { private String userName; private String password; public checkInterceptor(){ super(Phase.PRE_INVOKE); } @Override public void handleMessage(SoapMessage message) throws Fault { QName qnameCredentials = new QName("OrderCredentials"); if (message.hasHeader(qnameCredentials)) { 444Header header = message.getHeader(qnameCredentials); Element elementOrderCredential= (Element) header.getObject(); 444Node nodeUser = elementOrderCredential.getFirstChild(); Node nodePassword = elementOrderCredential.getLastChild(); if (usernamel != null) { 444userName = nodeUser.getTextContent(); 44} 44if (passwordel != null) { 444password = nodePassword.getTextContent(); 44} if ("John".equalsIgnoreCase(userName) && "password". 444equalsIgnoreCase(password)) { 444System.out.println("Authentication successful for John"); 44} else { 444throw new RuntimeException("Invalid user"); 44} } }
|
写好之后添加为入拦截器
- 在EndpointImpl中添加,或
- 在
@WebService
类上面添加@InInterceptors (interceptors = {"demo.checkInterceptor" })