使用Http(s)直接调用WebService

在权衡了麻烦程度以及适用性之后,本人使用http直接发送xml报文直接调用WebService。

声明:本文前部分内容介绍HTTP(S)调用WebService的简略用法(此用法可能不适用于所有的情况),本文
           后面会给出适用于所有情况的HTTP(S)调用WebService的万精油用法。


准备工作:先提供一个WebService

第一步:创建一个java项目(这里不是重点,创建普通java项目就行),并创建几个java文件

使用Http(s)直接调用WebService_第1张图片

说明:

          User被创建用于辅助演示的;

          MyWebService是用来编写提供的WebService服务的;

          MyServer中是用来发布MyWebService的。

User:

使用Http(s)直接调用WebService_第2张图片

MyWebService:

使用Http(s)直接调用WebService_第3张图片

MyServer:

使用Http(s)直接调用WebService_第4张图片

第二步:检查一下发布是否成功,运行MyServer主函数,并访问http://127.0.0.1:9527/webservice/test?wsdl

使用Http(s)直接调用WebService_第5张图片

说明发布WebService成功。

第三步:下载SoapUI工具,并根据http://127.0.0.1:9527/webservice/test?wsdl获得xml模板

使用样例:

使用Http(s)直接调用WebService_第6张图片

使用Http(s)直接调用WebService_第7张图片

使用Http(s)直接调用WebService_第8张图片

使用Http(s)直接调用WebService_第9张图片

可见SoapUI只需一分钟即可初步简单使用,上手并不难。


使用Http调用WebService

第一步:创建一个项目,并在pom.xml中引入依赖

使用Http(s)直接调用WebService_第10张图片

pom.xml除了基本的依赖外,还需要



	org.springframework.boot
	spring-boot-starter-web




	org.apache.axis2
	axis2-transport-http
	1.7.8

第二步:使用HTTP调用WebService

给出调用WebService核心逻辑图片版:

使用Http(s)直接调用WebService_第11张图片

给出完整(含HTTP工具类)的文字版:

package com;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.http.client.ClientProtocolException;
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.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;

@RunWith(SpringRunner.class)
@SpringBootTest
public class AbcAxis2DemoApplicationTests {

	@Test
	public void test() throws XMLStreamException, ClientProtocolException, IOException {
		// webservice的wsdl地址
		final String wsdlURL = "http://127.0.0.1:9527/webservice/test?wsdl";
		// 设置编码。(因为是直接传的xml,所以我们设置为text/xml;charset=utf8)
		final String contentType = "text/xml;charset=utf8";
		
	    /// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
		String name = "邓沙利文";
		Integer age = 24;
		String motto = "一杆清台!";
		StringBuffer xMLcontent = new StringBuffer("");
		xMLcontent.append("\n");
		xMLcontent.append("   \n");
		xMLcontent.append("   \n");
		xMLcontent.append("      \n");
		xMLcontent.append("         \n");
		xMLcontent.append("         " + name + "\n");
		xMLcontent.append("         \n");
		xMLcontent.append("         " + age + "\n");
		xMLcontent.append("         \n");
		xMLcontent.append("         " + motto + "\n");
		xMLcontent.append("      \n");
		xMLcontent.append("   \n");
		xMLcontent.append("");

		// 调用工具类方法发送http请求
		String responseXML = HttpSendUtil.doHttpPostByHttpClient(wsdlURL,contentType, xMLcontent.toString());
		// 当然我们也可以调用这个工具类方法发送http请求
		// String responseXML = HttpSendUtil.doHttpPostByRestTemplate(wsdlURL, contentType, xMLcontent.toString());
		
		// 利用axis2的OMElement,将xml数据转换为OMElement
		OMElement omElement = OMXMLBuilderFactory
				.createOMBuilder(new ByteArrayInputStream(responseXML.getBytes()), "utf-8").getDocumentElement();
		
		// 根据responseXML的数据样式,定位到对应element,然后获得其childElements,遍历
		Iterator it = omElement.getFirstElement().getFirstElement().getFirstElement().getChildElements();
		while (it.hasNext()) {
			OMElement element = it.next();
			System.out.println("属性名:" + element.getLocalName() + "\t属性值:" + element.getText());
		}

	}
}

/**
 * HTTP工具类
 *
 * @author JustryDeng
 * @DATE 2018年9月22日 下午10:29:08
 */
class HttpSendUtil {

	/**
	 * 使用apache的HttpClient发送http
	 *
	 * @param wsdlURL
	 *            请求URL
	 * @param contentType
	 *            如:application/json;charset=utf8
	 * @param content
	 *            数据内容
	 * @DATE 2018年9月22日 下午10:29:17
	 */
	static String doHttpPostByHttpClient(final String wsdlURL, final String contentType, final String content)
			throws ClientProtocolException, IOException {
		// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
		CloseableHttpClient httpClient = HttpClientBuilder.create().build();
		// 创建Post请求
		HttpPost httpPost = new HttpPost(wsdlURL);
		StringEntity entity = new StringEntity(content.toString(), "UTF-8");
		// 将数据放入entity中
		httpPost.setEntity(entity);
		httpPost.setHeader("Content-Type", contentType);
		// 响应模型
		CloseableHttpResponse response = null;
		String result = null;
		try {
			// 由客户端执行(发送)Post请求
			response = httpClient.execute(httpPost);
			// 从响应模型中获取响应实体
			// 注意:和doHttpPostByRestTemplate方法用的不是同一个HttpEntity
			org.apache.http.HttpEntity responseEntity = response.getEntity();
			System.out.println("响应ContentType为:" + responseEntity.getContentType());
			System.out.println("响应状态为:" + response.getStatusLine());
			if (responseEntity != null) {
				result = EntityUtils.toString(responseEntity);
				System.out.println("响应内容为:" + result);
			}
		} finally {
			// 释放资源
			if (httpClient != null) {
				httpClient.close();
			}
			if (response != null) {
				response.close();
			}
		}
		return result;
	}

	/**
	 * 使用springframework的RestTemplate发送http
	 *
	 * @param wsdlURL
	 *            请求URL
	 * @param contentType
	 *            如:application/json;charset=utf8
	 * @param content
	 *            数据内容
	 * @DATE 2018年9月22日 下午10:30:48
	 */
	static String doHttpPostByRestTemplate(final String wsdlURL, final String contentType, final String content) {
		// http使用无参构造;https需要使用有参构造
		RestTemplate restTemplate = new RestTemplate();
		// 解决中文乱码
		List> converterList = restTemplate.getMessageConverters();
		converterList.remove(1);
		HttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
		converterList.add(1, converter);
		restTemplate.setMessageConverters(converterList);
		// 设置Content-Type
		HttpHeaders headers = new HttpHeaders();
		headers.remove("Content-Type");
		headers.add("Content-Type", contentType);
		// 数据信息封装
		// 注意:和doHttpPostByHttpClient方法用的不是同一个HttpEntity
		org.springframework.http.HttpEntity formEntity = new org.springframework.http.HttpEntity(
				content, headers);
		String result = restTemplate.postForObject(wsdlURL, formEntity, String.class);
		return result;
	}
}

测试一下:

运行测试类,控制台输出内容为(为了看起来明明晰,本人将输出内容粘贴出来整理了一下):

使用Http(s)直接调用WebService_第12张图片

提示:代码中omElement.getFirstElement()获得的即为body节点。

说明:本人之所以使用HTTP调用WebService时,还引入了axis2的OMElement,主要是看中了
            XML、OMElement、Java对象之间的相互转换功能,由于本人最近较忙,所以此三者的转换,留待后面有时间再
            学习分享


HTTP(S)调用WebService万精油用法:

注:此用法至少需要先看上面的 准备工作 的 第二步、第三步(推荐:上面的内容全看)

注:推荐直接使用此方式实现HTTP(S)调用WebService

在上面的方式中,我们发送HTTP时,只有请求体的内容是从SoapUI里面复制出来的;而请求头域中的内容,却是凭着大概原理自己写的:

使用Http(s)直接调用WebService_第13张图片

注:上图中绿色的为请求体,红圈圈起来的表示是以XML方式浏览的。

万精油方式则是请求URL地址请求体内容请求头域内容等,均按照SoapUI来写,这样一来,只要SoapUI能测试访问的,那么HTTP(S)就一定能正确的进行访问,如图所示:

使用Http(s)直接调用WebService_第14张图片

提示:必须先在XML一栏中,先进行一次SoapUI访问后,再点击Raw一栏,才会有信息。

注:上图中绿色的为请求体,黄色的为请求头,蓝色的为访问URL,红圈圈起来的表示是以Raw方式浏览的。

 

^_^ 代码托管链接
           https://github.com/JustryDeng/PublicRepository

^_^ 如有不当之处,欢迎指正

^_^ 本文已经被收录进《程序员成长笔记(五)》,笔者JustryDeng

你可能感兴趣的:(HTTP/HTTPS,WebService,WebService,Http工具类,Java)