Java方式实现Get请求带body传递formdata参数

我正在参加「金石计划」

写在前面

一看到这个标题,我总会在想,get请求,你还要在body里面传递formdata参数?

这究竟是怎样如此反人类的设计呢?能写出这样接口的人,究竟是多么的奇葩?

你要在body里面传递formdata参数,为啥不能用post请求?非得用get请求?

说实话,全网找了很久,也问过gpt了,java中的httpclient能实现get传递body参数的,也就只有在body中传递json字符串的实现,传递formdata的,好像还真的是没有相关实现。

一时之间都不知道怎么解决呀?头都大!!!

看到知乎有一篇文章:HTTP GET 请求可以有 body 吗?

有兴趣的小伙伴,可以去看看。

看到其中有python的一个实现,是这样的:

curl,postman,apifox等工具也是可以:

唯独java的okHttp是这样的:🤣😂

哥们,你倒是实现一下呀,java的相关实现方法!!!

好吧,还是没有相关的说明,头还是有点大喔!!!

httpclient实现get请求body传递json参数

上面说过,全网能找到的基本上都是,get请求body传递json字符串参数了,这里也贴一下相关的实现,如下:

  • 创建HttpGetWithEntity
java 复制代码
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import java.net.URI;

/**
 * http get请求带body内容
 *
 * @author llsydn
 */
public class HttpGetWithEntity extends HttpEntityEnclosingRequestBase {
    private final static String METHOD_NAME = "GET";

    @Override
    public String getMethod() {
        return METHOD_NAME;
    }
    public HttpGetWithEntity() {
        super();
    }
    public HttpGetWithEntity(final String uri) {
        super();
        setURI(URI.create(uri));
    }
}
  • 封装get请求
java 复制代码
/**
 * 执行http请求。
 *
 * @throws Exception
 */
private String sendRequest(String url,Map<String,Object> params) throws Exception {
    String encoding = "UTF-8";
    String param = JSONArray.toJSON(params).toString();
    String body = "";
    //创建httpclient对象
    HttpGetWithEntity httpGetWithEntity = new HttpGetWithEntity(url);
    HttpEntity httpEntity = new StringEntity(param, ContentType.APPLICATION_JSON);
    httpGetWithEntity.setEntity(httpEntity);
    
    //执行请求操作,并拿到结果(同步阻塞)
    CloseableHttpClient client = HttpClientBuilder.create().build();
    CloseableHttpResponse response = client.execute(httpGetWithEntity);
    
    //获取结果实体
    HttpEntity entity = response.getEntity();
    if (entity != null) {
        //按指定编码转换结果实体为String类型
        body = EntityUtils.toString(entity, encoding);
    }
    //释放链接
    response.close();
    return body;
}

好了,以上就是httpclient实现get请求body传递json参数的相关实现。

但是还是没有实现:Java实现Get请求body传递formdata参数!!!

看到了知乎上面的相关说明,有些python工具类,是可以实现get请求body传递formdata参数的;

httpclient是不支持这种方式,那有没有其他工具包的实现方法呢?

找了很久,可算是找到了一个,那就是:AsyncHttpClient

AsyncHttpClient实现Get请求body传递formdata参数

HttpClient提供了两种I/O模型:经典的java阻塞I/O模型和基于Java NIO的异步非阻塞事件驱动I/O模型。

Java中的阻塞I/O是一种高效、便捷的I/O模型,非常适合并发连接数量相对适中的高性能应用程序。只要并发连接的数量在1000个以下并且连接大多忙于传输数据,阻塞I/O模型就可以提供最佳的数据吞吐量性能。

然而,对于连接大部分时间保持空闲的应用程序,上下文切换的开销可能会变得很大,这时非阻塞I/O模型可能会提供更好的替代方案。

异步I/O模型可能更适合于比较看重资源高效利用、系统可伸缩性、以及可以同时支持更多HTTP连接的场景。

参考的文章: get请求带body的formdata非json实现AsyncHttpClient解决

  • pom.xml依赖
xml 复制代码
<dependency>
    <groupId>org.asynchttpclient</groupId>
    <artifactId>async-http-client</artifactId>
    <version>2.2.0</version>
</dependency>
  • 最终实现
java 复制代码
import org.asynchttpclient.*;
import org.asynchttpclient.proxy.ProxyServer;
import org.asynchttpclient.request.body.multipart.Part;
import org.asynchttpclient.request.body.multipart.StringPart;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

import static org.asynchttpclient.proxy.ProxyType.HTTP;

/**
 * @author lilinshen
 */
public class TestMain3 {
    public static void main(String[] args) throws Exception {
        String url = "http://127.0.0.1:8080/llsydn/testGet";
        List<Part> params = new ArrayList<Part>();
        params.add(new StringPart("name1", "lls1"));
        params.add(new StringPart("name2", "lls2"));
        String result = asyncRequest(url, params);
        System.out.println("调用结果:" + result);
    }

    /**
     * 执行异步HTTP请求
     */
    public static String asyncRequest(String url, List<Part> params) throws Exception {
        //ProxyServer proxy = new ProxyServer("127.0.0.1", 8888, 8888, null, null, HTTP);
        AsyncHttpClient c = new DefaultAsyncHttpClient(new DefaultAsyncHttpClientConfig.Builder()//.setProxyServer(proxy)
                .build());
        Future<Response> f = c.prepareGet(url).setBodyParts(
                params)
                .execute(new AsyncCompletionHandler<Response>() {
                    @Override
                    public Response onCompleted(Response response) {
                        return response;
                    }

                    @Override
                    public void onThrowable(Throwable t) {
                        throw new RuntimeException("exception");
                    }


                });
        Response response = f.get();
        String result = response == null ? "" : response.getResponseBody();
        c.close(); // 关闭连接器,释放资源
        if (c.isClosed()) {
            System.out.println("已关闭");
        }
        return result;
    }
}

这里,我加了proxy代理,本地可以用fiddler进行代理,就可以拦截到相应的请求。

由上图可以看到,该实现的方式,估计和httpclient上传文件,带额外参数的方式类似。

看到这,有人就会跳出来说,那我用HttpURLConnection,参考asynchttpclient的方法,自己拼接参数,可不可以呀?

相关实现如下:

不好意思,哥们也去试了一下,虽然定义的是GET请求,但是在发送请求的时候,还是被转成了POST请求了!!!

走不通的!!!

在编写文档的时候,好像还发现了其他的实现,httpclient在4.x之后开始提供基于nio的异步版本httpasyncclient, httpasyncclient借助了Java并发库和nio进行封装(虽说NIO是同步非阻塞IO,但是HttpAsyncClient提供了回调的机制,与netty类似,所以可以模拟类似于AIO的效果),其调用方式非常便捷.

有兴趣的小伙伴,可以查看这里:异步httpClient(Async HttpClient)

好了,废话不多说了,既然使用asynchttpclient实现了Get请求body传递formdata参数。

这里就不再深入研究了,毕竟这种反人类的接口,大家伙,还是少写一点,免得麻烦对接人员。

说实话,程序员,还是别难为程序员了吧!!!大家都不容易的!!!

写在最后

好了,以上就是我个人的实操了。可能有些不对,大家伙,轻点喷!!!

个人理解,可能也不够全面,班门弄斧了。

好了,今天就先到这里了!!!^_^

如果觉得有收获的,帮忙点赞、评论、收藏一下,再走呗!!!

相关推荐
别致的影分身15 分钟前
Linux 线程池
java·开发语言·jvm
山山而川粤2 小时前
母婴用品系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
字节流动4 小时前
Android Java 版本的 MSAA OpenGL ES 多重采样
android·java·opengles
玉红7775 小时前
R语言的数据类型
开发语言·后端·golang
呜呼~225145 小时前
前后端数据交互
java·vue.js·spring boot·前端框架·intellij-idea·交互·css3
飞的肖5 小时前
从测试服务器手动热部署到生产环境的实现
java·服务器·系统架构
周伯通*6 小时前
策略模式以及优化
java·前端·策略模式
两点王爷6 小时前
Java读取csv文件内容,保存到sqlite数据库中
java·数据库·sqlite·csv
lvbu_2024war016 小时前
MATLAB语言的网络编程
开发语言·后端·golang
问道飞鱼6 小时前
【Springboot知识】Springboot进阶-实现CAS完整流程
java·spring boot·后端·cas