关于Webservice接口对接相关总结

Webservice接口对接

  因为近期处理了很多关于Webservice的接口对接,所以这篇文章是对近期自己的学习做一个简单的总结。

  一:

  对于接口对接,建议首先需要了解一下WSDL文件,以及入参的SOAP报文的阅读,各节点的含义。有时候对接的开发直接扔给你一个wsdl服务文件,或者一串soap报文让你调用,这种情况下,如果不了解如何阅读该文件包括相关节点的含义,就会很尴尬;其次,需要问清楚接口提供方,对方的接口有没有访问认证等,如果没有,可以采用自动生成客户端的形式处理,这种方式不再赘述,网上有一大堆的资料。我这里介绍一下我遇到的需要接口认证的方式,废话少说直接看代码:

//直接AXIS调用
public class WebserviceUtil {    public static String getResult(ServiceInfoDto serviceInfoDto, String jsoninfo)            throws ServiceException, MalformedURLException, RemoteException, SOAPException {        //调用接口//标识Web Service的具体路径        String endpoint = serviceInfoDto.getEndpoint();        String namespace = serviceInfoDto.getNamespace();        String soapaction = serviceInfoDto.getSoapaction();        String username = new String("***");        String password = new String("***");        String HU_SENDR = new String("***");        String HU_JSON = jsoninfo;        String result = "";        try {            // 创建 Service实例            Service service = new Service();            QName qname = new QName(namespace, serviceInfoDto.getLocalPart());            // 通过Service实例创建Call的实例            Call call = (Call) service.createCall();  //为Call设置服务的位置            call.setTargetEndpointAddress(endpoint);            call.setOperationName(qname);            call.setEncodingStyle("UTF-8");            call.setSOAPActionURI(soapaction);            call.setUsername(username);            call.setPassword(password);            call.addParameter(new QName("HU_JSON"),                    org.apache.axis.encoding.XMLType.XSD_STRING,                    javax.xml.rpc.ParameterMode.IN);            call.addParameter(new QName("HU_SENDR"),                    org.apache.axis.encoding.XMLType.XSD_STRING,                    javax.xml.rpc.ParameterMode.IN);            call.setReturnType(XMLType.XSD_STRING);    // 返回值类型:String            Object[] obj = {HU_JSON, HU_SENDR};            result = (String) call.invoke(obj);// 远程调用//            System.out.println("result is " + result);        } catch (Exception e) {            e.printStackTrace();        }        return result;    }}
public class ServiceInfoDto {    private String endpoint;    private String namespace;    private String soapaction;    private String localPart;    public String getEndpoint() {        return endpoint;    }    public void setEndpoint(String endpoint) {        this.endpoint = endpoint;    }    public String getNamespace() {        return namespace;    }    public void setNamespace(String namespace) {        this.namespace = namespace;    }    public String getSoapaction() {        return soapaction;    }    public void setSoapaction(String soapaction) {        this.soapaction = soapaction;    }    public String getLocalPart() {        return localPart;    }    public void setLocalPart(String localPart) {        this.localPart = localPart;    }}
解读一下入参和几个重要的参数:ServiceInfoDto对象:是对相关节点入参的汇总,这里的endpoint,namespace,soapaction,localPart在对方提供的wsdl文件中都可查到;jsoninfo:接口方要求的入参对象(转成json字符串形式入参)String username = new String("***"); 接口方提供的认证登录名(不需要可忽略)String password = new String("***"); 接口方提供的认证登录密码(不需要可忽略)String HU_SENDR = new String("***"); HU_SENDR需要按对方要求的字段名称处理,入参值接口方提供(不需要可忽略);String HU_JSON = jsoninfo;HU_JSON;需要按对方要求的字段名称处理,入参值是前面处理过的json对象;

  二:

第二种对接是拼接SOAP报文入参,并且解析返回的SOAP报文,获取返回信息;这种方式必须要清楚的知道对方入参的soap报文格式,相关节点一定要清晰,拿到对方的报文信息进行拼接即可:soap报文拼接,由于我用到的地方比较多,所以提取的代码块处理
public class SoapAppendXml {    public static StringBuffer soapXml(String arg2,String arg4,String method,String id) {        StringBuffer sendSoapString = new StringBuffer();        sendSoapString.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.**.com/\">");        sendSoapString.append(" <soapenv:Header/>");        sendSoapString.append(" <soapenv:Body>");        sendSoapString.append(" <web:"+method+">");        sendSoapString.append(" <arg0>*</arg0>");        sendSoapString.append(" <arg1>false</arg1>");        sendSoapString.append(" <arg2>"+arg2+"</arg2>");        sendSoapString.append(" <arg3>[]</arg3>");        sendSoapString.append(" <arg4>"+arg4+"</arg4>");        sendSoapString.append(" </web:"+method+">");        sendSoapString.append(" </soapenv:Body>");        sendSoapString.append("</soapenv:Envelope>");        return sendSoapString;    }}

入参可根据实际接口的需要进行修改,各节点可查看接口的soap入参要求,动态处理或者写死都行;由于我的调用服务只有一个,并且有多个方法,所以入参method需要动态处理;

下面是接口调用:

public class SoapUtil {    public static String getWebServiceAndSoap(String url,String isClass,String isMethod,StringBuffer sendSoapString) throws IOException {        String  result = "";        String soap = sendSoapString.toString();        if (soap == null) {            return null;        }        URL soapUrl = new URL(url);        URLConnection conn = soapUrl.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(isClass,isMethod);        OutputStream os = conn.getOutputStream();        OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");        osw.write(soap);        osw.flush();        osw.close();        // 获取webserivce返回的流        InputStream is = conn.getInputStream();if (is!=null) {    byte[] bytes = new byte[0];    bytes = new byte[is.available()];    is.read(bytes);    String str = new String(bytes);    return str;}else {    return null;}    }}
解读一下上面的工具类:
url:是对接服务地址,以"?wsdl"结尾的地址;
isClass:接口类名,在对方提供的wsdl文件中可以查到,我这里的是"LvYunkangWebservice";
isMethod:调用方法名
sendSoapString:拼接好的soap报文

该工具类在实际测试中,发现最终返回的报文,会出现乱码现象,查阅得知,应该是跟InputStream按字节解析有关。所以,对上述工具类进行简单的修改,也就是对返回结果部分做一下修改(标红的部分)
public class SoapUtil {

    public static String getWebServiceAndSoap(String url,String isClass,String isMethod,StringBuffer sendSoapString) throws IOException {        String  result = "";        String soap = sendSoapString.toString();        if (soap == null) {            return null;        }        URL soapUrl = new URL(url);        URLConnection conn = soapUrl.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(isClass,isMethod);        OutputStream os = conn.getOutputStream();        OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8");        osw.write(soap);        osw.flush();        osw.close();        // 获取webserivce返回的流        InputStream is = conn.getInputStream();        if (is != null) {            InputStreamReader isr = new InputStreamReader(is, "UTF-8");            BufferedReader br = new BufferedReader(isr);

            StringBuilder sb = new StringBuilder();            String temp = null;            while(null != (temp = br.readLine())) {                sb.append(temp);            }            result = sb.toString();            is.close();            isr.close();            br.close();        }        return result;    }}

解析返回的报文:

这里先给大家看一下,我的拿到的报文返回示例:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">   <soap:Body>      <ns2:getResultResponse xmlns:ns2="http://webservice.taikang.com/">         <return>            <message>访问成功</message>            <result>true</result>     </return> </ns2:getResultResponse > </soap:Body></soap:Envelope>

按节点分级解析的方式,返回Map即可

public static Map<String,String> XMLtoData(String xml) throws DocumentException {        Map map = new HashMap();        List<Data> dataList = new ArrayList<>();        Document doc = DocumentHelper.parseText(xml);        //获取根元素,准备递归解析这个XML树        Element root = doc.getRootElement();        //获取到data的集合        List<Element> mzList = root.element("Body").element("getResultResponse").elements("return");        //遍历data集合        for (Element e : mzList) {            List<Element> elements = e.elements();            //遍历将元素中的key和value存到map中            for (Element item : elements) {                if (!StringUtils.isEmpty(item.getText())) {                    map.put(item.getName(), item.getText());                }            }        }        return map;    }

注意:
List<Element> mzList = root.element("Body").element("getResultResponse").elements("return");节点可以按需求获取,即:root.element("**").element("**")................elements("**")
上述是两种工具类调用Webservice接口的方式,请多指教!
(0)

相关推荐