Skip to content

Latest commit

 

History

History
203 lines (203 loc) · 10.3 KB

SpringBoot整合WebService.md

File metadata and controls

203 lines (203 loc) · 10.3 KB
1.在Spring-Boot-WebService目录下新建Module: WebService-Server
    [1]引入web-services依赖,cxf相关依赖:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    [2]编写服务端配置类:
        @Configuration
        public class CxfConfig {
            @Bean(name = "cxfServlet")
            public ServletRegistrationBean<CXFServlet> cxfServlet(){
                // Servlet注册类,参数1为Servlet对象,参数2为请求到Servlet的地址
                return new ServletRegistrationBean<>(new CXFServlet(),"/demo/*");
            }
            @Bean(name = Bus.DEFAULT_BUS_ID)
            public SpringBus springBus(){
                return new SpringBus();
            }
            // 将提供的服务交给IOC管理,并提供给EndpointImpl发布
            @Bean
            public DemoService demoService() {
                return new DemoServiceImpl();
            }
            // 发布多个服务时,创建多个此类方法,并使用@Qualifier指定不同的名称
            @Bean
            public Endpoint endpoint(){
                EndpointImpl endpoint = new EndpointImpl(springBus(), demoService());
                endpoint.publish("/api");
                return endpoint;
            }
        }
    [3]编写服务端提供服务的接口:
        // name: Web Service的名称;targetNamespace: 指定名称空间,一般使用接口实现类的包名的反缀
        @WebService(name = "DemoService",targetNamespace = "http://impl.service.server.example.com")
        public interface DemoService {
            String sayHello(String user);
        }
    [4]编写服务端提供服务的接口实现类:
        // serviceName: 对外发布的服务名; 
	// targetNamespace: 指定名称空间,一般使用接口实现类的包名的反缀
        // endpointInterface:服务接口的全类名
        @WebService(serviceName = "DemoService"
                ,targetNamespace = "http://impl.service.server.example.com"
                ,endpointInterface = "com.example.server.service.DemoService")
        public class DemoServiceImpl implements DemoService {
            @Override
            public String sayHello(String user) {
                return user + ",现在的时间: "+ new Date();
            }
        }
2.在Spring-Boot-WebService目录下新建Module: WebService-Client
    [1]引入web依赖,web-services依赖,cxf相关依赖:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.3.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    [2]修改application.properties文件设置项目启动端口:
        server.port=8081
    [3]编写Controller测试WebService服务:
        @RestController
        public class TestController {
            @GetMapping("/test")
            public void test() throws Exception {
                // 创建动态客户端
                JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
		// 根据服务端的配置拼接而得
                Client client = factory.createClient("http://localhost:8080/demo/api?wsdl");
                // 需要密码的情况需要加上用户名和密码
                // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
                HTTPConduit conduit = (HTTPConduit) client.getConduit();
                HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
                httpClientPolicy.setConnectionTimeout(2000);  //连接超时
                httpClientPolicy.setAllowChunking(false);     //取消块编码
                httpClientPolicy.setReceiveTimeout(120000);   //响应超时
                conduit.setClient(httpClientPolicy);
                //client.getOutInterceptors().addAll(interceptors);//设置拦截器
                try{
                    Object[] objects ;
                    // invoke("方法名",参数1,参数2,参数3....);
                    objects = client.invoke("sayHello", "qiqi");
                    System.out.println("返回数据:" + objects[0]);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    [4]在Controller中测试网上公开发布的WebService服务:
        (1)可用的一些WebService服务地址: http://www.webxml.com.cn/zh_cn/index.aspx
        (2)以天气预报服务的getWeatherbyCityName接口为例:
            (http://ws.webxml.com.cn/WebServices/WeatherWebService.asmx)
        (3)编写Controller:
            @RestController
            public class TestController {
                @GetMapping("/testWeather")
                public void testWeather(){
                    String weatherInfo = getWeather("北京");
                    System.out.println(weatherInfo);
                }
                // 从接口文档中获取SOAP的请求头,并替换其中的标志符号为用户输入的城市
		// (http://ws.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getWeatherbyCityName)
                private static String getSoapRequest(String city) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
                            .append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
                            .append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ")
                            .append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">")
                            .append("<soap:Body> <getWeatherbyCityName xmlns=\"http://WebXml.com.cn/\">")
                            .append("<theCityName>")
                            .append(city)
                            .append("</theCityName> </getWeatherbyCityName>")
                            .append("</soap:Body></soap:Envelope>");
                    return sb.toString();
                }
                // 通过接口文档的请求头来构建SOAP请求,发送SOAP请求给服务器端,并返回流
                private static InputStream getSoapInputStream(String city) throws Exception {
                    try {
                        String soap = getSoapRequest(city);
                        // 通过请求的服务地址(即为Endpoint)构建URL对象,并使用URL对象开启连接
                        URL url = new URL("http://ws.webxml.com.cn/WebServices/WeatherWebService.asmx");
                        URLConnection conn = url.openConnection();
                        conn.setUseCaches(false);
                        conn.setDoInput(true);
                        conn.setDoOutput(true);
                        // 为连接设置请求头属性(服务接口文档中请求头信息)
                        conn.setRequestProperty("Content-Length", Integer.toString(soap.length()));
                        conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
                        conn.setRequestProperty("SOAPAction", "http://WebXml.com.cn/getWeatherbyCityName");
                        // 将请求的XML信息写入连接的输出流
                        OutputStream os = conn.getOutputStream();
                        OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
                        osw.write(soap);
                        osw.flush();
                        osw.close();
                        // 获取连接中请求得到的输入流
                        return conn.getInputStream();
                    } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                    }
                }
                // 对服务器端返回的XML进行解析(请求响应的XML信息在服务接口说明中)
                private static String getWeather(String city) {
                    try {
                        Document doc;
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        dbf.setNamespaceAware(true);
                        DocumentBuilder db = dbf.newDocumentBuilder();
                        InputStream is = getSoapInputStream(city);
                        assert is != null;
                        doc = db.parse(is);
                        NodeList nl = doc.getElementsByTagName("string");
                        StringBuffer sb = new StringBuffer();
                        for (int count = 0; count < nl.getLength(); count++) {
                            Node n = nl.item(count);
                            if(n.getFirstChild().getNodeValue().equals("查询结果为空!")) {
                                sb = new StringBuffer(" ");
                                break ;
                            }
                            sb.append(n.getFirstChild().getNodeValue()).append(" \n");
                        }
                        is.close();
                        return sb.toString();
                    } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                    }
                }