springboot+webservice(cxf和jax-ws两种方式)

webservice调用远程服务

目前自己参考网上博客写的两种方式,我这里用的是springboot,废话不多说,直接上代码

首先是pom依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.apache.cxfgroupId>
            <artifactId>cxf-spring-boot-starter-jaxwsartifactId>
            <version>3.1.11version>
        dependency>
    dependencies>

然后就是java代码
我直接把两个方法写在一个类里面了

package com.yikete.controller;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;

import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPBinding;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Controller
public class Test {
    /**
     * 方法一:用cxf框架
     * @param url
     * @param method
     * @param args
     * @return
     */
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String, Object> hello(String url, String method, String[] args) {
        if (args.length < 1) {
            args = new String[]{""};
        }
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(url);
        // 需要密码的情况需要加上用户名和密码
        // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));
        // 命名空间,方法名
        QName name = new QName("http://WebXml.com.cn/", method);
        HashMap<String, Object> map = new HashMap<>();
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            Object[] objects = client.invoke(name, args);
            System.out.println("返回数据:" + objects[0]);
            System.out.println("返回数据:" + Arrays.toString(objects));
            map.put("result", objects);
            return map;
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            map.put("result", "接口调用异常");
            return null;
        }
    }

    /**
     * 方法二:自己用jax-ws的方式实现
     * @param url 请求地址
     * @param targetNamespace 名称空间
     * @param pName 端口名
     * @param method 方法名
     * @param argsName 参数名
     * @param args  参数
     * @return
     * @throws Exception
     */
    @RequestMapping("/getSoap")
    @ResponseBody
    public Map getSoap(String url, String targetNamespace, String pName, String method, String[] argsName, String[] args) throws Exception {
        QName serviceName = new QName(targetNamespace, method);

        //WSDL中定义的端口的QName
        QName portName = new QName(targetNamespace, pName);

        //创建动态Service实例
        Service service = Service.create(serviceName);
        service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, url);

        //创建一个dispatch实例
        Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);

        // Use Dispatch as BindingProvider
        BindingProvider bp = (BindingProvider) dispatch;

        // 配置RequestContext以发送SOAPAction HTTP标头
        Map<String, Object> rc = dispatch.getRequestContext();
        rc.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
        rc.put(BindingProvider.SOAPACTION_URI_PROPERTY, targetNamespace + method);

        // 获取预配置的SAAJ MessageFactory
        MessageFactory factory = ((SOAPBinding) bp.getBinding()).getMessageFactory();

        // 创建SOAPMessage请求
        SOAPMessage request = null;
        request = factory.createMessage();
        // 请求体
        SOAPBody body = request.getSOAPBody();

        // Compose the soap:Body payload
        QName payloadName = new QName(targetNamespace, method);

        SOAPBodyElement payload = body.addBodyElement(payloadName);
        if (args.length > 0) {
            for (int i = 0; i < argsName.length; i++) {
                payload.addChildElement(argsName[i]).setValue(args[i]);
            }
        }
//        payload.addChildElement("startCity").setValue("北京");
//        payload.addChildElement("lastCity").setValue("上海");
//        payload.addChildElement("theDate").setValue("2019-06-07");
//        payload.addChildElement("userID").setValue("");

//        SOAPElement message = payload.addChildElement(INPUT_NMAE);
//        message.addTextNode("88888");

        SOAPMessage reply = null;

        try {
            //调用端点操作并读取响应
            request.writeTo(System.out);
            reply = dispatch.invoke(request);
            reply.writeTo(System.out);
        } catch (WebServiceException wse) {
            wse.printStackTrace();
        }

        // 处理响应结果
        Document doc = reply.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
        HashMap<String, Object> map = new HashMap<>();
            map.put("result", doc);
        return map;

    }

    // Document对象转字符串
    public static String format(Document doc) throws Exception {
        // XML转字符串
        String xmlStr = "";
        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.setOutputProperty("encoding", "UTF-8");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            t.transform(new DOMSource(doc), new StreamResult(bos));
            xmlStr = bos.toString();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return xmlStr;
    }
}

方法二比较好用一点,因为方法一的话cxf请求wsdl,如果wsdl中出现这个东西,就会报错,因为java这边没法解析这个。解决的办法是要把wsdl文件保存到本地,然后再把这个替换成,有点麻烦,所以还是用第二种比较好,至于传入的参数哪里找,可以去查一下wsdl文档详细说明

测试的话我是自己简单写了个html页面
我我也贴出来算了

这是方法一的测试页面


<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>webservicetitle>
    <script src="./js/jquery.js">script>
head>
<body>
<form id='form'>
    url:<input name="url" placeholder="请输入请求路径" style="width: 400px" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
    method:<input name="method" placeholder="请输入请求方法" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
    args:<input name="args" placeholder="arg1,arg2,arg3...">
form>
<button id="save-btn">提交button>
<div>返回结果div>
<textarea id="result" style="width:300px;height:100px;">textarea>
body>
html>
<script>
    $("#save-btn").on("click", function () {
        $.ajax({
            //几个参数需要注意一下
            type: "POST",//方法类型
            dataType: "json",//预期服务器返回的数据类型
            url: "/hello",//url
            data: $('#form').serialize(),
            success: function (data) {
                console.log(data.result);//打印服务端返回的数据(调试用)
                $("#result").html(data.result)
            },
            error: function () {
                alert("异常!");
            }
        });
    })
script>

这是方法二的测试页面


<html lang="en" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html"
      xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>webservicetitle>
    <script src="./js/jquery.js">script>
head>
<body>
<form id='form'>
    url:<input name="url" placeholder="请输入请求路径" style="width: 400px" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
    targetNamespace:<input name="targetNamespace" placeholder="名称空间" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
    pName:<input name="pName" placeholder="请输入请求方法" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">
    method:<input name="method" placeholder="请输入请求方法" onkeyup="this.value=this.value.replace(/^ +| +$/g,'')">br>
    argsName:<input name="argsName" placeholder="name1,name2,name3...">
    args:<input name="args" placeholder="arg1,arg2,arg3...">
form>
<button id="save-btn">提交button>
<div>返回结果div>
<textarea id="result" style="width:892px;height:810px;">textarea>
body>
html>
<script>
    $("#save-btn").on("click", function () {
        $.ajax({
            //几个参数需要注意一下
            type: "POST",//方法类型
            dataType: "json",//预期服务器返回的数据类型
            url: "/getSoap",//url
            data: $('#form').serialize(),
            success: function (data) {
                console.log(data.result);//打印服务端返回的数据(调试用)
                $("#result").html(data.result)
            },
            error: function () {
                alert("异常!");
            }
        });
    })
script>

你可能感兴趣的:(java进阶)