您的位置:首页 > 其它

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

2018-01-24 18:29 543 查看


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");

             }

             <
4000
br />
         }

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

例如

soapXml="<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><ns2:putIdentityAuthMesResponse xmlns:ns2=\"<?xml'>http://com.mh.webservice\"><return><?xml
version=\"1.0\" encoding=\"UTF-8\"?><CBECMESSAGE><MESSAGEHEAD><MESSAGEID>9e001895bc7e4864b6c3e98a7220fb77</MESSAGEID><MESSAGETYPE>R002</MESSAGETYPE><SENDERID>HBYKJ</SENDERID><RECEIVERID>YHQY0002</RECEIVERID><SENDTIME>20171213142240</SENDTIME></MESSAGEHEAD><MESSAGEBODY><BILL_NO>2017</BILL_NO><VOYAGE_NO>12017</VOYAGE_NO><MSG_CODE>2</MSG_CODE><MSG_TIME>2017-12-13
14:22:40</MSG_TIME><COMMENTS>sendId不合法;resultXm不合法;</COMMENTS></MESSAGEBODY></CBECMESSAGE></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中,然后根据项目实际需要获取字段值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐