后台http请求参数为json

版权所有,转载请注明出处,谢谢!
https://blog.csdn.net/gxkvji/article/details/97966198

1.问题

调用第三方接口,接口要求为:http请求类型,post请求方式,请求头固定参数。

在使用常规的urlConnection请求不到接口,从网上找的使用httpclient解决。接口要求参数为json字符串,并且放在body里,在raw里放入参数json字符串,然后我在请求头里设置content-Type为application/json,但是返回结果就是缺少body。研究了半天,看了源码才解决。原来是发送过去的参数被序列化为表格参数了,并不是字符串。上代码,看了代码就明白了。

2.代码

引入maven依赖:

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

具体代码实现:

/**
     * 向指定 URL 发送POST方法的请求(数据格式为json)
     *
     * @param url 发送请求的 URL
     * @param paramMap 请求参数集合
     * @param paramMap 请求参数,请求参数为json的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, Map<String, Object> paramMap) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);

        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        httpPost.addHeader("Content-Type", "application/json");
        httpPost.addHeader("appid", "avkp4qyu01fki");


        // 封装post请求参数
        JSONObject jsonObject = new JSONObject();
        if (null != paramMap && paramMap.size() > 0) {
            //List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            // 通过map集成entrySet方法获取entity
            Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
            // 循环遍历,获取迭代器
            Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> mapEntry = iterator.next();
                //nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
                jsonObject.put(mapEntry.getKey(),mapEntry.getValue());
            }
            ContentType contentType = ContentType.create("application/json");
            // 为httpPost设置封装好的请求参数
            try {
            	//设置参数的content-type格式
                httpPost.setEntity(new StringEntity(jsonObject.toString(), contentType));
                //此方式参数content-type为application/x-www-form-urlencoded,源码中默认实现的
				//httpPost.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }
public class UrlEncodedFormEntity extends StringEntity {
    public UrlEncodedFormEntity(List<? extends NameValuePair> parameters, String charset) throws UnsupportedEncodingException {
    	//参数content默认为application/x-www-form-urlencoded
        super(URLEncodedUtils.format(parameters, charset != null ? charset : HTTP.DEF_CONTENT_CHARSET.name()), ContentType.create("application/x-www-form-urlencoded", charset));
    }

    public UrlEncodedFormEntity(Iterable<? extends NameValuePair> parameters, Charset charset) {
    	super(URLEncodedUtils.format(parameters, charset != null ? charset : HTTP.DEF_CONTENT_CHARSET), ContentType.create("application/x-www-form-urlencoded", charset));
    }

    public UrlEncodedFormEntity(List<? extends NameValuePair> parameters) throws UnsupportedEncodingException {
        this((Iterable)parameters, (Charset)((Charset)null));
    }

    public UrlEncodedFormEntity(Iterable<? extends NameValuePair> parameters) {
        this((Iterable)parameters, (Charset)null);
    }
}

当时没有想到看源码,一直以为是方法不对,在网上找对应的方法,找了半天发现3.1版本的可以设置请求体body,结果找不到jar包。然后才通过debug发现给httpPost设置请求参数时,参数的content-type是application/x-www-form-urlencoded,然后看了UrlEncodedFormEntity 类的源码,从名字上看也是可以看出是表单序列化参数,是StringEntity的一个子类,然后我就看有没有content/json格式的子类实现,发现没有,然后直接使用了StringEntity,可以设置content格式,这样问题就解决了。

现在看一下问题不难,结果搞了大半天没搞定,养成一个看源码的习惯还是很重要的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值