WebService 学习基础-1

WebService 基础学习-2

CXF支持的数据类型

  1. 基本数据类型,如int、float等
  2. 引用类型:String、集合(Map、List等)、自定义类型
    • JDK的WebService不支持Map类型

一次Web Service请求的流程

  1. 客户端向服务端发送一个soap消息(http+xml)(根据wsdl)
  2. 服务端处理完成之后,给客户端返回一个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;
//execute during the WRITE phase and after the SoapPreProtocolOutInterceptor interceptor class
//super(Phase.WRITE);?
44//addAfter(SoapPreProtocolOutInterceptor.class.getName());?
}
@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);//在PRE_INVOKE阶段执行
}
@Override
public void handleMessage(SoapMessage message) throws Fault
{
QName qnameCredentials = new QName("OrderCredentials");
if (message.hasHeader(qnameCredentials)) {
444Header header = message.getHeader(qnameCredentials);//根据qname获得相应的header
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" })
文章目录
  1. 1. WebService 基础学习-2
    1. 1.1. CXF支持的数据类型
    2. 1.2. 一次Web Service请求的流程
    3. 1.3. CXF拦截器
      1. 1.3.1. 分类(从不同角度)
      2. 1.3.2. 系统拦截器——访问日志
      3. 1.3.3. 自定义拦截器——用户名和密码检查
|