本文已参加「新人创作礼」活动,一起开启掘金创作之路
WebService 参考博客
-
概念
- 一种跨编程语言和跨操作系统的远程调用技术
-
WebService规范
- JAX-WS
- jdk1.6自带2.1,位于javax.xml.ws.*包,基于soap协议
- JAXM&SASJ
- 定义了包含发送和接受消息所需的api,相当于web服务的服务器端
- JAX-RS
- 基于resultful风格的webService
- JAX-WS
-
webService三要素
- soap
- 基于xml语言的协议 -SOAP=在http的基础上+xml数据
- wsdl说明书
- 描述webService服务端对外发布的服务
- 基于xml文件,通过xml语言描述整个服务
- uudi
- uddi是跨产业、跨平台的开放性架构,帮助web服务提供商在互联网上发布web服务的信息
- soap
-
应用场景
- 跨防火墙通信
- 应用系统集成
- 软件数据重用
-
优缺点
- 优点
- 异构平台的互通
- 广泛的软件复用
- 成本低、可读性强、应用范围广
- 开发迅速
- 客户端与服务器端可以是不同的语言,可以传递对象
- 缺点
- soap是基于xml传输,会携带很多无用的内容
- 简单的接口可以直接使用http传输
- 优点
-
ApacheCXF框架
-
概念
- 开源的Services框架,利用Frontend编程API构建和开发Services,支持多协议并且可以在多种传输协议上运行
-
功能特性
- 支持WebService标准
- 支持多种"Frontend"编程模型
- 容易使用
-
WS服务端
package com.jamin.service;
import javax.jws.WebService;
/** * @author Jamin <br> * @date 2019/11/20 18:11<br> * helloWebService服务端接口 */ @WebService public interface HelloServer { /** * 服务端接口 * @param name * @return */ public String helloServer(String name); } ``` ```javapackage com.jamin.service.impl;
import com.jamin.service.HelloServer;
/** * @author Jamin <br> * @date 2019/11/20 21:01<br> * 服务端接口实现 */ public class HelloServerImpl implements HelloServer { @Override public String helloServer(String name) { return "你好"+name+"+WebSerice"; } } ``` ```javapackage com.jamin;
import com.jamin.service.impl.HelloServerImpl;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/* * @author Jamin <br> * @date 2019/11/20 21:08<br> * 测试WebService发布 */ public class TestWebService { public static void main(String[] args) { // 发布服务的工厂 JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean(); // 设置服务地址 jaxWsServerFactoryBean.setAddress("http://127.0.0.1:9099/ws/hello"); // 设置服务 jaxWsServerFactoryBean.setServiceBean(new HelloServerImpl()); // 发布服务 jaxWsServerFactoryBean.create(); System.out.println("服务发布完成"); } } ``` ```javapackage com.jamin.server;
import com.jamin.service.impl.HelloServerImpl;
import javax.xml.ws.Endpoint;
/** * @author Jamin <br> * @date 2019/11/23 17:08<br> * 测试 此方法需要接口实现类注解 导入javax.jws.jsr181 @WebService(endpointInterface = * "com.jamin.service.HelloServer", serviceName = "helloServer") */ public class Test { public static void main(String[] args) { Endpoint.publish("http://localhost:9001/userServer/", new HelloServerImpl()); }}
```4. WS客户端 (将接口放在客户端包下,[异常处理]blog.csdn.net/qq_38999509…) ```java package com.jamin;
import com.jamin.impl.HelloServerImpl;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
/** * @author Jamin <br> * @date 2019/11/20 21:08<br> * 测试WebService发布 */ public class TestWebService { public static void main(String[] args) { // 发布服务的工厂 JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean(); // 设置服务地址 jaxWsServerFactoryBean.setAddress("http://127.0.0.1:9099/ws/hello"); // 设置服务 jaxWsServerFactoryBean.setServiceBean(new HelloServerImpl()); // 发布服务 jaxWsServerFactoryBean.create(); System.out.println("服务发布完成"); } } ```5. 日志输入输出
java // 添加日志输入输出拦截器 jaxWsProxyFactoryBean.getInInterceptors().add(new LoggingInInterceptor()); jaxWsProxyFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());xml <!--发送请求的信息--> ---------------------------- ID: 1 Response-Code: 200 Encoding: UTF-8 Content-Type: text/xml;charset=utf-8 Headers: {Content-Length=[229], content-type=[text/xml;charset=utf-8], Date=[Thu, 21 Nov 2019 07:42:45 GMT], Server=[Jetty(9.4.21.v20190926)]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:helloServerResponse xmlns:ns2="http://jamin.com/"><return>你好测试+WebSerice</return></ns2:helloServerResponse></soap:Body></soap:Envelope> --------------------------------------6. Spring整合CXF框架(WS) 1. 服务端 - web.xmlxml <?xml version="1.0" encoding="UTF-8"?> <!-- Created by IntelliJ IDEA. User: Jamin Date: 2019/11/21 Time: 16:18 Desc: web.xml --> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0" 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_3_0.xsd"> <!--csfServlet配置--> <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> <!--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> </web-app>- applicationContext.xml ```xml <beans xmlns="www.springframework.org/schema/bean…" xmlns:xsi="www.w3.org/2001/XMLSch…" xmlns:jaxws="cxf.apache.org/jaxws" xsi:schemaLocation="www.springframework.org/schema/bean… www.springframework.org/schema/bean…http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:server address="/hello"> <jaxws:serviceBean> <bean class="com.jamin.springService.impl.HelloServiceImpl"/> </jaxws:serviceBean> </jaxws:server> </beans> ``` 2. 客户端 1. applicationContext.xml ```xml <?xml version="1.0" encoding="UTF-8"?> <!-- Created by IntelliJ IDEA. User: Jamin Date: 2019/11/21 Time: 16:15 Desc: spring配置文件 --> <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"> <!-- 客户端--> <jaxws:client id="HelloService" serviceClass="com.jamin.springService.HelloService" address="http://localhost:8080/ws/hello"/> </beans> ``` 2. 测试代码 ```java package com.jamin; import com.jamin.springService.HelloService; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; /** * @author Jamin <br> * @date 2019/11/21 17:44<br> * 测试 */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class Test { @Resource private HelloService helloService; @org.junit.Test public void test() { System.out.println(helloService.getClass()); String s = helloService.helloService("测试"); System.out.println(s); } } ```7. 独立RS 1. 服务端 - pom.xml ```xml junit junit 4.11 test org.apache.cxf cxf-rt-rs-extension-providers 3.3.4
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>3.3.4</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http-jetty --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.3.4</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>2.0.0-alpha1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.codehaus.jettison/jettison --> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.4.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart --> </dependencies> ``` - 接口 ```java package com.jamin.service; import com.jamin.entity.User; import javax.ws.rs.*; import java.util.List; /** * @author Jamin <br> * @date 2019/11/22 20:27<br> * 用户接口 */ /** 当前服务对应访问路径 */ @Path("/userService") /** * 返回格式 */ @Produces("*/*") public interface UserService { /** * 新增操作 * * @param user 访问当前服务所对应的路径 服务器支持的请求数据格式 */ /** 请求格式 */ @POST /** 请求路径 */ @Path("/user") /** */ @Consumes({"application/xml", "application/json"}) public void saveUser(User user); /** * 修改操作 * * @param user */ @PUT @Path("/user") @Consumes({"application/xml", "application/json"}) @Produces({"application/xml", "application/json"}) public void updateUser(User user); /** * 删除操作 * * @param user */ @DELETE @Path("/user") @Consumes({"application/xml", "application/json"}) public void deleteUser(User user); /** * 查询操作 * * @return */ @GET @Path("/user") @Consumes({"application/xml", "application/json"}) public List<User> findAllUsers(); @GET @Path("/user/{id}") @Consumes({"application/xml", "application/json"}) public User findUserById(@PathParam("id") int id); } ``` - 实现类(省略) - 开启服务 ```java package com.jamin; import com.jamin.entity.User; import com.jamin.service.impl.UserServiceImpl; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; /** * @author Jamin <br> * @date 2019/11/23 12:00<br> * 服务端测试 */ public class ServerTest { public static void main(String[] args) { JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean(); // 设置类文件转换json格式 jaxrsServerFactoryBean.setResourceClasses(User.class); jaxrsServerFactoryBean.setAddress("http://localhost:9001/ws/"); jaxrsServerFactoryBean.setServiceBean(new UserServiceImpl()); jaxrsServerFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); jaxrsServerFactoryBean.getInInterceptors().add(new LoggingInInterceptor()); jaxrsServerFactoryBean.create(); System.out.println("服务启动完成"); } } ```8. Spring整合RS 1. 服务端 1. application.xml
xml <?xml version="1.0" encoding="UTF-8"?> <!-- Created by IntelliJ IDEA. User: Jamin Date: 2019/11/23 Time: 18:40 Desc: --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <jaxrs:server id="userServer" address="/userServer"> <jaxrs:serviceBeans> <bean class="com.jamin.server.service.impl.UserServiceImpl"/> <bean class="com.jamin.server.entity.User"/> </jaxrs:serviceBeans> <jaxrs:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> </jaxrs:outInterceptors> <jaxrs:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/> </jaxrs:inInterceptors> </jaxrs:server> </beans>2. web.xml ```xml<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:application.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <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>/*</url-pattern> </servlet-mapping> </web-app> ```` 2. 客户端 ```java package com.jamin; import com.jamin.server.entity.User; import org.apache.cxf.jaxrs.client.WebClient; import java.util.Collection; /** * @author Jamin <br> * @date 2019/11/23 18:52<br> * 测试 */ public class TestClient { public static void main(String[] args) { Collection<? extends User> collection = WebClient.create("http://localhost:8080/userServer/userService/user") .getCollection(User.class); System.out.println(collection); } } ```9. ajax跨域访问 1. 配置服务端支持跨域访问(添加过滤器) ```java package com.jamin.server.filter;
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import javax.ws.rs.ext.Provider; import java.io.IOException; /** * @author Jamin <br> * @date 2019/11/24 9:56<br> * 过滤器 */ @Provider public class CORSFilter implements ContainerResponseFilter { @Override public void filter( final ContainerRequestContext requestContext, final ContainerResponseContext cres) throws IOException { cres.getHeaders().add("Access-Control-Allow-Origin", "*"); cres.getHeaders() .add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); cres.getHeaders().add("Access-Control-Allow-Credentials", "true"); cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); cres.getHeaders().add("Access-Control-Max-Age", "1209600"); } } ``` 2. 前端页面 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script src="js/jquery-3.4.1.min.js"></script> </head> <body> <input type="text" id="name" name="name" value="" /> <input type="button" id="btn1" value="send" /> <input type="text" id="dictionary" /> </body> <script type="text/javascript"> $(document).ready(function() { var user = {'user': "{'userId': 1,'userName': 'ceshi'}"}; // alert(user); $.ajax({ url: "http://localhost:8080/userServer/userService/user", type: "PUT", dataType: "json", contentType: "application/json", data: JSON.stringify(user), success: function(result) { // console.log(result.User.userId); // console.log(result.User.userName); console.log("success"); } }); }); </script> </html> ```` -