Java動態呼叫Webservice,不生成客戶端,基於soapUI
阿新 • • 發佈:2019-01-05
近日專案一需求,需要實現動態解析Webservice滿足Webservice動態呼叫。參考過CXF、AXIS等非常成熟的相關框架技術,但在使用過程中發現,簡單物件(入參、出參)的時候很好用,當是複雜物件的時候很棘手!當然CXF、AXIS全然滿足,也支援物件,動態引數等,但構造過程是一個很複雜的過程。最後以XML方式去做,參考SOAP-UI,最終寫出了以下工具。
Java基於soapUI解析Webservice,以XML方式呼叫
package com.sonic.platform.soap; /*** * * * * * */ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import org.apache.commons.codec.binary.Base64; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.ParseException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.apache.xmlbeans.XmlException; import com.eviware.soapui.impl.wsdl.WsdlInterface; import com.eviware.soapui.impl.wsdl.WsdlOperation; import com.eviware.soapui.impl.wsdl.WsdlProject; import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter; import com.eviware.soapui.model.iface.Operation; import com.eviware.soapui.support.SoapUIException; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import net.sf.json.xml.XMLSerializer; /** * * @author FishingGo * */ public class ConvertWSDL{ private final static String password_key="soapui.loader.password"; private final static String username_key="soapui.loader.username"; /** * * @return * @throws XmlException * @throws IOException * @throws SoapUIException */ private static WsdlProject init() throws XmlException, IOException, SoapUIException{ //new 會有一個守護程序??? WsdlProject WSDL_PROJECT=new WsdlProject(); return WSDL_PROJECT; } /** * auth * @param userName * @param password * @param auth */ private static void initAuth(String userName,String password,boolean auth){ if(auth){ Preconditions.checkArgument(StringUtils.isNotBlank(userName), "username can not be empty or null"); Preconditions.checkArgument(StringUtils.isNotBlank(password), "password can not be empty or null"); System.setProperty(password_key, password); System.setProperty(username_key, userName); } } /** * 解析WSDL * @param address * @param method * @param userName * @param password * @param auth * @return * @throws ConvertWSDLException */ private final static OperationMethodInfo operationMethodInfo(String address,String method,String userName,String password,boolean auth) throws ConvertWSDLException{ Preconditions.checkArgument(StringUtils.isNotBlank(method), "method can not be empty or null"); List<OperationMethodInfo> infos=convertOperation(address, userName, password, auth); for (OperationMethodInfo operationMethodInfo : infos) { if(method.equals(operationMethodInfo.getOperationName())) return operationMethodInfo; } return null; } public final static OperationMethodInfo operationMethodInfo(String address,String method) throws ConvertWSDLException{ return operationMethodInfo(address, method,null,null,false); } public final static OperationMethodInfo operationMethodInfo(String address,String method,String userName,String password) throws ConvertWSDLException{ return operationMethodInfo(address, method,userName,password,true); } /** * 解析WSDL 返回SOAP協議引數XML * @param address * @param method * @return * @throws ConvertWSDLException */ public final static String soapRequestXML(String address,String method) throws ConvertWSDLException{ OperationMethodInfo operationMethodInfo=operationMethodInfo(address, method); return null==operationMethodInfo?null:operationMethodInfo.getRequestXml(); } public final static String soapRequestXML(String address,String method,String userName,String password) throws ConvertWSDLException{ OperationMethodInfo operationMethodInfo=operationMethodInfo(address, method,userName,password); return null==operationMethodInfo?null:operationMethodInfo.getRequestXml(); } /** * convert WSDL Operation * @param address * @param charset * @param userName * @param password * @param auth * @return * @throws ConvertWSDLException */ private static List<OperationMethodInfo> convertOperation(String address,String userName,String password,boolean auth) throws ConvertWSDLException{ initAuth(userName, password, auth); WsdlInterface wsdlInterface=getWsdlInterface(address); return convertOperation(wsdlInterface); } public final static List<OperationMethodInfo> convertOperation(String address) throws ConvertWSDLException{ return convertOperation(address,null,null,false); } public final static List<OperationMethodInfo> convertOperation(String address,String userName,String password) throws ConvertWSDLException{ return convertOperation(address,userName, password, true); } /** * convert WSDL Operation * @param wsdlInterface * @return */ private static List<OperationMethodInfo> convertOperation(WsdlInterface wsdlInterface) { List<Operation> operationList = wsdlInterface.getOperationList(); return new ArrayList<>(Lists.transform(operationList, action->{ return new OperationMethodInfo((WsdlOperation) action); })); } /** * getWsdlInterface * @param address * @return * @throws ConvertWSDLException */ private static WsdlInterface getWsdlInterface(String address) throws ConvertWSDLException { Preconditions.checkArgument(StringUtils.isNotBlank(address), "address can not be empty or null"); try { WsdlInterface[] wsdls = WsdlImporter.importWsdl(init(), address.endsWith("wsdl")?address:address+"?wsdl"); return wsdls[0]; } catch (XmlException e) { throw new ConvertWSDLException(e); } catch (IOException e) { throw new ConvertWSDLException(e); } catch (SoapUIException e) { throw new ConvertWSDLException(e); } catch (Exception e) { throw new ConvertWSDLException(e); } } final static String charset="UTF-8"; private static final String xmlToJson(String responseXml){ if (responseXml != null && !"".equals(responseXml)) { int beginIndex = responseXml.indexOf("<return>"); int endIndex = responseXml.indexOf("</return>"); responseXml = responseXml.substring(beginIndex, endIndex+9); } return StringUtils.isNotBlank(responseXml)?new XMLSerializer().read(responseXml).toString():null; } /** * * @param address * @param charset * @param requestXml * @throws MalformedURLException * @throws IOException */ @SuppressWarnings("unused") @Deprecated private static String doPostSoap_(String address,String charset,String requestXml) throws MalformedURLException, IOException{ HttpURLConnection httpURLConnection=null; try { httpURLConnection=(HttpURLConnection) new URL(address).openConnection(); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setDoOutput(true); httpURLConnection.setDoInput(true); httpURLConnection.setRequestProperty("Content-Type","text/xml;charset="+charset); OutputStream outputStream=httpURLConnection.getOutputStream(); outputStream.write(requestXml.getBytes(charset)); int responseCode = httpURLConnection.getResponseCode(); StringBuffer stringBuffer=new StringBuffer(); if(HttpStatus.SC_OK==responseCode){ InputStream inputStream=httpURLConnection.getInputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inputStream.read(buffer)) > 0) { stringBuffer.append(new String(buffer, 0, len)); } } return xmlToJson(stringBuffer.toString()); } finally { if(null!=httpURLConnection) httpURLConnection.disconnect(); } } public static String doPostSoap(String address,String requestXml) throws ParseException, IOException{ return doPostSoap(address,requestXml,charset); } public static String doPostSoap(String address,String requestXml,String charset) throws ParseException, IOException{ return doPostSoap(address,charset, requestXml,null,null,null,false); } public static String doPostSoap(String address,String requestXml,String charset,String username,String password) throws ParseException, IOException{ return doPostSoap(address,charset, requestXml,null,username,password,true); } public static String doPostSoap(String address,String requestXml,String username,String password) throws ParseException, IOException{ return doPostSoap(address,requestXml,charset,username,password); } /** * * @param url * @param charset * @param requestXml * @param methodName * @param username * @param password * @param auth * @return * @throws ParseException * @throws IOException */ private static String doPostSoap(String url, String charset, String requestXml, String methodName, String username, String password, boolean auth) throws ParseException, IOException { CloseableHttpClient httpClient = null; try { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClient = httpClientBuilder.build(); HttpPost httpPost = new HttpPost(url); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60 * 1000) .setConnectTimeout(60 * 1000).build(); httpPost.setConfig(requestConfig); httpPost.setHeader("Content-Type", "text/xml;charset=" + charset); //httpPost.setHeader("SOAPAction", methodName); if (auth) httpPost.setHeader("Authorization", authHeader(username, password, charset)); StringEntity data = new StringEntity(requestXml, Charset.forName(charset)); httpPost.setEntity(data); CloseableHttpResponse response = httpClient.execute(httpPost); if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) { HttpEntity httpEntity = response.getEntity(); if (httpEntity != null) { return xmlToJson(EntityUtils.toString(httpEntity, charset)); } } } finally { // 釋放資源 httpClient.close(); } return null; } private static String authHeader(String userName, String password, String charset) { String auth = userName + ":" + password; byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName(charset))); String authHeader = "Basic " + new String(encodedAuth); return authHeader; } }
//new 會有一個守護程序???
WsdlProject WSDL_PROJECT=new WsdlProject();
疑惑點,拜讀soapUI原始碼研究中!
歡迎‘大牛’不吝賜教指正!