如果我们的WebService对外提供的服务是收费的,我们就不能让用户自由的去访问我们的WebService服务,这个时候我们就要为WebService服务端进行权限控制。
那么我们如何进行权限控制呢?我们可以添加类似于拦截器的东西。
在WebService中,我们的客户端与服务端的调用过程如下:
进行权限控制的方法,就是传输数据的时候(input)需要用户名和密码信息,如果用户名密码信息不正确的话,就不能调用该服务。
解决思路就是:服务器要求input消息总是携带有用户名、密码信息。如果没有用户名密码信息,直接拒绝调用。
如果不用CXF等框架,SOAP消息的生成,解析都需要开发人员负责,无论是添加用户名,密码信息,还是提取用户名,密码信息,都可以由开发人员的代码完成。
如果用CXF框架,SOAP消息的生成、解析都是由CXF等框架来完成的。
为了让开发人员能访问,并修改CXF框架所生成的SOAP消息,CXF提供了拦截器。
当我们使用拦截器的时候,WebService的传输情况则变为:
我们复制一下之前的服务端WS_Service,改名为Inter_Service:
然后我们开始在服务端加拦截器。
步骤:
(1)获取Endpoint的publish方法返回值
(2)调用该方法的返回值的getInterceptor、getOutInterceptor方法来获取In、out拦截器列表,接下来就可以添加拦截器了。
自定义拦截器需要实现Interceptor接口。实际上我们一般会继承AbstractPhaseIntercaptor。这里CXF也给我们提供了很多拦截器给我们用,我们这里使用的就是它提供的LoggingInterceptor。
我们修改主运行类ServerMain:
package show;
import javax.xml.ws.Endpoint;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.java.cxf.ws.HelloWorld;
import org.java.cxf.ws.impl.HelloworldWs;
public class ServerMain {
public static void main(String[] args) {
HelloWorld hw=new HelloworldWs();
//调用Endpoint的publish方法发布WebService
EndpointImpl ep=(EndpointImpl)Endpoint.publish("http://127.0.0.1:8082/sayHi", hw);
//添加In拦截器
ep.getInInterceptors().add(new LoggingInInterceptor());
//添加Out拦截器
ep.getOutInterceptors().add(new LoggingOutInterceptor());
System.out.println("WebService 暴露成功!");
}
}
这里在CXF3.1.4的Libray中要新加入
cxf-rt-frontend-jaxws-3.1.4.jar
cxf-rt-wsdl-3.1.4.jar
cxf-rt-frontend-simple-3.1.4.jar
cxf-rt-bindings-soap-3.1.4.jar
cxf-rt-databinding-jaxb-3.1.4.jar
cxf-rt-transports-http-3.1.4.jar
cxf-rt-transports-http-jetty-3.1.4.jar
woodstox-core-asl-4.4.1.jar
stax2-api-3.1.4.jar
LoggingInterceptor/LoggingOutInterceptor拦截器如果不传入参数的话,默认会把请求和回复报文打印在控制台。
启动服务端
我们运行一下客户端,客户端结果:
我们可以使用Print或者log日志文件的形式获取请求报文和回复报文的信息,然后分析请求数据或者回复数据,来做数据分析进行拦截。
我们运行客户端,发现服务端控制台输出了请求与回复报文信息:
下一次我们来剖析请求和回复报文的信息,来深入理解SOAP协议。