一、场景需求

项目要求实现在两个服务器之间传输复杂对象,如果使用前端的话ajax可以轻松实现,但是server to server的我还没尝试过,踩了不少雷。话不多说,直接上代码。

思路:将对象转为Json,再通过HttpClient发送。

二、使用步骤

1.Maven

		<dependency>
				<groupId>org.apache.httpcomponents</groupId>
				<artifactId>httpclient</artifactId>
				<version>4.4.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpcore</artifactId>
			<version>4.4.1</version>
		</dependency>

2.工具包

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class HttpClientPostUtil {
    // 接口地址
    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容 重点
            List<NameValuePair> values=new ArrayList<NameValuePair>();
            values.add(new BasicNameValuePair("json", json));
            UrlEncodedFormEntity formEntity=new UrlEncodedFormEntity(values,"UTF-8");
            httpPost.setEntity(formEntity);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return resultString;
    }

}

3.spring接收

    @RequestMapping(params = "accept", method= RequestMethod.POST)
    @ResponseBody
    public String accept(String json) {
    	 System.out.println(json);
    }

注意:接收方法的变量名要与工具包中的NameValuePair对应。

总结&踩雷过程

实现方式看着挺简单的,其实再摸索的这个过程中遇到了不少事情。

比如说最开始想使用公司已经封装好的HttpClient工具包,但是他们好像再写的时候完全没考虑这个场景。无奈之下决定自己封装。

刚开始借鉴的代码,都信誓旦旦的说

method.addHeader("Content-type","application/json; charset=utf-8");
method.setHeader("Accept", "application/json");
method.setEntity(new StringEntity("Json字符串", Charset.forName("UTF-8")));

“这样子设置消息体就没问题”
结果报错URISyntaxException,也不知道是不是我环境有问题。

最后忘了在哪个论坛,看到一条来自2017年的回复,说使用NameValuePair就好了,顿时惊为天人火速去查阅使用方法,折腾一天的问题到此就结束了。

NameValuePair的作用我看了一下,大致就是把请求模拟成表单,就像前端ajax一样往表单里塞数据然后发送。

最后在这里记录一下踩雷过程,希望能帮大家少走弯路。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐