使用自定义CXF拦截器确认用户名和密码的合法性。废话不多说,直接上代码。
服务端:
package com.cmbc.service;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface myWS {
@WebMethod
public String sayHello(String name);
}
package com.cmbc.service;
import javax.jws.WebService;
@WebService
public class myWSImpl implements myWS {
@Override
public String sayHello(String name) {
System.out.println("SERVER SAYHELLO!"+name);
return "hello !"+name;
}
}
拦截器:
package com.cmbc.intercepter;
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 CheckUserIntercepter extends AbstractPhaseInterceptor<SoapMessage> {
public CheckUserIntercepter() {
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
System.out.println("----- 进入拦截器 -----");
Header header = message.getHeader(new QName("cmbc"));
if(header!=null){
Element rootElement = (Element)header.getObject();
String name = rootElement.getElementsByTagName("name").item(0).getTextContent();
String password = rootElement.getElementsByTagName("password").item(0).getTextContent();
if(name.equals("张三")&&password.equals("123456")){
System.out.println("server 通过拦截器");
return;
}
}
System.out.println("server 没有通过拦截器");
throw new Fault(new RuntimeException("请求需要一个正确的用户名和密码"));
}
}
终端;
package com.cmbc.test;
import org.apache.cxf.jaxws.EndpointImpl;
import com.cmbc.intercepter.CheckUserIntercepter;
import com.cmbc.service.myWSImpl;
public class RRRR {
public static void main(String[] args) {
String address = "http://localhost:8989/sayHello";
//发布服务端
EndpointImpl epi = (EndpointImpl) EndpointImpl.publish(address, new myWSImpl());
//服务端入拦截器添加一个日志入拦截器
epi.getInInterceptors().add(new CheckUserIntercepter());
//发布服务
System.out.println("WebService 发布成功 , address : " + address);
}
}
客户端;
package com.cmbc.test;
import java.util.List;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import com.cmbc.intercepter.UserIntercepter;
import com.cmbc.service.MyWSImpl;
import com.cmbc.service.MyWSImplService;
public class ClientTest {
public static void main(String[] args) {
MyWSImplService myWSImplService=new MyWSImplService();
MyWSImpl myWSImplPort = myWSImplService.getMyWSImplPort();
//使用cxf的客户端代理
Client client = ClientProxy.getClient(myWSImplPort);
//同理,添加客户端的出拦截器
//获取客户端的出拦截器 注意这里的出拦截器是一个list
List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
//向客户端的出拦截器添加一个出日志拦截器
outInterceptors.add(new UserIntercepter("张三","123456"));
//发送请求
String res = myWSImplPort.sayHello("张琴");
System.out.println(res);
}
}
拦截器:
package com.cmbc.intercepter;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.Document;
import org.w3c.dom.Element;
public class UserIntercepter extends AbstractPhaseInterceptor<SoapMessage> {
public UserIntercepter(String name, String password) {
super(Phase.PRE_PROTOCOL);
this.name = name;
this.password = password;
}
private String name;
private String password;
@Override
public String toString() {
return "UserIntercepter2 [name=" + name + ", password=" + password + "]";
}
public UserIntercepter() {
super(Phase.PRE_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
List<Header> headers = message.getHeaders();
DocumentBuilderFactory documentBuilderFactory= DocumentBuilderFactory.newInstance();
try {
Document document = documentBuilderFactory.newDocumentBuilder().newDocument();
/**
<cmbc>
<name></name>
<password></password>
</cmbc>
*/
Element rootElement = document.createElement("cmbc");
Element nameElement = document.createElement("name");
nameElement.setTextContent(name);
rootElement.appendChild(nameElement);
Element passwordElement = document.createElement("password");
passwordElement.setTextContent(password);
rootElement.appendChild(passwordElement);
headers.add(new Header(new QName("cmbc"), rootElement));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
发送正确的请求的日志;
服务端:
十一月 25, 2018 10:02:24 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://service.cmbc.com/}myWSImplService from WSDL: http://localhost:8989/sayHello?wsdl
hello !张琴
客户端:
十一月 25, 2018 10:02:17 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://service.cmbc.com/}myWSImplService from class com.cmbc.service.myWS
十一月 25, 2018 10:02:18 下午 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be http://localhost:8989/sayHello
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.util.log.Log initialized
信息: Logging initialized @1805ms to org.eclipse.jetty.util.log.Slf4jLog
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.server.Server doStart
信息: jetty-9.4.12.v20180830; built: 2018-08-30T13:59:14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 1.8.0_131-b11
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.server.AbstractConnector doStart
信息: Started ServerConnector@17d88132{HTTP/1.1,[http/1.1]}{localhost:8989}
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.server.Server doStart
信息: Started @2066ms
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.server.handler.ContextHandler setContextPath
警告: Empty contextPath
十一月 25, 2018 10:02:18 下午 org.eclipse.jetty.server.handler.ContextHandler doStart
信息: Started o.e.j.s.h.ContextHandler@3403e2ac{/,null,AVAILABLE}
十一月 25, 2018 10:02:18 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01}Discovery from WSDL: classpath:/org/apache/cxf/ws/discovery/wsdl/wsdd-discovery-1.1-wsdl-os.wsdl
十一月 25, 2018 10:02:18 下午 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be soap.udp://239.255.255.250:3702
十一月 25, 2018 10:02:19 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01}DiscoveryProxy from class org.apache.cxf.jaxws.support.DummyImpl
WebService 发布成功 , address : http://localhost:8989/sayHello
----- 进入拦截器 -----
server 通过拦截器
SERVER SAYHELLO!张琴
发送错误请求:(比如把密码换成1234567)
客户端日志:
十一月 25, 2018 10:09:17 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://service.cmbc.com/}myWSImplService from WSDL: http://localhost:8989/sayHello?wsdl
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 请求需要一个正确的用户名和密码
at org.apache.cxf.jaxws.JaxWsClientProxy.mapException(JaxWsClientProxy.java:195)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145)
at com.sun.proxy.$Proxy36.sayHello(Unknown Source)
at com.cmbc.test.ClientTest.main(ClientTest.java:31)
Caused by: org.apache.cxf.binding.soap.SoapFault: 请求需要一个正确的用户名和密码
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:87)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:53)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:42)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:70)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:35)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:826)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1695)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1572)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1373)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:673)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:313)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
... 2 more
服务端日志:
----- 进入拦截器 -----
server 没有通过拦截器
十一月 25, 2018 10:09:18 下午 org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
警告: Interceptor for {http://service.cmbc.com/}myWSImplService has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: 请求需要一个正确的用户名和密码
at com.cmbc.intercepter.CheckUserIntercepter.handleMessage(CheckUserIntercepter.java:35)
at com.cmbc.intercepter.CheckUserIntercepter.handleMessage(CheckUserIntercepter.java:1)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:247)
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:79)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:205)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:503)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: 请求需要一个正确的用户名和密码
... 29 more