Webservice整合Spring进行校验

服务端代码:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
  <display-name>Archetype Created Web Application</display-name>
  <!--1. cxfsevlet配置-->
  <servlet>
    <servlet-name>cxfservlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>cxfservlet</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>
  <!--2.spring容器配置-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 欢迎页面配置 -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd">

        <!--
            Spring整合cxf发布服务,关键点:
            1. 服务地址
            2. 服务类
            服务完整访问地址:
                http://localhost:8080/ws/hello
        -->
    <jaxws:server address="/hello">
        <jaxws:serviceBean>
            <bean class="webservice.com.topcheer.impl.HelloServiceImpl"></bean>
        </jaxws:serviceBean>
        <jaxws:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
        </jaxws:outInterceptors>
        <jaxws:inInterceptors>
            <bean class="webservice.com.topcheer.interceptor.AuthInterceptor"></bean>
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
        </jaxws:inInterceptors>
    </jaxws:server>


</beans>

拦截器

/**
 * @author WGR
 * @create 2020/2/14 -- 14:40
 */
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    public AuthInterceptor() {
        super(Phase.PRE_INVOKE);//调用之前拦截soap消息
        System.out.println("服务器端拦截器初始化");
    }
    @Override
    public void handleMessage(SoapMessage msg) throws Fault {
        System.out.println("服务端拦截器="+msg);
        List<Header> headers=msg.getHeaders();
        if(headers==null||headers.size()<=0){
            throw new Fault(new IllegalArgumentException("没有header 不能调用"));
        }

        Header firstHeader=headers.get(0);
        Element ele=(Element)firstHeader.getObject();
        NodeList userIds= ele.getElementsByTagName("userId");
        NodeList passwards= ele.getElementsByTagName("password");

        System.out.println("用户名个数="+userIds.getLength());
        System.out.println("密码个数="+passwards.getLength());
        if(userIds.getLength()!=1 || passwards.getLength()!=1 ){
            throw new Fault(new IllegalArgumentException("格式不对"));
        }
        String userId= userIds.item(0).getTextContent();
        String passward= passwards.item(0).getTextContent();
        System.out.println("用户名="+userId);
        System.out.println("密码="+passward);
        if(!"wl".equals(userId)||!"1985310".equals(passward) ){
            throw new Fault(new IllegalArgumentException("用户名或者密码不对"));
        }
        System.out.println("通过服务端拦截器");

    }

}

客户端代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/jaxws
        http://cxf.apache.org/schemas/jaxws.xsd">

        <!--
            Spring整合cxf客户端配置:
            1. 服务地址     http://localhost:8080/ws/hello
            2. 服务接口类型

        -->
    <jaxws:client
            id="helloService"
            serviceClass="webservice.impl.HelloService"
            address="http://localhost:8080/ws/hello">
        <jaxws:outInterceptors>
            <bean class="webservice.impl.AddHeaderInterceptor">
                <constructor-arg name="userId" value="wl"/>
                <constructor-arg name="password" value="1985310"/>
            </bean>
        </jaxws:outInterceptors>
    </jaxws:client>


</beans>

拦截器代码:

/**
 * @author WGR
 * @create 2020/2/14 -- 14:49
 */
public class AddHeaderInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    private String userId;
    private String password;

    public AddHeaderInterceptor(String userId,String password) {
        super(Phase.PREPARE_SEND);//准备发送soap消息的时候
        this.userId=userId;
        this.password=password;
        System.out.println("客户端端拦截器初始化");
    }

    @Override
    public void handleMessage(SoapMessage msg) throws Fault {
        System.out.println("客户端拦截器"+msg);
        List<Header> headers=msg.getHeaders();
        Document doc= DOMUtils.createDocument();
        Element ele=doc.createElement("authHeader");
        Element idEle=doc.createElement("userId");
        idEle.setTextContent(userId);
        Element passwordEle=doc.createElement("password");
        passwordEle.setTextContent(password);

        ele.appendChild(idEle);
        ele.appendChild(passwordEle);
        headers.add(new Header( new QName("www.xxx") ,ele));

    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Client {

    // 注入对象
    @Resource
    private HelloService helloService;

    @Test
    public void remote(){
        // 查看接口的代理对象类型
        // class com.sun.proxy.$Proxy45
        System.out.println(helloService.getClass());

        // 远程访问服务端方法
        System.out.println(helloService.sayHello("Jerry"));
    }
}

测试端的日志:

二月 14, 2020 5:02:03 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService
信息: Inbound Message
----------------------------
ID: 1
Address: http://localhost:8080/ws/hello
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[299], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 3.0.1]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><authHeader><userId>wl</userId><password>1985310</password></authHeader></soap:Header><soap:Body><ns2:sayHello xmlns:ns2="http://topcheer.com.webservice/"><arg0>Jerry</arg0></ns2:sayHello></soap:Body></soap:Envelope>
--------------------------------------
服务端拦截器={org.apache.cxf.message.MessageFIXED_PARAMETER_ORDER=false, http.base.path=http://localhost:8080, HTTP.REQUEST=org.apache.catalina.connector.RequestFacade@51c6f68a, org.apache.cxf.transport.Destination=org.apache.cxf.transport.servlet.ServletDestination@338495c9, HTTP.CONFIG=org.apache.catalina.core.StandardWrapperFacade@26a01655, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@606e1db, org.apache.cxf.message.Message.QUERY_STRING=null, javax.xml.ws.wsdl.operation={http://topcheer.com.webservice/}sayHello, javax.xml.ws.wsdl.service={http://impl.topcheer.com.webservice/}HelloServiceImplService, org.apache.cxf.message.Message.ENCODING=UTF-8, HTTP.CONTEXT=org.apache.catalina.core.ApplicationContextFacade@60122537, Content-Type=text/xml; charset=UTF-8, org.apache.cxf.security.SecurityContext=org.apache.cxf.transport.http.AbstractHTTPDestination$2@772fce21, org.apache.cxf.message.Message.PROTOCOL_HEADERS={Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[299], content-type=[text/xml; charset=UTF-8], host=[localhost:8080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 3.0.1]}, org.apache.cxf.request.url=http://localhost:8080/ws/hello, Accept=*/*, org.apache.cxf.request.uri=/ws/hello, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://topcheer.com.webservice/}sayHello], org.apache.cxf.message.Message.PATH_INFO=/ws/hello, org.apache.cxf.transport.https.CertConstraints=null, HTTP.RESPONSE=org.apache.catalina.connector.ResponseFacade@519b7c2f, org.apache.cxf.headers.Header.list=[org.apache.cxf.binding.soap.SoapHeader@602247fe], schema-validation-enabled=NONE, org.apache.cxf.request.method=POST, org.apache.cxf.async.post.response.dispatch=true, org.apache.cxf.message.Message.IN_INTERCEPTORS=[org.apache.cxf.transport.https.CertConstraintsInterceptor@1168fd50], HTTP_CONTEXT_MATCH_STRATEGY=stem, http.service.redirection=null, org.apache.cxf.message.Message.BASE_PATH=/ws/hello, org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@18bf779a, javax.xml.ws.wsdl.port={http://impl.topcheer.com.webservice/}HelloServiceImplPort, org.apache.cxf.configuration.security.AuthorizationPolicy=null, javax.xml.ws.wsdl.interface={http://topcheer.com.webservice/}HelloService, javax.xml.ws.wsdl.description=/hello?wsdl, org.apache.cxf.interceptor.LoggingMessage.ID=1}
用户名个数=1
密码个数=1
用户名=wl
密码=1985310
通过服务端拦截器
二月 14, 2020 5:02:03 下午 org.apache.cxf.services.HelloServiceImplService.HelloServiceImplPort.HelloService
信息: Outbound Message
---------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://topcheer.com.webservice/"><return>Jerry,Welcome to Itheima!</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
--------------------------------------

客户端的日志:

客户端端拦截器初始化
二月 14, 2020 5:02:01 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://topcheer.com.webservice/}HelloServiceService from class webservice.impl.HelloService
class com.sun.proxy.$Proxy45
客户端拦截器{org.apache.cxf.message.Message.PROTOCOL_HEADERS={SOAPAction=[""]}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.URLConnectionHTTPConduit1925352804target: http://localhost:8080/ws/hello, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://topcheer.com.webservice/}sayHello], org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@6492fab5, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:8080/ws/hello, org.apache.cxf.headers.Header.list=[], org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@2c5529ab, org.apache.cxf.invocation.context={ResponseContext={}, RequestContext={org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:8080/ws/hello, java.lang.reflect.Method=public abstract java.lang.String webservice.impl.HelloService.sayHello(java.lang.String)}}, org.apache.cxf.client=true, client.holders=[null], org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.mime.headers={}, org.apache.cxf.message.inbound=false, org.apache.cxf.ws.policy.EffectivePolicy=org.apache.cxf.ws.policy.EffectivePolicyImpl@39a8312f, java.lang.reflect.Method=public abstract java.lang.String webservice.impl.HelloService.sayHello(java.lang.String), Content-Type=text/xml}
Jerry,Welcome to WebService!

Process finished with exit code 0

 =========================================================================================

假如是用WebService Client根据wsdl生成的代码,就用一下方式添加拦截器

/**
 * @author WGR
 * @create 2020/2/14 -- 19:44
 */
public class Main {

    public static void main(String[] args) {
        HelloServiceImplService h = new HelloServiceImplService();
        HelloService hello = h.getHelloServiceImplPort();
        Client client = ClientProxy.getClient(hello);

        //客户端的系统日志出拦截器
        List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
        String u = "wl";
        String p = "1985310";
        AddHeaderInterceptor a = new AddHeaderInterceptor(u,p);
        outInterceptors.add(a);
        outInterceptors.add(new LoggingOutInterceptor());
        //客户端的系统日志入拦截器
        List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();
        inInterceptors.add(new LoggingInInterceptor());

        String result = hello.sayHello("webService");
        System.out.println(result);
    }
}
原文地址:https://www.cnblogs.com/dalianpai/p/12308146.html