【项目问题解决】Java发起Soap请求

在这里插入图片描述

目录


文章所属专区 超链接


1.前言

SOAP请求(Simple Object Access Protocol,简单对象访问协议)是HTTP POST的一个专用版本,遵循一种特殊的XML消息格式,Content-type设置为:text/xml ,任何数据都可以XML化。

SOAP:简单对象访问协议。SOAP是一种轻量的,简单的,基于XML的协议,它被设计成在web上交换结构化的和固化的信息。SOAP可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。

2.请求报文格式

在使用SOAP请求时,我们需要明确请求的Method,即要请求的Web服务所提供的方法名,不同的Web服务API会提供不同的方法名,具体使用时需要根据API文档进行查

2.1不带表头的请求格式

 <?xml version="1.0" encoding="UTF-8"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com">
   <SOAP-ENV:Body>
      <ns1:getWeather>
         <ns1:city>Beijing</ns1:city>
      </ns1:getWeather>
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

2.2带表头的请求格式

 <?xml version="1.0" encoding="UTF-8"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.com">
   <SOAP-ENV:Header>
      <ns1:Auth>
         <ns1:Username>testUser</ns1:Username>
         <ns1:Password>testPassword</ns1:Password>
      </ns1:Auth>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns1:getUserData>
         <ns1:userId>12345</ns1:userId>
      </ns1:getUserData>
   </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

3 请求代码实例

   /**
     * 根据soap请求获取url
     * @param token
     * @param appKey
     * @param xmlStrSM4
     * @return
     */
    public JSONObject getUrlBySoap(String token,String appKey,String xmlStrSM4) {
        StringBuilder stringBuilder = new StringBuilder();
        JSONObject result = new JSONObject();
        OutputStream out = null;
        BufferedReader in = null;
        //需要传的参数
        //String[] pointNames = {"chang","tiao","rap","basketball"};
        //拼接请求报文的方法
        String soap =  buildXML(token,appKey,xmlStrSM4).toString();
        try {
            URL url = new URL(evaluation_url);
            URLConnection connection = url.openConnection();
            HttpURLConnection httpConn = (HttpURLConnection) connection;
            byte[] soapBytes = soap.getBytes("ISO-8859-1");
            httpConn.setRequestProperty( "Content-Length",String.valueOf( soapBytes.length ) );
            httpConn.setRequestProperty("Content-Type","text/xml; charset=utf-8");
            httpConn.setRequestProperty("soapaction","http://tempuri.org/WcfDataProxy/GetPoints");//重点中的重点,不加就500。注意:soapaction对应的值不固定,具体值看你的请求。
            httpConn.setRequestMethod( "POST" );
            httpConn.setDoOutput(true);
            httpConn.setDoInput(true);
            
            out = httpConn.getOutputStream();
            out.write(soapBytes);
            int responseCode = httpConn.getResponseCode();
            if(responseCode == 200){
                in = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "utf-8"));

                //把响应回来的报文拼接为字符串
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    stringBuilder.append(inputLine);
                }
                out.close();
                in.close();

                //报文转成doc对象
                Document doc = DocumentHelper.parseText(stringBuilder.toString());
                //获取根元素,准备递归解析这个XML树
                Element root = doc.getRootElement();
                //获取叶子节点的方法
                String leafNode = "";
                leafNode = getCode(root);
                if(leafNode != null && leafNode.contains("data")){
                    String resultUrl = getUrlByDom4j(leafNode);
                    result.put("url",resultUrl);
                }else{
                    String message = getMessage(leafNode);
                    result.put("message",message);
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }  catch (ParseException e) {
            e.printStackTrace();
        } catch (org.dom4j.DocumentException e) {
            e.printStackTrace();
        } finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

3.1解析Soap返回的XML,提取需要的元素

    /**
     * 找到soap的xml报文的叶子节点的数据
     * @param root
     */
    public String getCode(Element root) throws DocumentException {
        String result = "";
        if (root.elements() != null) {

            //如果当前跟节点有子节点,找到子节点
            List<Element> list = root.elements();
            //遍历每个节点
            for (Element e : list) {
                if (e.elements().size() > 0) {
                    //当前节点不为空的话,递归遍历子节点;
                    result=getCode(e);
                    if(result != null && result != ""){
                        return result;
                    }
                }
                if (e.elements().size() == 0) {
                    result = e.getTextTrim();
                    return result;
                }
            }
        }else{
            return root.getTextTrim();
        } 
        return result;
    }

3.2解析Soap返回的XML,提取需要的元素方式而

解析的字符串:

<?xml version="1.0" encoding="GB2312"?><Case><code>500</code><message>受理部门编码为:001003008002013,未查询到部门信息,请联系管理员</message></Case>
/**
     * 解析msg字符串中的message
     * @param msg
     * @return
     */
    public String getMessage(String msg){
        String result = "";
        try {
            
            // 创建DocumentBuilder对象
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

            // 将XML字符串转换为输入流
            InputStream is = new ByteArrayInputStream(msg.getBytes("GB2312"));

            // 解析XML
            org.w3c.dom.Document doc = builder.parse(is);

            // 获取根节点
            org.w3c.dom.Element root = doc.getDocumentElement();

            // 在这里插入代码片遍历解析后的XML
            NodeList itemList = root.getElementsByTagName("message");
            for (int i = 0; i < itemList.getLength(); i++) {
                Node item = itemList.item(i);
                result = item.getTextContent();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

4.请求参数加密参考

      //参数xmlStr需要使用私钥加密
        StringBuffer xmlStr = new StringBuffer();
        //组装请求参数
        xmlStr = getXmlStr(apasinfoDto,contactMobile,evaluationChannel,urlType,evaluateType,networkType,customFields);
        //对密钥进行MD5
        String md5 = Md5Util.getMD5(private_key);
        //sm4对数据加密
        String xmlStrSM4=new SM4().encode(xmlStr.toString(),md5 );
        //对接方传递公钥给我方,我方会根据对接方的公钥查询出密钥对数据解密
        xmlStrSM4=xmlStrSM4.replaceAll("[\\n\\r]", "");
        JSONObject jsonObject = getUrlBySoap( token, appKey, xmlStrSM4);

5.SOAP请求返回报文格式参考

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">  
  <soap:Body> 
    <ns1:doServiceResponse xmlns:ns1="http://cn.gov.chinatax.gt3nf.nfzcpt.service/">  
      <return><![CDATA[<taxML><service><sid>SID值</sid><channelType>10</channelType><version>1.0</version><tranSeq>UUID</tranSeq><tranReqDate>20171204</tranReqDate></service><bizContent><bizResult><head><rtnCode>0</rtnCode><rtnMsg><code>000</code><message>处理成功</message><reason></reason></rtnMsg></head><body>PFJFU1BPTlNFX0NPT1k+(BASE64加密后的数据)</body></bizResult></bizContent><returnState><returnCode>00000</returnCode><returnMessage>Success!</returnMessage></returnState></taxML>]]></return> 
    </ns1:doServiceResponse> 
  </soap:Body> 
</soap:Envelope>


6.另一方法发起SOAP请求

// 导入所需的类
import javax.xml.soap.*;

public class SOAPClient {
    public static void main(String[] args) {
        try {
            // 创建SOAP连接和消息工厂
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();
            MessageFactory messageFactory = MessageFactory.newInstance();

            // 创建SOAP消息
            SOAPMessage soapMessage = messageFactory.createMessage();

            // 创建SOAP部分
            SOAPPart soapPart = soapMessage.getSOAPPart();

            // 创建SOAP信封和主体
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();

            // 添加SOAP操作和参数
            QName operation = new QName("http://example.com/namespace", "OperationName");
            SOAPBodyElement bodyElement = body.addBodyElement(operation);
            bodyElement.addChildElement("Parameter1").addTextNode("Value1");
            bodyElement.addChildElement("Parameter2").addTextNode("Value2");

            // 设置SOAP消息的URL
            String endpointUrl = "http://example.com/soap-endpoint";
            soapConnection.call(soapMessage, endpointUrl);

            // 处理SOAP响应
            SOAPMessage soapResponse = soapConnection.call(soapMessage, endpointUrl);
            // 解析和处理SOAP响应的数据

            // 关闭连接
            soapConnection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

参考

使用 Postman 发送 SOAP 请求的步骤与方法
ava 发送SOAP请求调用WebService,解析SOAP报文
Java发布webservice应用并发送SOAP请求调用
java soap 请求

给个三连吧 谢谢谢谢谢谢了
在这里插入图片描述

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顶子哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值