webService




  
  /*WebService:远程调用,==>XML,SOAP和WSDL就是构成WebService
平台的三大技术,就是一台计算机的应用可以调用其他计算机上的应用。例如:支付宝,
支付宝并没有银行卡等数据,它只是去调用银行提供的接口来获得数据。还有天气预报等,
也是气象局把自己的系统服务以webservice服务的形式暴露出来,
让第三方网站和程序可以调用这些服务功能。*/
 
  /*WebService服务器端首先要通过一个WSDL文件来说明自己有什么服务可以对外调用。
简单的说,WSDL就像是一个说明书,
用于描述WebService及其方法、
参数和返回值。WSDL文件保存在Web服务器上,通过一个url地址就可以访问到它。

  客户端要调用
一个WebService服务之前,要知道该服务的WSDL文件的地址。
WebService服务提供商可以通过两种方式来暴露它的WSDL文件地址:
1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。*/

  /*WSDL(Web Services Description Language), web服务描述语言,
他是webservice服务端使用说明书,
说明服务端接口、方法、参数和返回值,
WSDL是随服务发布成功,自动生成,无需编写。*/


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

A1.web Service和Spring Mvc整合,父工程ws-cxf-spring中包含ws-cxf-spring-client客户端和ws-cxf-spring-web服务端

父工程依赖
<!-- dependencyManagement:依赖管理器 声明依赖,但是不导入依赖,由子模块按需引入依赖 --> <dependencyManagement> <dependencies> <!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- Spring-Web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.6.RELEASE</version> </dependency> <!-- spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.6.RELEASE</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.1</version> </dependency> <!-- CXF相关依赖 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.18</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.1.18</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.1.18</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.14</version> </dependency> </dependencies> </dependencyManagement>

A2.ws-cxf-spring-web服务端

2.1服务端pom依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ws-cxf-spring</artifactId> <groupId>com.etoak.et2006.ws</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ws-cxf-spring-web</artifactId> <packaging>war</packaging> <name>Spring-Web整合CXF创建服务端</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <scope>provided</scope> </dependency> <!-- Spring-Web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <!-- spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> <!-- CXF相关依赖 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> </dependencies> <build> <finalName>ws-cxf-spring-web</finalName> </build> </project>
2.2web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- 配置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> </web-app>
2.3spring-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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:core="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <!-- Spring组件扫描 --> <context:component-scan base-package="com.etoak" /> <!-- 创建JaxWsServerFactoryBean: 发布CXF的web服务 setAddress() setServiceClass() setServiceBean Server server = factory.create(); server.start() --> <!-- http://localhost:8080/path/ws/user?wsdl --> <jaxws:server address="/user" serviceClass="com.etoak.service.UserService"><!--要发布的接口--> <jaxws:serviceBean> <ref bean="userServiceImpl" /><!--接口实现类--> </jaxws:serviceBean> <!-- 配置Out拦截器 --> <jaxws:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" /><!--日志拦截器--> </jaxws:outInterceptors> <!-- 配置In拦截器 --> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <!-- <ref bean="authInInterceptor" /> --> </jaxws:inInterceptors> </jaxws:server> <!-- 可以用于配置全局拦截器 --> <core:bus> <core:inInterceptors> <ref bean="authInInterceptor" /> </core:inInterceptors> </core:bus>
<!-- 数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://127.0.0.1:3306/et2006" p:username="root" p:password="root"> </bean> <!-- SqlSessionFactoryBean: 创建session --> <bean class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:typeAliasesPackage="com.etoak.bean" p:mapperLocations="classpath:mappers/*.xml"> </bean> <!-- MapperScannerConfigurer: 自动扫描 将Mapper接口生成代理注入到Spring --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.etoak.mapper"> </bean> </beans>
2.4对外提供的接口及实现类
@WebService(serviceName = "UserServiceWS", portName = "UserServicePort")
//serviceName和portName其实就是为了好看点,不加的话,页面出来的标签会是UserService Service (两个service)
public interface UserService {
    User getUser(@WebParam(name = "id") int id);
    /*@WebParam表示方法的参数,加上会让wsdl里的参数名一致,不加则是arg0,arg1....
    * 暴漏接口参数时使用,例如在接口文件中写入一个接口*/

}
=========================================================实现类==============================================================
package com.etoak.service.impl;

import com.etoak.bean.User;
import com.etoak.mapper.UserMapper;
import com.etoak.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.jws.WebService;

@WebService(serviceName = "UserServiceWS",
portName = "UserServicePort") // web service
@Service // spring bean
public class UserServiceImpl implements UserService {

@Autowired
UserMapper userMapper;

@Override
public User getUser(int id) {
return userMapper.getUser(id);
}

}
 
2.5服务端拦截器
package com.etoak.interceptor; import com.etoak.bean.User; import com.etoak.mapper.UserMapper; import org.apache.commons.codec.digest.DigestUtils; 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.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import javax.xml.
namespace.QName; @Service public class AuthInInterceptor extends AbstractPhaseInterceptor<SoapMessage> { @Autowired UserMapper userMapper; public AuthInInterceptor() { // 调用父类的构造方法,传入拦截阶段 // 在执行前拦截 super(Phase.PRE_INVOKE); } @Override public void handleMessage(SoapMessage message) throws Fault { // 先获取<et2006> Header header = message.getHeader(new QName("et2006")); if(header == null) { throw new Fault(new RuntimeException("没有认证信息")); } Element et2006 = (Element)header.getObject(); // 获取<name>元素 NodeList nameNode = et2006.getElementsByTagName("name"); if(nameNode == null || nameNode.getLength() != 1) { throw new Fault(new RuntimeException("请传入name元素")); } NodeList pwdNode = et2006.getElementsByTagName("password"); if(pwdNode == null || pwdNode.getLength() != 1) { throw new Fault(new RuntimeException("请传入password元素")); } // 获取用户名和密码 String name = nameNode.item(0).getTextContent(); String password = pwdNode.item(0).getTextContent(); password = DigestUtils.md5Hex(password); User user = userMapper.getByNameAndPwd(name, password); if(ObjectUtils.isEmpty(user)) { throw new Fault(new RuntimeException("用户名或密码错误")); } System.out.println("======验证通过======="); } }

A3.ws-cxf-spring-client客户端

wsdl2java -d D:/client http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl ==>根据文档地址下载客户端到d盘的client中

3.1 客户端pom依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ws-cxf-spring</artifactId> <groupId>com.etoak.et2006.ws</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>ws-cxf-spring-client</artifactId> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> </dependency> </dependencies> </project>
3.2spring-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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:core="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <!-- 配置远程服务代理 --> <!-- JaxWsProxyFactoryBean setAddress() setServiceClass() 远程服务代理 = create() --> <jaxws:client id="userService" address="http://localhost:8080/ws/user" serviceClass="com.etoak.service.UserService"> <!-- 配置Out拦截器 --> <jaxws:outInterceptors> <!-- 官方拦截器 --> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" /> </jaxws:outInterceptors> <!-- 配置In拦截器 --> <jaxws:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" /> </jaxws:inInterceptors> </jaxws:client> <core:bus> <core:outInterceptors> <!-- 配置自定义拦截器 --> <bean class="com.etoak.interceptor.AuthOutInterceptor"> <constructor-arg name="name" value="zs" /> <constructor-arg name="password" value="123456" /> </bean> </core:outInterceptors> </core:bus> </beans>
3.3客户端拦截器
package
com.etoak.interceptor; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.headers.Header; import org.apache.cxf.helpers.DOMUtils; 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; import javax.xml.namespace.QName; import java.util.List; public class AuthOutInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String name; private String password; public AuthOutInterceptor(String name, String password) { // 调用父类的构造方法,传入拦截器拦截阶段 super(Phase.PRE_STREAM); this.name = name; this.password = password; } /** * <soap:Header> * <et2006> * <name>zs</name> * <password>123456</password> * </et2006> * </soap:Header> * @param message * @throws Fault */ @Override public void handleMessage(SoapMessage message) throws Fault { // 创建Document Document doc = DOMUtils.createDocument(); // 创建<et2006> Element et2006 = doc.createElement("et2006"); // 创建Element <name> Element nameElement = doc.createElement("name"); nameElement.setTextContent(this.name); // 创建Element <password> Element passwdElement = doc.createElement("password"); passwdElement.setTextContent(this.password); et2006.appendChild(nameElement); et2006.appendChild(passwdElement); List<Header> headers = message.getHeaders(); Header header = new Header(new QName("et2006"), et2006); headers.add(header); } }

B1.cxf与springBoot没有starter的整合

1.1配置类
package
com.etoak.config; import com.etoak.service.HelloService; import com.etoak.service.impl.HelloServiceImpl; import org.apache.cxf.Bus; import org.apache.cxf.bus.spring.SpringBus; import org.apache.cxf.endpoint.Server; import org.apache.cxf.interceptor.Interceptor; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import org.apache.cxf.message.Message; import org.apache.cxf.transport.servlet.CXFServlet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration//定义配置类 public class CxfConfig { @Bean//注册Servlet组件 public ServletRegistrationBean<CXFServlet> cxfServlet() { ServletRegistrationBean<CXFServlet> registrationBean = new ServletRegistrationBean<>(); // servlet-class registrationBean.setServlet(new CXFServlet()); // url-pattern registrationBean.addUrlMappings("/ws/*"); return registrationBean; }
@Autowired HelloService helloService;
/** * bean的名称必须cxf * @return */ @Bean(Bus.DEFAULT_BUS_ID) public Bus cxf() { Bus bus = new SpringBus(); // 添加全局拦截器 bus.getInInterceptors().add(new LoggingInInterceptor()); return bus; } @Bean public void helloService() { /*使用Endpoint(端点)类发布webservice*/ EndpointImpl endpoint = new EndpointImpl(helloService); // 添加私有的拦截器 endpoint.getOutInterceptors().add(new LoggingOutInterceptor()); endpoint.publish("/hello"); } @Bean("helloService2") public void helloService2() { //发布web服务 JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.setAddress("/hello2"); factoryBean.setServiceClass(HelloService.class); factoryBean.setServiceBean(this.helloService); // factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()) Server server = factoryBean.create(); server.start(); } }

 


 

=================================================pom依赖===============================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.etoak.et2006.boot</groupId>
<artifactId>ws-boot-non-starter</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.18</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.18</version>
</dependency>
</dependencies>

</project>
 

C1.cxf与springBoot有starter的整合

1.1pom依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.etoak.et2006.ws</groupId> <artifactId>ws-boot-cxf-starter</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.3.5</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.10</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> </project>
1.2application.yml配置
server: port:
9001 cxf: # path的值只能是/xxx 或者 /xxx/ path: /ws spring: datasource: # 更换数据源 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/et2006?serverTimezone=UTC username: root password: root mybatis: mapper-locations: classpath:mappers/*.xml type-aliases-package: com.etoak.bean pagehelper: reasonable: true logging: level: com.etoak.mapper: debug
1.3Springboot启动类
package com.etoak;

import com.etoak.service.UserService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@MapperScan(basePackages = "com.etoak.mapper")
/*@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加,*/
public class CxfApp {

    public static void main(String[] args) {
        SpringApplication.run(CxfApp.class, args);
    }

    @Autowired
    UserService userService;

//    @Autowired
//    Bus bus;
    /*只要cxf和springBoot整合就必须要写springBus*/
    @Bean("cxf")
    public SpringBus springBus() {
        SpringBus bus = new SpringBus();
        return bus;
    }

    @Bean
    public void userService() {
        EndpointImpl endpoint = new EndpointImpl(userService);
        endpoint.getOutInterceptors()
                .add(new LoggingOutInterceptor());
        endpoint.publish("/user");
    }

}

 

posted @ 2020-12-15 23:17  zhong12138  阅读(218)  评论(0编辑  收藏  举报