HttpClient 发送表单

发布时间 2023-10-30 22:12:38作者: 抱糖果彡

基础代码

只包含最简单的代码,不包含乱码解决、文件上传

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class Test {

    public static void main(String[] args) {
        CloseableHttpClient client = HttpClients.createDefault();
        try{
            //创建 post 请求(fiddler 设置了监听 8888 端口)
            HttpPost post = new HttpPost("http://127.0.0.1:8888");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();
            post.setConfig(defaultRequestConfig);
            //创建表单
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addTextBody("key1","值1", ContentType.create("multipart/form-data",Consts.UTF_8));
            builder.addTextBody("key2","值2", ContentType.create("multipart/form-data",Consts.UTF_8));
            HttpEntity build = builder.build();
            post.setEntity(build);
            //发送请求
            CloseableHttpResponse response = client.execute(post);
            System.out.println(response.getEntity());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭连接
                client.close();
            }catch (Exception e){}
        }
    }

}

image-20231030213927997

可以看到没有乱码,并且都已经赋值,但是此时我们将 key 改成中文,就会变成乱码

image-20231030214037196

即使上方已经将 Content-type 改成 UTF-8,但依旧乱码,因为此时只是设置了内容的值为 UTF-8,需要设置字段值也改成 UTF-8

解决中文乱码

方法一

设置字段模式为 HttpMultipartMode.RFC6532

builder.setMode(HttpMultipartMode.RFC6532);
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class Test {

    public static void main(String[] args) {
        CloseableHttpClient client = HttpClients.createDefault();
        try{
            //创建 post 请求
            HttpPost post = new HttpPost("http://127.0.0.1:8888");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();
            post.setConfig(defaultRequestConfig);
            //创建表单
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //设置模式,在 下方 build 方法中,会调用 new HttpRFC6532Multipart() 方法,其中字段默认编码就为 UTF-8 (一种取巧的方法)
            builder.setMode(HttpMultipartMode.RFC6532);
            builder.addTextBody("字段1","值1", ContentType.create("multipart/form-data",Consts.UTF_8));
            builder.addTextBody("字段2","值2", ContentType.create("multipart/form-data",Consts.UTF_8));
            HttpEntity build = builder.build();
            post.setEntity(build);
            //发送请求
            CloseableHttpResponse response = client.execute(post);
            System.out.println(response.getEntity());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭连接
                client.close();
            }catch (Exception e){}
        }
    }

}

image-20231030214724564

方法二

设置字段模式为 HttpMultipartMode.BROWSER_COMPATIBLE,同时设置编码为 UTF-8

builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setCharset(Consts.UTF_8);
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class Test {

    public static void main(String[] args) {
        CloseableHttpClient client = HttpClients.createDefault();
        try{
            //创建 post 请求
            HttpPost post = new HttpPost("http://127.0.0.1:8888");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();
            post.setConfig(defaultRequestConfig);
            //创建表单
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //设置为浏览器模式,其中字段会根据 builder.charset 来设置编码格式
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.setCharset(Consts.UTF_8);
            builder.addTextBody("字段1","值1", ContentType.create("multipart/form-data",Consts.UTF_8));
            builder.addTextBody("字段2","值2", ContentType.create("multipart/form-data",Consts.UTF_8));
            HttpEntity build = builder.build();
            post.setEntity(build);
            //发送请求
            CloseableHttpResponse response = client.execute(post);
            System.out.println(response.getEntity());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭连接
                client.close();
            }catch (Exception e){}
        }
    }

}

image-20231030214736001

文件上传

一般 form 表单都会提供文件上传,直接添加 addBinaryBody 即可,其中该提供 inputSteam、文件重命名等方法,具体可自行研究

builder.addBinaryBody("文件字段3",new File("D:\\test\\部署路径.xlsx"));

image-20231030215231602

发送form表单完整代码

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.File;

public class Test {

    public static void main(String[] args) {
        CloseableHttpClient client = HttpClients.createDefault();
        try{
            //创建 post 请求
            HttpPost post = new HttpPost("http://127.0.0.1:8888");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();
            post.setConfig(defaultRequestConfig);
            //创建表单
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            //(防止字段名中文乱码)设置为浏览器模式,其中字段会根据 builder.charset 来设置编码格式
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.setCharset(Consts.UTF_8);
            //设置普通字段值
            builder.addTextBody("字段1","值1", ContentType.create("multipart/form-data",Consts.UTF_8));
            builder.addTextBody("字段2","值2", ContentType.create("multipart/form-data",Consts.UTF_8));
            //添加文件
            builder.addBinaryBody("文件字段3",new File("D:\\test\\部署路径.xlsx"));
            HttpEntity build = builder.build();
            post.setEntity(build);
            //发送请求
            CloseableHttpResponse response = client.execute(post);
            System.out.println(response.getEntity());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭连接
                client.close();
            }catch (Exception e){}
        }
    }

}

附带发送 body 请求代码

import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.util.HashMap;

public class Test {

    public static void main(String[] args) {
        CloseableHttpClient client = HttpClients.createDefault();
        try{
            //创建 post 请求
            HttpPost post = new HttpPost("http://127.0.0.1:8888");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();
            post.setConfig(defaultRequestConfig);

            //设置 body 值
            HashMap<String, Object> map = new HashMap<>();
            map.put("字段1","值1");
            String jsonString = JSONObject.toJSONString(map);

            post.setEntity(new StringEntity(jsonString, ContentType.APPLICATION_JSON));

            //发送请求
            CloseableHttpResponse response = client.execute(post);
            System.out.println(response.getEntity());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                //关闭连接
                client.close();
            }catch (Exception e){}
        }
    }

}

image-20231030215913084