首页 > 其他分享 >Apache HttpClient发送文件时中文名变问号

Apache HttpClient发送文件时中文名变问号

时间:2024-07-31 22:51:36浏览次数:10  
标签:http builder 中文名 RFC apache org Apache import HttpClient

使用Apache HttpClient发送multipart/form-data,包含有中文名的文件,对方收到的文件名中文变成了问号

解决方法:
发送方需要设置mode为HttpMultipartMode.RFC6532

发送端代码如下,其中关键行为builder.setMode(HttpMultipartMode.RFC6532);

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
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 org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@SpringBootTest
public class HttpClientTest {

    @Test
    public void test() {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            ContentType contentType = ContentType.create(
                    ContentType.MULTIPART_FORM_DATA.getMimeType(),
                    StandardCharsets.UTF_8);

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            // 解决中文变问号的关键代码
            builder.setMode(HttpMultipartMode.RFC6532);
            builder.setCharset(StandardCharsets.UTF_8);
            builder.setContentType(contentType);
            builder.addTextBody("some_name", "中文的名字", contentType);
            builder.addBinaryBody("some_file", new File("H:\\这是一个中文名的文件_ABC_123.jpg"));
            HttpEntity httpEntity = builder.build();
            HttpPost httpPost = new HttpPost("http://localhost:8080/city/test");
            httpPost.setEntity(httpEntity);

            HttpResponse response = httpClient.execute(httpPost);
            System.out.println(response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收端代码如下:

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

@RestController
@RequestMapping("/city")
public class CityController {

    @PostMapping("/test")
    public String test(HttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        fileMap.forEach((key, multipartFile) -> {
            System.out.println("key : " + key);
            String originalFilename = multipartFile.getOriginalFilename();
            System.out.println("file name : " + originalFilename);
            File file = new File("H:\\out" + File.separator + originalFilename);
            try {
                multipartFile.transferTo(file);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        Map<String, String[]> parameterMap = multipartRequest.getParameterMap();
        parameterMap.forEach((key, value) -> {
            System.out.println("key : " + key);
            System.out.println("value : " + Arrays.toString(value));
        });

        return "this is a test";
    }
}

为什么要这样设置呢?因为默认是STRICT,需要改为RFC6532以处理中文。
源码中有这么一个枚举

package org.apache.http.entity.mime;

/**
 *
 * @since 4.0
 */
public enum HttpMultipartMode {

    /** RFC 822, RFC 2045, RFC 2046 compliant */
    STRICT,
    /** browser-compatible mode, i.e. only write Content-Disposition; use content charset */
    BROWSER_COMPATIBLE,
    /** RFC 6532 compliant */
    RFC6532

}

STRICT: 最严格的模式,遵循 RFC 822、RFC 2045 和 RFC 2046 的规范。在此模式下,通常要求严格按照标准编码和处理内容,不一定会特别处理非ASCII字符,可能会导致中文文件名乱码或转换为问号。

BROWSER_COMPATIBLE: 较为宽松的模式,主要兼容浏览器的行为。它通常仅写入 Content-Disposition 头部,使用当前默认的字符集(通常是 ISO-8859-1 或类似的)来编码内容。对于非ASCII字符的处理可能因浏览器而异,可能导致中文文件名出现问号。

RFC6532: 较新的标准,专门用于处理国际化的多部分内容。在这种模式下,使用 RFC 6532 定义的规则来处理非ASCII字符,包括文件名等内容不会出现乱码或问号。这种模式适合需要确保国际化字符正确传输的场景。

标签:http,builder,中文名,RFC,apache,org,Apache,import,HttpClient
From: https://www.cnblogs.com/lambdadog/p/18335660

相关文章

  • 文件解析漏洞总结(IIS,NGINX,APACHE)
    目录一、IIS解析漏洞IIS6.X方式一:目录解析方式二:畸形文件解析IIS7.X利用条件环境配置下载链接:二、Nginx解析漏洞2.1:nginx_parsing利用条件利用姿势2.2:CVE-2013-4547影响版本利用姿势三、Apache解析漏洞3.1:apache_parsing利用姿势3.2:CVE-2017-15715影响版......
  • Apache DolphinScheduler用户线上Meetup火热来袭!
    ApacheDolphinScheduler社区8月用户交流会精彩继续!本次活动邀请到老牌农牧产品实业集团铁骑力士架构工程师,来分享ApacheDolphinScheduler在现代农牧食品加工场景中的应用实践。此外,还将有社区活跃贡献者以ApacheDolphinScheduler为例,总结ApacheDolphinScheduler以及Apache......
  • 成为Apache SeaTunnel贡献者的N种方式
    如何参与开源贡献参与开源贡献的常见方法有多种:1)参与解答在社区中,帮助使用过程中遇到困难的人,帮他们解释框架的用法也算是一种贡献。2)文档贡献帮助框架来完善文档,比如说将英文文档翻译为中文,纠正文档里面的错误单词,这是很多人参与开源贡献的第一步。3)代码贡献经过阅读......
  • Java中的数据流处理框架:Apache Flink
    Java中的数据流处理框架:ApacheFlink大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨一下Java中的数据流处理框架——ApacheFlink。Flink是一款用于处理数据流和批处理的分布式处理框架。它具有高吞吐量、低延迟和容错的特性,广泛应用于实时......
  • RestTemplate和 apache HttpClient 使用方式
    一、RestTemplate RestTemplate是简化了组装请求对象该类存在于依赖spring-boot-starter-web中,RestTemplate支持get,post现1、RestTemplate不是可直接注入Bean,需要实例化生成BeanSpringBoot的自动配置机制非常强大,但并不是所有的类都被默认自动配置为bean。对于R......
  • Windows下使用Apache和mod_wsgi部署django项目
    一、安装Python确定好所需要的python版本。二、安装Apacheapache下载地址:http://httpd.apache.org/docs/current/platform/windows.html#down下载完成后做如下操作将apache解压后直接复制到你想安装的路径下1、更改httpd.conf文件,找到如下代码并更改路径DefineSRVROOT"E:......
  • 【Apache Doris】3.0存算分离|标准部署篇(一)
    【ApacheDoris】3.0存算分离|标准部署篇(一)一、前提概要二、环境信息三、前置准备四、FoundationDB安装五、OpenJDK17安装六、MetaService安装七、集群安装八、快速体验接上数据架构新篇章:存算一体与存算分离的协同演进。本文主要分享ApacheDoris3.0存算分离架......
  • Apache2服务介绍
    apache2安装使用配置web访问配置虚拟主机配置代理正向代理反向代理官网互联网上排名第一的HTTP服务器,ApacheHTTP服务器项目致力于开发和维护适用于现代操作系统(包括UNIX和Windows)的开源HTTP服务器。该项目的目标是提供安全、高效且可扩展的服务器,该服务......
  • 在.net 8中使用HttpClientFactory时日志记录请求body和响应body
     1、定义DelegatingHandlerpublicclassLoggingHandler:DelegatingHandler{privatereadonlyILogger<LoggingHandler>_logger;publicLoggingHandler(ILogger<LoggingHandler>logger){_logger=logger;}protectedov......
  • Linux中,Apache配置与应用
    ApacheHTTPServer之所以受到众多企业的青睐,得益于其代码开源、跨平台、功能模块化、可灵活定制等诸多优点,不仅性能稳定,在安全性方面的表现也十分出色。Apache连接保持HTTP是属于应用层的面向对象协议,基于TCP协议之上的可靠传输。每次在进行HTTP连接之前,需要先进行TCP连......