WebService
Posted 狼_少_年
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebService相关的知识,希望对你有一定的参考价值。
1.什么是WebService?
WebService是一种跨编程语言,跨操作系统平台的远程调用技术.
即使服务端和客户端程序的编程语言,操作系统不同,客户端上的程序也可以调用到服务端接口提供的方法
举例:
1)商家的pos机调用银行服务器上的方法进行转账
2)百度调用天气预报系统
2.WebService的三个规范
1)JAX-WS(Java API for XML-Based Webservices)规范
采用基于http应用层的协议Soap(Simple Object Access Protocol),Soap协议传输的是xml数据,xml是WebService可以跨操作系统平台的基础,因为xml主要的优点就是它既与平台无关,也与厂商无关.
W3C为WebService制定了一套传输数据类型,使用xml进行描述,即XSD(XML Schema Datatypes),任何编程语言写的WebService接口在发送数据时都要转换成WebService标准的XSD发送.
1.1)JAX-WS三要素
1.SOAP:基于HTTP协议,采用XML格式,用来传递信息的格式
2.WSDL:用来描述如何访问具体服务的文档(JAX-WS可自动生成对外接口的\\说明文档,但此文档并不是给程序员提供的,而是给JDK提供的)
3.UDDI:用户可以按UDDI标准搭建UDDI服务器,用来管理分发查询WebService(类似目录收集)
2)JAX-RS规范
是JAVA针对REST风格制定的一套Web服务规范,rest风格的WebService不采用SOAP协议传输,而是采用http协议,可以返回xml或json.
Apache CXF(Celtix+Xfire)是一个开源的WebService框架,支持多种协议,包括SOAP,XML/HTTP,RESTFUL,正是因为CXF支持RESTFUL风格,所以CXF也是支持JAX-RS服务规范的框架.
3)JAXM&SAAJ
编码麻烦,暴露SOAP的底层细节,废弃
3.JAX_RS整合Spring案例
3.1 模拟服务提供方(生产者)
3.1.1 创建服务提供者,项目名称:spring_jax_rs_server
3.1.2 引入依赖,指定打包方式war
<dependencies> <!-- cxf 进行rs开发 必须导入 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>3.0.1</version> </dependency> <!-- 日志引入 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <!-- 客户端 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>3.0.1</version> </dependency> <!-- 扩展json提供者 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>3.0.1</version> </dependency> <!-- 转换json工具包,被extension providers 依赖 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.7</version> </dependency> <!-- spring 核心 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- spring web集成 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- spring 整合junit --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- junit 开发包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
3.1.3 编写实体类
注意:@XmlRootElement注解作用:指明xml中根标签的名称,可对比下面的服务端返回的xml
package com.jaxrs.domain; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "User") public class User { private Integer id; private String username; private String city; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
3.1.4 编写提供给客户端的接口及实现类
注意:@Produces注解作用:用来指定资源能够生成并发送给客户端的MIME媒体类型
@Consumes注解作用:用来指定资源能够接受的客户端发送的MIME媒体类型
package com.jaxrs.service; import com.jaxrs.domain.User; import javax.ws.rs.*; import java.util.List; /** * @author Adil * @date 2020-03-21 13:32:18 */ @Path("/userService") @Produces("*/*") public interface UserService { @POST @Path("/user") @Consumes({"application/xml", "application/json"}) public void saveUser(User user); @PUT @Path("/user") @Consumes({"application/xml", "application/json"}) public void updateUser(User user); @GET @Path("/user") @Produces({"application/xml", "application/json"}) public List<User> findAllUsers(); @GET @Path("/user/{id}") @Consumes("application/xml") @Produces({"application/xml", "application/json"}) public User finUserById(@PathParam("id") Integer id); @DELETE @Path("/user/{id}") @Consumes({"application/xml", "application/json"}) public void deleteUser(@PathParam("id") Integer id); }
package com.jaxrs.service.impl; import com.jaxrs.domain.User; import com.jaxrs.service.UserService; import java.util.ArrayList; import java.util.List; /** * @author Adil * @date 2020-03-21 13:33:49 */ public class UserServiceImpl implements UserService { public void saveUser(User user) { System.out.println("save user:" + user); } public void updateUser(User user) { System.out.println("update user:" + user); } public List<User> findAllUsers() { List<User> users = new ArrayList<User>(); User user1 = new User(); user1.setId(1); user1.setUsername("小明"); user1.setCity("北京"); users.add(user1); User user2 = new User(); user2.setId(2); user2.setUsername("小丽"); user2.setCity("上海"); users.add(user2); return users; } public User finUserById(Integer id) { if (id == 1) { User user1 = new User(); user1.setId(1); user1.setUsername("小明"); user1.setCity("北京"); return user1; } return null; } public void deleteUser(Integer id) { System.out.println("delete user id :" + id); } }
3.1.5 编写applicationContext.xml
注意:address属性作用:添加路由(可写可不写,如果写了,客户端发送的url中就要包含此路径)
serviceClass属性作用:映射到实现类
<?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/core" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd "> <jaxrs:server address="/toUserService" serviceClass="com.jaxrs.service.impl.UserServiceImpl"></jaxrs:server> </beans>
3.1.6 编写web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--全局加载监听器,监听applicationContext.xml配置文件--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF的核心控制器 如果与spring整合需要配置 CXF核心控制器 作用跟DispathcerServlet一样 --> <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>/rs/*</url-pattern> </servlet-mapping> </web-app>
以上简单模拟了一个服务端,实际服务端是不需要我们自己写的,因为使用WebService,就是调用其他的系统,肯定是已经写好并对你开放的,接下来我们配置tomcat,就可以启动服务了.
我们先通过浏览器端进行访问:http://localhost:8080/rs/toUserService/userService/user/1
<User> <city>北京</city> <id>1</id> <username>小明</username> </User>
<User>就是@XmlRootElement注解指定的根标签的名称
3.2基于JAX-RS的客户端
3.2.1 创建客户端项目
3.2.2 引入依赖(与服务端保持一致)
3.2.3 编写实体类(与服务端保持一致)
3.2.3 调用服务
注意:调用的url路径及传入的参数要遵守服务端的规定
package com.jaxrs.client; import com.jaxrs.domain.User; import org.apache.cxf.jaxrs.client.WebClient; /** * @author Adil * @date 2020-03-21 14:11:19 */ public class JaxRsClient { public static void main(String[] args) { WebClient webClient = WebClient.create("http://localhost:8080/rs/toUserService/userService/user/1"); User user = webClient.get(User.class); System.out.println(user); } }
接下来,启动main方法,可以看到控制台打印服务端返回的User对象
4.JAX-WS整合Spring调用互联网系统(IP地址来源搜索)案例
4.1 创建客户端项目
4.2 引入依赖
<dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.0.1</version> </dependency> <!-- 日志引入 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <!-- 转换json工具包,被extension providers 依赖 --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.7</version> </dependency> <!-- spring 核心 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- spring web集成 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- spring 整合junit --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- junit 开发包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
4.3 通过JDK解析WDSL文档生成代码
在JAX-WS规范的介绍中,我们就说了,它有自己的对外接口说明文档,而JDK是可以解析该文档生成代码的.命令如图
执行完该命令后,我们会在java下看到多了几个包和很多文件,其中.class文件我们全部删除掉.
4.4 配置Spring整合
address指定WSDL文件的位置
serviceClass指定生成的接口的位置
<?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/core" 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/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd "> <jaxws:client id="ipAddress" address="http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl" serviceClass="cn.com.webxml.IpAddressSearchWebServiceSoap"></jaxws:client> </beans>
4.5 调用服务
通过id得到接口对象,打点可以查看其中的方法,这里是getCountryCityByIp(),即通过ip查看所在城市位置
package cn.com.client; import cn.com.webxml.ArrayOfString; import cn.com.webxml.IpAddressSearchWebServiceSoap; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; /** * @author Adil * @date 2020-03-21 18:36:22 */ public class JaxwsClient { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-cxf-client.xml"); IpAddressSearchWebServiceSoap ipAddress = (IpAddressSearchWebServiceSoap) context.getBean("ipAddress"); ArrayOfString city = ipAddress.getCountryCityByIp("111.198.224.201"); System.out.println(city.getString())
返回结果
以上是关于WebService的主要内容,如果未能解决你的问题,请参考以下文章
C#动态调用webService出现 基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系。
当我们在webservice.asmx.cs中编写所有代码时,webservice.asmx有啥用?