java使用HttpClient 发送带文件的formdate类型表单 post请求

先贴上代码

1.创建一个表单

        // 创建一个表单
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

        File photoFile = ResourceUtils.getFile("classpath:static/temp1.jpg");
        builder.addTextBody("uid", uid");
        builder.addTextBody("token", token);
        builder.addBinaryBody("icon",photoFile);

        String setIconUrl = "http://www.123.com";
        JSONObject body = HttpClientUtil.httpYywSetIcon(setIconUrl, "utf-8", builder);

2.发送post请求

 public static JSONObject httpYywSetIcon(String url, String encoding, MultipartEntityBuilder entityBuilder)
            throws KeyManagementException, NoSuchAlgorithmException, ClientProtocolException, IOException {
        // 采用绕过验证的方式处理https请求
        SSLContext sslcontext = createIgnoreVerifySSL();

        // 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext)).build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        HttpClients.custom().setConnectionManager(connManager);

        // 创建自定义的httpclient对象
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();

        // 定义数据分隔线
//        String BOUNDARY = "========7d4a6d158c9";

        // 创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        // 构造消息头
//        httpPost.setHeader("Content-type", "multipart/form-data; boundary=" + BOUNDARY);
        httpPost.setHeader("Accept", "application/json");

        //配置代理
        RequestConfig requestConfig = RequestConfig.custom()
                .setProxy(new HttpHost("localhost", 8888))
                .build();
        httpPost.setConfig(requestConfig);

        // 设置参数到请求对象中
        httpPost.setEntity(entityBuilder.build());

        CloseableHttpResponse response = client.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();

        if (statusCode != 200) {
            return new JSONObject();
        }
        //responseEntity才是真正收到的内容
        HttpEntity responseEntity = response.getEntity();
        String result = "";
        if (responseEntity != null) {
            result = EntityUtils.toString(responseEntity, "UTF-8");

        }
        EntityUtils.consume(responseEntity);
        return JSONObject.parseObject(result);
    }
public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sc = SSLContext.getInstance("SSLv3");

        // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        sc.init(null, new TrustManager[] { trustManager }, null);
        return sc;
    }

如上的代码是可以实现表单上传的,但是也发现了一些问题,记录一下:

1 在 httpYywSetIcon 方法里有这2行代码

  // 定义数据分隔线
   String BOUNDARY = "========7d4a6d158c9";
// 构造消息头
   httpPost.setHeader("Content-type", "multipart/form-data; boundary=" + BOUNDARY);

我刚开始只加了第二行,使用fiddler工具 查看表单内容是完全错乱的

后来加上BUUNDARY,发现表单里第一个key是正常的,其他是错乱的,所以是因为我的请求头数据分割的问题。

然后,我把这2行都注释了,发现正常了

2. 这只是HttpClient的用法,实际上使用流的 write方式,也可以实现这个功能,不过要加上数据分割线,数据传输开始和结束标志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值