Springboot 项目 调用webservice接口

2024-05-01 1170阅读

springboot 项目 调用webservice接口/集成老系统

    • 前言
    • 焦头烂额
    • 调用方式:
      • 1.使用Hutool工具包调用:
      • 2.使用cxf工具包调用:
      • 问题及方案

        前言

        近期接到个需求,项目中需要集成零几年建设的OA系统。
        OA系统使用的接口全部都是webservice接口,在此分享一下webservice接口调用过程中遇到的问题及调用方式。
        

        焦头烂额

        笔者也是第一次接触webservice接口,搜索了大量的资料,最后使用如下两种方式进行的交互。
        

        调用方式:

        笔者接触到的OA系统,接口参数没有统一
        1、有的入参使用XML方式,有的入参是JSON字符串,
        2、有的有命名空间,有的没有命名空间
        3、有的返回了JSON字符串,有的返回了XML~
        em....(@#%¥#@%#¥%),为了适配这个老东西,下面展出两种方式的调用代码,。
        

        1.使用Hutool工具包调用:

           业务流程是web端调用我的HTTP接口,然后HTTP接口去调用OA的webservice接口拿数据。
           但是webservice接口返回的参数是XML形式的,所以需要使用工具转成JSON,返回给web浏览器。
           笔者使用的工具是hutool下的SoapClient工具包(Hutool还是挺强大)调用webservice接口,jdom、fastjson做XML转换JSON。
        

        POM如下:

        Springboot 项目 调用webservice接口
        (图片来源网络,侵删)
           		
           		
           		
                
                    com.alibaba
                    fastjson
                    //版本自己找哈~
                
                
                
                    cn.hutool
                    hutool-all
                    5.8.20
                
                
                
                
                    org.jdom
                    jdom
                    2.0.2
                
                
            
        

        Controller忽略不展示了

        Service 实现 如下:

        import com.alibaba.fastjson.JSONArray;
        import com.alibaba.fastjson.JSONObject;
        import cn.hutool.http.webservice.SoapClient;
        import javax.xml.namespace.QName;
        import java.util.*;
        @Service
        @Slf4j
        public class OAServiceImpl implements OAService {
         //@Override
         public JSONObject getGWList(OAReqVO reqVO) {
                Map map = new HashMap();
                //笔者系统中的业务参数,对方需要用到的json参数
                map.put("参数3-1","1");
                map.put("参数3-2","2");
                map.put("参数3-3","3");
                Map mapReq = new HashMap();
                mapReq.put("content",map);
                JSONObject writeContent = new JSONObject(mapReq);
                log.info("接口入参:"+writeContent);
                String result = null;
                try {
                	//对方接口地址
                    SoapClient soapClient = SoapClient.create("http://xxx.xxx.xxx/xxxController/init.done")
                            // 对端 提供的方法名,命名空间(如果有命名空间记得找他们要)
                            .setMethod("方法名", "http://xxx.xxx.com.cn")
                            // 设置参数名称及参数值
                            .setParam("token", "token-123123123")
                            .setParam("systemId","系统标识")
                            //上面中的writeContent,对端业务系统使用
                            .setParam("content",writeContent.toString())
                            // 设置超时时间
                            .setConnectionTimeout(15000)
                            .setReadTimeout(15000)
                            .timeout(15000);
                    // 还有其他可以配置,根据自己的需求配置
                    result = soapClient.send();
                    log.info("OA返回信息={}", result);
                    // 返回的是xml形式的,所以在此处转一下json
                    JSONObject jsonObject = XmlToJsonUtil.xml2Json(result);
                    //拿到数据 下面做自己的业务处理,笔者就直接return了。
                    log.info("OA返回信息JSON转换={}", jsonObject);
                    return jsonObject ;
                }catch (Exception e) {
                    log.error("接口调用失败:"+e.getMessage(),e);
                     JSONObject jsonObject = new JSONObject();
                	 jsonObject.put("code","1002");
                	 jsonObject.put("mesText","");
               		 jsonObject.put("mesType","0");
                	 jsonObject.put("mes","获取失败");
                     return jsonObject;
                }
            }
         }
        

        XmlToJsonUtil:

        package cn.com.XXXX.utils;
        import com.alibaba.fastjson.JSONObject;
        import org.apache.commons.lang3.StringUtils;
        import org.jdom2.Document;
        import org.jdom2.Element;
        import org.jdom2.JDOMException;
        import org.jdom2.input.SAXBuilder;
        import org.springframework.stereotype.Component;
        import java.io.ByteArrayInputStream;
        import java.io.IOException;
        import java.io.InputStream;
        import java.nio.charset.StandardCharsets;
        import java.util.LinkedList;
        import java.util.List;
        @Component
        public class XmlToJsonUtil {
            public static JSONObject xml2Json(String xmlStr) throws JDOMException, IOException {
                if (StringUtils.isBlank(xmlStr)) {
                    return null;
                }
                xmlStr = xmlStr.replaceAll("\n", "");
                byte[] xml = xmlStr.getBytes(StandardCharsets.UTF_8);
                JSONObject json = new JSONObject();
                InputStream is = new ByteArrayInputStream(xml);
                SAXBuilder sb = new SAXBuilder();
                Document doc = sb.build(is);
                Element root = doc.getRootElement();
                json.put(root.getName(), iterateElement(root));
                return json;
            }
            private static JSONObject iterateElement(Element element) {
                List node = element.getChildren();
                JSONObject obj = new JSONObject();
                List list = null;
                for (Element child : node) {
                    list = new LinkedList();
                    String text = child.getTextTrim();
                    if (StringUtils.isBlank(text)) {
                        if (child.getChildren().size() == 0) {
                            continue;
                        }
                        if (obj.containsKey(child.getName())) {
                            list = (List) obj.get(child.getName());
                        }
                        list.add(iterateElement(child)); //遍历child的子节点
                        obj.put(child.getName(), list);
                    } else {
                        if (obj.containsKey(child.getName())) {
                            Object value = obj.get(child.getName());
                            try {
                                list = (List) value;
                            } catch (ClassCastException e) {
                                list.add(value);
                            }
                        }
                        if (child.getChildren().size() == 0) { //child无子节点时直接设置text
                            obj.put(child.getName(), text);
                        } else {
                            list.add(text);
                            obj.put(child.getName(), list);
                        }
                    }
                }
                return obj;
            }
        }
        

        如此一番操作就能调用了~

        2.使用cxf工具包调用:

        注:下面这个接口没用使用命名空间
        

        废话不多说,直接上代码

        pom依赖:

            
                
                    dom4j
                    dom4j
                    1.6.1
                
                
                    com.google.code.gson
                    gson
                    2.9.0
                
                  
                
                    org.apache.cxf
                    cxf-spring-boot-starter-jaxws
                    3.2.1
                
                
                    org.apache.cxf
                    cxf-rt-transports-http
                    3.2.1
                
        

        controller忽略

        service实现如下:

        import org.apache.cxf.endpoint.Client;
        import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
        import org.apache.cxf.transport.http.HTTPConduit;
        import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
        //如需复制,import 与代码 请分开复制~
         @Override
            public String webserviceTest() {
                //封装xml报文体,可以自己拼装例如:
                //请求参数
                String req = 
                        "\n" +
                        "  \n" +
                        "    123\n" +
                        "    123\n" +
                        "  \n" +
                        "";
                //或者编辑好JSON,使用下面的JsonToXml 的工具类进行xml转换
                //创建请求实例
                JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
                try{
                    Client client = factory.createClient("http://xxx.xxx.com/sdadsa");
                    HTTPConduit conduit = (HTTPConduit) client.getConduit();
                    HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
                    httpClientPolicy.setConnectionTimeout(10000);  //连接超时
                    httpClientPolicy.setAllowChunking(false);    //取消块编码
                    httpClientPolicy.setReceiveTimeout(10000);     //响应超时
                    conduit.setClient(httpClientPolicy);
                    Object[] objects = new Object[0];
                    //请求接口
                    objects = client.invoke(loginMethod, req);
                    log.info("返回数据= {}" , objects[0].toString() );
                    //做自己的业务逻辑处理,如果返回的是XML,需要转JSON,可以使用上面的XML转JSON的工具类进行操作。笔者直接return了
          			return objects[0].toString();
                }catch (Exception e){
                    log.error("系统交互异常:{}",e.getMessage(),e);
                    return "交互异常,请联系管理员";
                }
            }
        

        json转xml工具类:

        package cn.com.XXXX.utils;
        import com.google.gson.JsonArray;
        import com.google.gson.JsonElement;
        import com.google.gson.JsonObject;
        import com.google.gson.JsonParser;
        import org.dom4j.Element;
        import org.springframework.stereotype.Component;
        import java.util.Map;
        import java.util.Set;
        @Component
        public class JsonToXml {
            /**
             * 将json字符串转换成xml
             *
             * @param json
             *            json字符串
             * @param parentElement
             *            xml根节点
             * @throws Exception
             */
            public static Element jsonToXml(String json, Element parentElement) throws Exception {
                JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
                Element ee = toXml(jsonObject, parentElement, null);
                return ee;
            }
            /**
             * 将json字符串转换成xml
             *
             * @param jsonElement
             *            待解析json对象元素
             * @param parentElement
             *            上一层xml的dom对象
             * @param name
             *            父节点
             */
            public static Element toXml(JsonElement jsonElement, Element parentElement, String name) {
                if (jsonElement instanceof JsonArray) {
                    //是json数据,需继续解析
                    JsonArray sonJsonArray = (JsonArray)jsonElement;
                    for (int i = 0; i  
        

        问题及方案

        谈谈遇到的问题,
        1:跟OA交互时候,传参没有驼峰,OA系统收不到这个没有驼峰的参数
        解决方案:给字段进行驼峰。
        2:xml转JSON后会有多个层级,取最里层的参数比较麻烦
        解决方案:使用JSONPath.read()方法,能快速去除最里层的参数,注意判空。
        如:String respDesc = JSONPath.read(SessionHeader, "$.Response[:1].RspDesc[0]").toString();
        3:其他问题
          切记 一定要把所有接口交互前想到的问题都问清楚,最好双方能出个文档,评审完文档后进行开发~,
          多沟通才是解决问题的重要方式。
        

        以上就是笔者跟老系统交互的两种方式,欢迎各位讨论交流~

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]