Http方式调用WebService,直接发送soap消息到服务端,然后自己解析服务端返回的结果,这种方式比较简单粗暴,也很好用;soap消息可以通过SoapUI来生成,也很方便。文中所使用到的软件版本:Java 1.8.0_191、Commons-HttpClient 3.1、HttpClient 4.5.10、HttpAsyncClient 4.1.4、Spring 5.1.9、dom4j 2.1.1、jackson 2.9.9、netty-all 4.1.33。
1、准备
参考Java调用WebService方法总结(1)--准备工作
2、调用
2.1、HttpURLConnection方式
该方式利用JDK自身提供的API来调用,不需要额外的JAR包。
public static void httpURLConnection(String soap) { HttpURLConnection connection = null; try { URL url = new URL(urlWsdl); connection = (HttpURLConnection)url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); connection.setRequestProperty("SOAPAction", targetNamespace + "toTraditionalChinese"); connection.connect(); setBytesToOutputStream(connection.getOutputStream(), soap.getBytes()); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { byte[] b = getBytesFromInputStream(connection.getInputStream()); String back = new String(b); System.out.println("httpURLConnection返回soap:" + back); System.out.println("httpURLConnection结果:" + parseResult(back)); } else { System.out.println("httpURLConnection返回状态码:" + connection.getResponseCode()); } } catch (Exception e) { e.printStackTrace(); } finally { connection.disconnect(); } }
2.2、Commons-HttpClient方式
利用Apache Commons项目下的Commons-HttpClient组件调用,目前该组件已被HttpComponents项目所取代。
public static void commonsHttpClient(String soap) { try { org.apache.commons.httpclient.HttpClient httpclient = new org.apache.commons.httpclient.HttpClient(); org.apache.commons.httpclient.methods.PostMethod post = new org.apache.commons.httpclient.methods.PostMethod(urlWsdl); post.addRequestHeader("Content-Type", "text/xml;charset=UTF-8"); post.addRequestHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); org.apache.commons.httpclient.methods.RequestEntity entity = new org.apache.commons.httpclient.methods.InputStreamRequestEntity(new ByteArrayInputStream(soap.getBytes())); post.setRequestEntity(entity); int status = httpclient.executeMethod(post); if (status == org.apache.commons.httpclient.HttpStatus.SC_OK) { String back = post.getResponseBodyAsString(); System.out.println("Commons-HttpClinet返回soap:" + back); System.out.println("commons-HttpClinet返回结果:" + parseResult(back)); } else { System.out.println("commons-HttpClinet返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } }
2.3、HttpClient方式
利用Apache HttpComponents项目下HttpClient组件调用,是Commons-HttpClient组件的升级版。
public static void httpClient(String soap) { try { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(urlWsdl); httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8"); httpPost.setHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(soap.getBytes())); httpPost.setEntity(entity); CloseableHttpResponse response = httpClient.execute(httpPost); if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); String back = EntityUtils.toString(responseEntity); System.out.println("httpClient返回soap:" + back); System.out.println("httpClient返回结果:" + parseResult(back)); } else { System.out.println("HttpClinet返回状态码:" + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); } }
2.4、HttpAsyncClient方式
HttpAsyncClient是HttpClient的异步版本,其用法跟HttpClient类似。
public static void httpAsyncClient(String soap) { CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault(); try { httpClient.start(); HttpPost httpPost = new HttpPost(urlWsdl); httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8"); httpPost.setHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(soap.getBytes())); httpPost.setEntity(entity); Future<HttpResponse> future = httpClient.execute(httpPost, null); HttpResponse response = future.get(); if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); String back = EntityUtils.toString(responseEntity); System.out.println("HttpAsyncClient返回soap:" + back); System.out.println("HttpAsyncClient返回结果:" + parseResult(back)); } else { System.out.println("HttpAsyncClient返回状态码:" + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); } finally { try {httpClient.close();} catch (IOException e) {e.printStackTrace();} } }
2.5、RestTemplate方式
利用Srping的RestTemplate工具调用。
public static void restTemplate(String soap) { RestTemplate template = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add("SOAPAction", targetNamespace + "toTraditionalChinese"); headers.add("Content-Type", "text/xml;charset=UTF-8"); org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<String>(soap, headers); ResponseEntity<String> response = template.postForEntity(urlWsdl, entity, String.class); if (response.getStatusCode() == org.springframework.http.HttpStatus.OK) { String back = template.postForEntity(urlWsdl, entity, String.class).getBody(); System.out.println("restTemplate返回soap:" + back); System.out.println("restTemplate返回结果:" + parseResult(back)); } else { System.out.println("restTemplate返回状态码:" + response.getStatusCode()); } }
2.6、WebClient方式
利用Spring的WebClient工具调用,它是RestTemplate的异步版本。
public static void webClient(String soap) { WebClient webClient = WebClient.create(); ResponseSpec response = webClient.post().uri(urlWsdl) .header("SOAPAction", targetNamespace + "toTraditionalChinese") .header("Content-Type", "text/xml;charset=UTF-8") .syncBody(soap).retrieve(); Mono<String> mono = response.bodyToMono(String.class); System.out.println("webClient返回soap:" + mono.block()); System.out.println("webClient结果:" + parseResult(mono.block())); }
这种方式会用到reactor及nettty相关包:
reactor-core-3.3.0.RELEASE.jar(https://search.maven.org/artifact/io.projectreactor/reactor-core/3.3.0.RELEASE/jar)
reactive-streams-1.0.3.jar(https://search.maven.org/artifact/org.reactivestreams/reactive-streams/1.0.3/jar)
reactor-netty-0.9.1.RELEASE.jar(https://search.maven.org/artifact/io.projectreactor.netty/reactor-netty/0.9.1.RELEASE/jar)
netty-all-4.1.33.Final.jar(https://search.maven.org/artifact/io.netty/netty-all/4.1.33.Final/jar)
2.7、OkHttp方式
利用OkHttp工具调用
public static void okHttp(String soap) {
try {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(soap, MediaType.get("text/xml;charset=UTF-8"));
Request request = new Request.Builder().url(urlWsdl).post(body)
.addHeader("SOAPAction", targetNamespace + "toTraditionalChinese").build();
Response response = client.newCall(request).execute();
String soapReturn = response.body().string();
System.out.println("okHttp返回soap:" + soapReturn);
System.out.println("okHttp结果:" + parseResult(soapReturn));
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
该方式需引入OkHttp的依赖:
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.8.1</version> </dependency>
由于okHttp 4.x用到了kotline,所以需要kotline的环境;在IDEA中可以直接下载kotline的插件。
2.8、小结
几种方式其实差不多,主体思想是一样的就是发送soap报文,就是写法不一样而已。完整例子:
package com.inspur.ws; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Future; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClients; import org.apache.http.util.EntityUtils; import org.dom4j.Document; import org.dom4j.io.SAXReader; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import reactor.core.publisher.Mono; /** * Http方式调用WebService * */ public class Http { private static String urlWsdl = "http://www.webxml.com.cn/WebServices/TraditionalSimplifiedWebService.asmx?wsdl"; private static String targetNamespace = "http://webxml.com.cn/"; /** * HttpURLConnection方式 * @param soap */ public static void httpURLConnection(String soap) { HttpURLConnection connection = null; try { URL url = new URL(urlWsdl); connection = (HttpURLConnection)url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); connection.setRequestProperty("SOAPAction", targetNamespace + "toTraditionalChinese"); connection.connect(); setBytesToOutputStream(connection.getOutputStream(), soap.getBytes()); if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { byte[] b = getBytesFromInputStream(connection.getInputStream()); String back = new String(b); System.out.println("httpURLConnection返回soap:" + back); System.out.println("httpURLConnection结果:" + parseResult(back)); } else { System.out.println("httpURLConnection返回状态码:" + connection.getResponseCode()); } } catch (Exception e) { e.printStackTrace(); } finally { connection.disconnect(); } } /** * Commons-HttpClinet方式 * @param soap */ public static void commonsHttpClient(String soap) { try { org.apache.commons.httpclient.HttpClient httpclient = new org.apache.commons.httpclient.HttpClient(); org.apache.commons.httpclient.methods.PostMethod post = new org.apache.commons.httpclient.methods.PostMethod(urlWsdl); post.addRequestHeader("Content-Type", "text/xml;charset=UTF-8"); post.addRequestHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); org.apache.commons.httpclient.methods.RequestEntity entity = new org.apache.commons.httpclient.methods.InputStreamRequestEntity(new ByteArrayInputStream(soap.getBytes())); post.setRequestEntity(entity); int status = httpclient.executeMethod(post); if (status == org.apache.commons.httpclient.HttpStatus.SC_OK) { String back = post.getResponseBodyAsString(); System.out.println("Commons-HttpClinet返回soap:" + back); System.out.println("commons-HttpClinet返回结果:" + parseResult(back)); } else { System.out.println("commons-HttpClinet返回状态码:" + status); } } catch (Exception e) { e.printStackTrace(); } } /** * HttpClient方式 * @param soap */ public static void httpClient(String soap) { try { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(urlWsdl); httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8"); httpPost.setHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(soap.getBytes())); httpPost.setEntity(entity); CloseableHttpResponse response = httpClient.execute(httpPost); if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); String back = EntityUtils.toString(responseEntity); System.out.println("httpClient返回soap:" + back); System.out.println("httpClient返回结果:" + parseResult(back)); } else { System.out.println("HttpClinet返回状态码:" + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); } } /** * HttpAsyncClient方式 * @param soap */ public static void httpAsyncClient(String soap) { CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault(); try { httpClient.start(); HttpPost httpPost = new HttpPost(urlWsdl); httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8"); httpPost.setHeader("SOAPAction", targetNamespace + "toTraditionalChinese"); InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(soap.getBytes())); httpPost.setEntity(entity); Future<HttpResponse> future = httpClient.execute(httpPost, null); HttpResponse response = future.get(); if (response.getStatusLine().getStatusCode() == org.apache.http.HttpStatus.SC_OK) { HttpEntity responseEntity = response.getEntity(); String back = EntityUtils.toString(responseEntity); System.out.println("HttpAsyncClient返回soap:" + back); System.out.println("HttpAsyncClient返回结果:" + parseResult(back)); } else { System.out.println("HttpAsyncClient返回状态码:" + response.getStatusLine().getStatusCode()); } } catch (Exception e) { e.printStackTrace(); } finally { try {httpClient.close();} catch (IOException e) {e.printStackTrace();} } } /** * RestTemplate方式 * @param soap */ public static void restTemplate(String soap) { RestTemplate template = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.add("SOAPAction", targetNamespace + "toTraditionalChinese"); headers.add("Content-Type", "text/xml;charset=UTF-8"); org.springframework.http.HttpEntity<String> entity = new org.springframework.http.HttpEntity<String>(soap, headers); ResponseEntity<String> response = template.postForEntity(urlWsdl, entity, String.class); if (response.getStatusCode() == org.springframework.http.HttpStatus.OK) { String back = template.postForEntity(urlWsdl, entity, String.class).getBody(); System.out.println("restTemplate返回soap:" + back); System.out.println("restTemplate返回结果:" + parseResult(back)); } else { System.out.println("restTemplate返回状态码:" + response.getStatusCode()); } } /** * WebClient方式 * @param soap */ public static void webClient(String soap) { WebClient webClient = WebClient.create(); ResponseSpec response = webClient.post().uri(urlWsdl) .header("SOAPAction", targetNamespace + "toTraditionalChinese") .header("Content-Type", "text/xml;charset=UTF-8") .syncBody(soap).retrieve(); Mono<String> mono = response.bodyToMono(String.class); System.out.println("webClient返回soap:" + mono.block()); System.out.println("webClient结果:" + parseResult(mono.block())); } /** * OkHttp方式 * @param soap */ public static void okHttp(String soap) { try { OkHttpClient client = new OkHttpClient(); RequestBody body = RequestBody.create(soap, MediaType.get("text/xml;charset=UTF-8")); Request request = new Request.Builder().url(urlWsdl).post(body) .addHeader("SOAPAction", targetNamespace + "toTraditionalChinese").build(); Response response = client.newCall(request).execute(); String soapReturn = response.body().string(); System.out.println("okHttp返回soap:" + soapReturn); System.out.println("okHttp结果:" + parseResult(soapReturn)); response.close(); } catch (IOException e) { e.printStackTrace(); } } /** * 从输入流获取数据 * @param in * @return * @throws IOException */ private static byte[] getBytesFromInputStream(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int len; while ((len = in.read(b)) != -1) { baos.write(b, 0, len); } byte[] bytes = baos.toByteArray(); return bytes; } /** * 向输入流发送数据 * @param out * @param bytes * @throws IOException */ private static void setBytesToOutputStream(OutputStream out, byte[] bytes) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); byte[] b = new byte[1024]; int len; while ((len = bais.read(b)) != -1) { out.write(b, 0, len); } out.flush(); } /** * 解析结果 * @param s * @return */ private static String parseResult(String s) { String result = ""; try { Reader file = new StringReader(s); SAXReader reader = new SAXReader(); Map<String, String> map = new HashMap<String, String>(); map.put("ns", "http://webxml.com.cn/"); reader.getDocumentFactory().setXPathNamespaceURIs(map); Document dc = reader.read(file); result = dc.selectSingleNode("//ns:toTraditionalChineseResult").getText().trim(); } catch (Exception e) { e.printStackTrace(); } return result; } public static void main(String[] args) { String soap11 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webxml.com.cn/\">" + "<soapenv:Header/>" + "<soapenv:Body>" + "<web:toTraditionalChinese>" + "<web:sText>小学</web:sText>" + "</web:toTraditionalChinese>" + "</soapenv:Body>" + "</soapenv:Envelope>"; String soap12 = "<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:web=\"http://webxml.com.cn/\">" + "<soapenv:Header/>" + "<soapenv:Body>" + "<web:toTraditionalChinese>" + "<web:sText>大学</web:sText>" + "</web:toTraditionalChinese>" + "</soapenv:Body>" + "</soapenv:Envelope>"; httpURLConnection(soap11); httpURLConnection(soap12); commonsHttpClient(soap11); commonsHttpClient(soap12); httpClient(soap11); httpClient(soap12); httpAsyncClient(soap11); httpAsyncClient(soap12); restTemplate(soap11); restTemplate(soap12); webClient(soap11); webClient(soap12); okHttp(soap11); okHttp(soap12); } }