如何访问发布的webservice,并解析返回的非正常soap报文

本文介绍如何使用Java的HttpClient类进行WebService通信,处理返回的非标准SOAP报文。通过创建XML请求对象,转换为XML字符串,然后解析返回的非标准SOAP响应,将其转化为JavaBean。



1首先写一个通讯类HttpClient,并不局限于只是webservice通讯

public class HttpClient{

public class HttpClient {
     public  String getPostResponse(String url,String encode, String requestBody) throws Exception
     {
         MultiThreadedHttpConnectionManager manager = new MultiThreadedHttpConnectionManager();
         org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient(manager);
         SetPara(manager);
         PostMethod post = new PostMethod(url);
         post.getParams().setParameter(HttpMethodParams.HTTP_ELEMENT_CHARSET, "utf-8");
         post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,"utf-8");
         ByteArrayRequestEntity entity = new ByteArrayRequestEntity(requestBody.getBytes("utf-8"));
         post.setRequestEntity(entity);
         post.setFollowRedirects(false);
         post.setRequestHeader("Content-Type", "text/xml;charset=utf-8");
         post.setRequestHeader("Content-Length", String.valueOf(entity.getContentLength()));
         String result = null;
         StringBuffer resultBuffer = new StringBuffer();
         try
         {
             client.executeMethod(post);
             BufferedReader in = new BufferedReader(new InputStreamReader(post.getResponseBodyAsStream(), post.getResponseCharSet()));
             String inputLine = null;
             while ((inputLine = in.readLine()) != null)
             {
                 resultBuffer.append(inputLine);
                 resultBuffer.append("\n");
             }
             in.close();
            
             result = ConverterStringCode(resultBuffer.toString() , post.getResponseCharSet(), encode);
         }
         catch (Exception e)
         {
             result = "";
             e.printStackTrace();
         }
         finally
         {
             post.releaseConnection();
         }
         return result;
     }
     // 初始化ConnectionManger的方法
    private static void SetPara(MultiThreadedHttpConnectionManager manager)
     {
         manager.getParams().setConnectionTimeout(100000);   //设置连接超时数,单位:毫秒
        manager.getParams().setSoTimeout(300000);            //设置请求超时数,单位:毫秒
        manager.getParams().setDefaultMaxConnectionsPerHost(5);
         manager.getParams().setMaxTotalConnections(2);
     }
     private static String ConverterStringCode(String source, String srcEncode,String destEncode)
     {
         if (source != null)
         {
             try
             {
                 return new String(source.getBytes(srcEncode), destEncode);
             }
             catch (UnsupportedEncodingException e)
             {
                 // e.printStackTrace();
                 return "";
             }
         } else
         {
             return "";
         }
     }
 }


}

2,然后定义一个请求webservice的报文头,根据实际项目自己定义

@XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "RequestHead")


public class RequestHead{

    @XmlElement(name = "MESSAGEID")
     protected String billNo;
     @XmlElement(name = "MESSAGETYPE",defaultValue="R001")
     protected String messageType;
     @XmlElement(name = "SENDERID")
     protected String senderId;
     @XmlElement(name = "RECEIVERID")
     protected String receiveerId;
     @XmlElement(name = "SENDTIME")
     protected String sendTime;


}

body:

@XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name="RequestBody")


public class RequestBody{

@XmlElement(name = "MESSAGEID")
     protected String billNo;
     @XmlElement(name = "MESSAGETYPE",defaultValue="R001")
     protected String messageType;
     @XmlElement(name = "SENDERID")
     protected String senderId;
     @XmlElement(name = "RECEIVERID")
     protected String receiveerId;
     @XmlElement(name = "SENDTIME")
     protected String sendTime;


}

在把body和head拼成一个整体报文

@XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name="RequestTotal")

@XmlRootElement(name="TEST")


public class RequestTotal{

@XmlElement(name="TESTHEAD")
     private RequestHead reqHead;
     @XmlElement(name="TESTBODY")
     private RequestBody reqBody;


}

3接下来就可以把java对象转化成xml形式的String

    public static  <E> String parseToXml(E rb,Class<?> className) throws Exception {
         Logger logger=Logger.getLogger(XmlUtil.class);
         StringWriter sw=new StringWriter();
         Date date=new Date();
         String sf="yyyyMMddHHmmss";
         try { 
             JAXBContext jc = JAXBContext.newInstance(className); 
             Marshaller ms = jc.createMarshaller();
             ms.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
             ms.setSchema(null);
             RequestTotal rt=new RequestTotal();
             RequestHead rh=new RequestHead();
             rh.setSendTime(DateUtils.dateFormat(date, sf));
             rt.setReqHead(rh);
             rt.setReqBody((RequestBody)rb);
             ms.marshal(rt, sw);
           
         } catch (JAXBException e) {
             throw new Exception(
                     "Unable to create xml from [" + rb.getClass().getName() + "]", e);
         }
         return sw.getBuffer().toString();
        
     }

//注,如果访问的webser需要生成soap形式的报文,简单的一种办法就是直接使用StringBuilder或StringBuffer拼接

4接下来就可以调用第一步写的通讯类访问webservice,返回的String

5接下来就可以解析报文了,如果返回报文是标准的xml报文,那就直接把它转成Doc

        public static void pareseStrToDoc(String sour,WHBean wb) throws ParseException{
             StringReader read=new StringReader(sour);
             InputSource source=new InputSource(read);
             SAXBuilder sb=new SAXBuilder();
             Document doc=null;
             SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
             try {
                 doc=sb.build(source);
                 Element el=doc.getRootElement().getChild("TESTBODY");
                 wb.setWhMsgCode(Integer.valueOf(el.getChild("TEST_CODE").getValue()));
                 wb.setWhMsgTime(sdf.parse(el.getChild("TEST_TIME").getValue()));
                 wb.setWhMsgComments(el.getChild("TEST").getValue());
             } catch (JDOMException | IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
                 wb.setWhComments("pares doc error");
             }
            
         }


比较恶心的就是返回的soap报文不是标准的不能直接用soap解析

例如

soapXml="<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><ns2:putIdentityAuthMesResponse xmlns:ns2=\"&lt;?xml'>http://com.mh.webservice\"><return>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;CBECMESSAGE&gt;&lt;MESSAGEHEAD&gt;&lt;MESSAGEID&gt;9e001895bc7e4864b6c3e98a7220fb77&lt;/MESSAGEID&gt;&lt;MESSAGETYPE&gt;R002&lt;/MESSAGETYPE&gt;&lt;SENDERID&gt;HBYKJ&lt;/SENDERID&gt;&lt;RECEIVERID&gt;YHQY0002&lt;/RECEIVERID&gt;&lt;SENDTIME&gt;20171213142240&lt;/SENDTIME&gt;&lt;/MESSAGEHEAD&gt;&lt;MESSAGEBODY&gt;&lt;BILL_NO&gt;2017&lt;/BILL_NO&gt;&lt;VOYAGE_NO&gt;12017&lt;/VOYAGE_NO&gt;&lt;MSG_CODE&gt;2&lt;/MSG_CODE&gt;&lt;MSG_TIME&gt;2017-12-13 14:22:40&lt;/MSG_TIME&gt;&lt;COMMENTS&gt;sendId不合法;resultXm不合法;&lt;/COMMENTS&gt;&lt;/MESSAGEBODY&gt;&lt;/CBECMESSAGE&gt;</return></ns2:putIdentityAuthMesResponse></soap:Body></soap:Envelope>";

解析该字符创需要先解析出标准的xml报文

          private static SOAPMessage formatSoapString(String soapString) {
               MessageFactory msgFactory;
               try {
                   msgFactory = MessageFactory.newInstance();
                   SOAPMessage reqMsg = msgFactory.createMessage(new MimeHeaders(),
                           new ByteArrayInputStream(soapString.getBytes("UTF-8")));
                  reqMsg.saveChanges();
                   return reqMsg;
               } catch (Exception e) {
                  e.printStackTrace();
                  return null;
              }
          }


        public static void parseSoapToBean(Iterator<SOAPElement> it,WHBean wb) throws ParseException{
             while(it.hasNext()){
                    SOAPElement soapElement=it.next();
                    if("ns2:putIdentityAuthMesResponse".equals(soapElement.getNodeName())){
                     Iterator<SOAPElement> iterator=soapElement.getChildElements();
                     SOAPElement el=null;
                     while(iterator.hasNext()){
                      el=iterator.next();
                      if("return".equals(el.getNodeName())) {
                        
                         pareseStrToDoc(el.getValue(),wb);
                      }
                     }
                    }
                   }
         }

至此就可以把返回的报文解析到javabean中,然后根据项目实际需要获取字段值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值