WebService入门

214 阅读4分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之路

WebService 参考博客

  1. 概念

    • 一种跨编程语言和跨操作系统的远程调用技术
  2. WebService规范

    1. JAX-WS
      • jdk1.6自带2.1,位于javax.xml.ws.*包,基于soap协议
    2. JAXM&SASJ
      • 定义了包含发送和接受消息所需的api,相当于web服务的服务器端
    3. JAX-RS
      • 基于resultful风格的webService
  3. webService三要素

    1. soap
      • 基于xml语言的协议 -SOAP=在http的基础上+xml数据
    2. wsdl说明书
      • 描述webService服务端对外发布的服务
      • 基于xml文件,通过xml语言描述整个服务
    3. uudi
      • uddi是跨产业、跨平台的开放性架构,帮助web服务提供商在互联网上发布web服务的信息
  1. 应用场景

    1. 跨防火墙通信
    2. 应用系统集成
    3. 软件数据重用
  2. 优缺点

    1. 优点
      • 异构平台的互通
      • 广泛的软件复用
      • 成本低、可读性强、应用范围广
      • 开发迅速
      • 客户端与服务器端可以是不同的语言,可以传递对象
    2. 缺点
      • soap是基于xml传输,会携带很多无用的内容
      • 简单的接口可以直接使用http传输
  3. ApacheCXF框架

    1. 概念

      • 开源的Services框架,利用Frontend编程API构建和开发Services,支持多协议并且可以在多种传输协议上运行
    2. 功能特性

      • 支持WebService标准
      • 支持多种"Frontend"编程模型
      • 容易使用
    3. 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);
    
     }
     ```
     ```java
    

    package 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";
         }
     }
     ```
     ```java
    

    package 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("服务发布完成");
     }
     }
     
     ```
     ```java
    

    package 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.xml xml <?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>
         ````