电竞比分网-中国电竞赛事及体育赛事平台

分享

調(diào)用WebService 設(shè)置超時

 一本正經(jīng)地胡鬧 2020-07-17
    最近項目上要調(diào)用其他系統(tǒng)的WebService(Axis搭建),由于接收數(shù)據(jù)較大耗時4分鐘左右,所以要設(shè)置超時時間,而且系統(tǒng)中已有jar包的原因,導(dǎo)致許多方法都不能用,最終用HttpClient。
方法一:使用JaxWsDynamicClientFactory調(diào)用WebService

Java代碼  收藏代碼

  1. public static Object call(String wsdl,String method,String requestStr){  

  2.     JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();  

  3.     Client client = factory.createClient(wsdl);  

  4.     HTTPConduit conduit = (HTTPConduit) client.getConduit();  

  5.     HTTPClientPolicy policy = new HTTPClientPolicy();  

  6.     long timeout = 10 * 60 * 1000;//  

  7.     policy.setConnectionTimeout(timeout);  

  8.     policy.setReceiveTimeout(timeout);  

  9.     conduit.setClient(policy);  

  10.     //動態(tài)invoke方法  

  11.     Object[] os =client.invoke(method,requestStr);  

  12.     return os[0];  

  13.     }  

 
方法二:使用JaxWsProxyFactoryBean調(diào)用WebService
     原理:使用JaxWsProxyFactoryBean類生成本地的代理類。
     首先創(chuàng)建接口,然后通過JaxWsProxyFactoryBean調(diào)用。    

Java代碼  收藏代碼

  1. @WebService  

  2. public interface IDataService {  

  3.     @WebMethod  

  4.     @WebResult  

  5.     String getData(@WebParam String requestData);  

  6. }  

  7. public static String call(String wsdl, String requestStr) {  

  8.     JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();  

  9.     factory.setServiceClass(IDataService.class);  

  10.     factory.setAddress(wsdl);  

  11.     IDataService service = (IDataService) factory.create();  

  12.     // 設(shè)置超時時間  

  13.     org.apache.cxf.endpoint.Client proxy = ClientProxy.getClient(service);  

  14.     HTTPConduit conduit = (HTTPConduit) proxy.getConduit();  

  15.     HTTPClientPolicy policy = new HTTPClientPolicy();  

  16.     long timeout = 10 * 60 * 1000;//  

  17.     policy.setConnectionTimeout(timeout);  

  18.     policy.setReceiveTimeout(timeout);  

  19.     conduit.setClient(policy);  

  20.     // 發(fā)出請求  

  21.     return service.getData(requestStr);  

  22. }  

 
方法三:使用wsimport命令構(gòu)建WebService客戶端
       首先使用wsimport命令構(gòu)建客戶端,然后用下面的方法調(diào)用。

Java代碼  收藏代碼

  1. public static String call(String requestData) {  

  2.     // 構(gòu)建的客戶端代碼  

  3.     IDataService_Service factory = new IDataService_Service();  

  4.     IDataService service = factory.getDataSharedWebService();  

  5.     long timeout = 30 * 60 * 1000;// 30分鐘  

  6.     // 設(shè)置超時時間  

  7.     // 當(dāng)前起作用的配置  

  8.     ((BindingProvider) service).getRequestContext().put("javax.xml.ws.client.connectionTimeout", timeout);  

  9.     ((BindingProvider) service).getRequestContext().put("javax.xml.ws.client.receiveTimeout", timeout);  

  10.     // 網(wǎng)上搜到的其他設(shè)置超時的方法,當(dāng)前項目沒有起作用  

  11.     ((BindingProvider) service).getRequestContext().put("com.sun.xml.ws.connect.timeout", timeout);  

  12.     ((BindingProvider) service).getRequestContext().put("com.sun.xml.ws.request.timeout", timeout);  

  13.     ((BindingProvider) service).getRequestContext().put("com.sun.xml.internal.ws.connect.timeout", timeout);  

  14.     ((BindingProvider) service).getRequestContext().put("com.sun.xml.internal.ws.request.timeout", timeout);  

  15.     ((BindingProvider) service).getRequestContext().put("sun.net.client.defaultConnectTimeout", timeout);  

  16.     ((BindingProvider) service).getRequestContext().put("sun.net.client.defaultReadTimeout", timeout);  

  17.     try {  

  18.         // 調(diào)用WebService  

  19.         return service.getData(requestData);  

  20.     } catch (Exception e) {  

  21.         log.error(e.getMessage());  

  22.     }  

  23.     return null;  

  24. }  

     也可以用cxf的wsdl2java命令構(gòu)建客戶端,調(diào)用方式一樣,但是如何設(shè)置超時時間沒有試。
 
方法四:使用HttpClient調(diào)用WebService
      使用commons-httpclient-3.1,依賴jar包(commons-codec.jar、commons-logging.jar)。

Java代碼  收藏代碼

  1. public String call(String wsdl, String requestData) {  

  2.     try {  

  3.         // requestData可以直接用soapui中請求的數(shù)據(jù),注意<![CDATA[]]>的使用  

  4.         PostMethod postMethod = new PostMethod(wsdl);  

  5.         byte[] b = requestData.getBytes("UTF-8");  

  6.         InputStream in = new ByteArrayInputStream(b, 0, b.length);  

  7.         RequestEntity re = new InputStreamRequestEntity(in,  

  8.                 "text/xml; charset=utf-8");  

  9.         postMethod.setRequestEntity(re);  

  10.         // 設(shè)置header SOAPAction,不設(shè)置的話,會報異常:no SOAPAction  

  11.         // header,但是SOAPAction的好像任意值都可以  

  12.         String soapAction = "XX";  

  13.         postMethod.setRequestHeader("SOAPAction", soapAction);  

  14.         HttpClient client = new HttpClient();  

  15.         // 設(shè)置超時(不知道默認(rèn)是多久,沒有設(shè)置的時候,也沒有報錯,設(shè)置下保險些)  

  16.         int timeout = 10 * 60 * 1000;  

  17.         client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);  

  18.         client.getHttpConnectionManager().getParams().setSoTimeout(timeout);  

  19.         //  

  20.         int status = client.executeMethod(postMethod);  

  21.         if (status == 200) {// 成功  

  22.             InputStream is = postMethod.getResponseBodyAsStream();  

  23.             /** 

  24.              * 獲取的結(jié)果可以參考用soapui調(diào)用時的返回值, 

  25.              * 如果約定的返回值是XML,并不會像soapui一樣把xml用<![CDATA[]]>包含起來,要注意解析的方法, 

  26.              * 不知道soapui如何處理的,暫時沒時間研究。 

  27.              */  

  28.             return getResponseXML(is);  

  29.         } else {  

  30.             log.error("調(diào)用Webservice出錯;錯誤代碼為:" + status);  

  31.         }  

  32.     } catch (Exception e) {  

  33.         log.error(e.getMessage());  

  34.     }  

  35.     return null;  

  36. }  

  37. public String getResponseXML(InputStream response) throws Exception {  

  38.     // 根據(jù)具體的返回值寫的解析  

  39.     SAXReader reader = new SAXReader();  

  40.     Document document = reader.read(response);  

  41.     Element root = document.getRootElement();  

  42.     List<Element> childElements = root.elements();  

  43.     for (Element child : childElements) {  

  44.         List<Element> datas = child.selectNodes("getOrgInfoResponse/getOrgInfoResponse");  

  45.         for (Element node : datas) {  

  46.             // 返回約定的xml  

  47.             return node.getText();  

  48.         }  

  49.     }  

  50.     return null;  

  51. }  

  
 總結(jié)下這次遇到的問題:
     1.異常:java.lang.NoSuchFieldError: QUALIFIED
     jar包沖突,刪除jar包(如果可以的話,不能刪除就用HttpClient的方式)。由于項目中第三方工具需要XmlSchema-1.3.x.jar,而cxf-2.5作為客戶端時需要用到xmlschema-core-2.0.1.jar導(dǎo)致前三種方式都不能用。
     2.超時
     由于接收數(shù)據(jù)較大,時間較長,必須設(shè)置超時時間。
     3.異常:javax.xml.bind.UnmarshalException:unexpected element (uri:"", local:"getDataResponse").Expected elements are <{http://xxx/xx}getOrgInfoResponse>
     是namespace的問題,如果用JaxWsProxyFactoryBean的方式,要修改@WebResult中targetNamespace;如果用wsimport命令的方式,需要修改類GetDataResponse中屬性getDataResponse的注解中namespace的值。
     4.異常:no SOAPAction header
  沒有設(shè)置SOAPAction,設(shè)置方式:postMethod.setRequestHeader("SOAPAction", soapAction),soapAction的值是什么好像并不影響結(jié)果。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多