前言

不用DispatcherServlet而是用CXFServlet,用一下xml传值

配置

配置web.xml

 <!--配置CXFServlet-->
    <servlet>
        <servlet-name>cxf</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <init-param>
            <param-name>config-location</param-name>
            <param-value>classpath:spring-cxf.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxf</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

配置MVC容器中的WebService以及javaBean代码对照

    <!--
        1.  引入cxf框架提供jaxws的Schema
        2.  JaxWsServerFactoryBean
            服务地址 setAddress
            服务接口 setServiceClass
            服务实现:setServiceBean
            创建服务并启动:factory.create().start()
=>
        JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
        服务地址
        factory.setAddress("http://localhost:8080/ws/user?wsdl");
        服务接口
        factory.setServiceClass(UserService.class);
        服务实现
        factory.setServiceBean(new UserServiceImpl());
        创建服务 并启动服务
        Server server = factory.create();
        server.start();
        -->
    <cxf:server address="/user" serviceClass="com.etoak.service.UserService">
        <cxf:serviceBean>
            <ref bean="userServiceImpl" />
        </cxf:serviceBean>
    </cxf:server>

约定

WebService实现类

/**
 * @Author shang
 * @UserServiceImpl--WebService
 */
@Service
@WebService(serviceName = "UserServiceSoap",portName = "UserServicePort")
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper dao;
    /**
     * @Param id
     * return User
     */
    @Override
    public User getUser(@WebParam(name = "userId") int id) {
      log.info("param id -{}",id);
      return dao.getById(id);
    }
}

启动

在这里插入图片描述


配置拦截器

说明

拦截器的种类,以及数据走的流程
在上面的基础上,我们需要在请求头里写点东西
首先说一下WebService的拦截器有两种,InInterceptor和OutInterceptor,画张图说明一下
在这里插入图片描述

配置服务端拦截器

    <cxf:server address="/user" serviceClass="com.etoak.service.UserService">
        <cxf:serviceBean>
            <ref bean="userServiceImpl" />
        </cxf:serviceBean>
        <!--In拦截器-->
        <cxf:inInterceptors>
         <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
         <bean class="com.etoak.interceptor.AuthInInterceptor"/>
        </cxf:inInterceptors>
        <!--Out拦截器-->
        <cxf:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
        </cxf:outInterceptors>
    </cxf:server>

在这里插入图片描述


现在开始服务端
自定义拦截器,名称与bean中的class对应

在这里插入图片描述

代码如下:

public class AuthInInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    @Autowired
    UserMapper userMapper;
    public AuthInInterceptor(){
    	//给父类传拦截阶段
        super(Phase.PRE_INVOKE);
    }
    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        Header header =soapMessage.getHeader(new QName("shang"));
        //验证请求头里有没有<shang>这么标签
        if(ObjectUtils.isEmpty(header)){
           throw new Fault(new RuntimeException("没有认证信息"));
        }
        //有的话拿username和password
        Element et2009 = (Element) header.getObject();
        NodeList usernameNode = et2009.getElementsByTagName("username");
        if(usernameNode==null || usernameNode.getLength()!=1){
            throw new Fault(new RuntimeException("username元素错误"));
        }
        NodeList passwordNode = et2009.getElementsByTagName("password");
        if(passwordNode==null || passwordNode.getLength()!=1){
            throw new Fault(new RuntimeException("password元素错误"));
        }
		//从请求头中拿到username和password,储存到变量里
        String username = usernameNode.item(0).getTextContent();
        String password = passwordNode.item(0).getTextContent();
        //dao层执行查询
        User user=userMapper.getByNameAndPassword(username,password);
        //判断用户名密码是否正确
        if(ObjectUtils.isEmpty(user)){
            throw new Fault(new RuntimeException("用户名或密码错误"));
        }else {
            System.out.println("验证通过");
        }
    }
}

服务端就没问题了,再次启动把服务推上去 我们开始写客户端


客户端

客户端目录
在这里插入图片描述
客户端的config也就是上文中cxf.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:cxf="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">
    <!--
        JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
        设置地址
        factoryBean.setAddress("http://localhost:8080/ws/user");
        设置服务portType
        factoryBean.setServiceClass(UserService.class);
        创建服务端接口的实现类的代理对象
        HelloService service =(UserService)factoryBean.create();
        调用远程服务获取服务端实现类方法的返回值
        String result =service.getUser(2);
      -->
    <cxf:client id="userService"
                serviceClass="com.etoak.service.UserService"
                address="http://localhost:8080/ws/user">
        <!--In拦截器-->
        <cxf:inInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
        </cxf:inInterceptors>
        <!--Out拦截器-->
        <cxf:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
            <bean class="com.etoak.interceptor.AutoOutInterceptor">
                <constructor-arg name="username" value="zs" />
                <constructor-arg name="password" value="123456"/>
            </bean>
        </cxf:outInterceptors>

    </cxf:client>
</beans>

客户端自定义拦截器

未完待续
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐