springcloud 上传文件获取文件名乱码

项目使用路由zuul,用HttpServletRequest接收文件参数时,file.getOriginalFilename()名称乱码。Spring Cloud Zuul上传文件有spring mvc和zuulServlet两种处理方式,spring mvc会导致乱码,zuulServlet不会。一般外部请求由DispatcherServlet处理,/zuul/路径请求由ZuulServlet处理。

项目中使用了路由zuul。
用HttpServletRequest接收文件参数
使用 MultipartHttpServletRequest multi = (MultipartHttpServletRequest) httpServletRequest;
file.getOriginalFilename()得到的名称时乱码。
此时在网关项目中添加

zuul:
  servlet-path: /

Spring Cloud Zuul对于上传文件有两种处理方式,一种是用spring mvc,另一种是zuulServlet。spring mvc会导致乱码问题,zuulServlet不会。在zuul的过滤器中,有一个pre的过滤器 ServletDetectionFilter,他的执行顺序是-3,也是最先执行的过滤器,在这个过滤器中,有这么一段代码:

@Override
public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
    if (!(request instanceof HttpServletRequestWrapper) 
            && isDispatcherServletRequest(request)) {
        ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, true);
    } else {
        ctx.set(IS_DISPATCHER_SERVLET_REQUEST_KEY, false);
    }
 
    return null;
}

用来判断使用springmvc 还是zuulServlet,IS_DISPATCHER_SERVLET_REQUEST_KEY为false就会用ZuulServlet处理。如果没加/zuul前缀,IS_DISPATCHER_SERVLET_REQUEST_KEY就会置为true,就会用spring mvc上传。一般情况下,发送到API网关的外部请求都会被Spring的DispatcherServlet处理,除了通过/zuul/路径访问的请求会绕过DispatcherServlet,被ZuulServlet处理。

### 解决 Insomnia 上传文件时中文文件名乱码的问题 在使用 Insomnia 进行文件上传测试时,如果文件名中包含中文字符,可能会出现乱码问题。这是由于 Insomnia 在处理请求参数时对特殊字符(如中文)进行了 URL 编码,而服务器端如果没有正确解码,会导致文件名显示异常。 为了解决这一问题,可以在服务器端对接收到的文件名进行 `URLDecoder.decode` 处理。例如,在 Spring Boot 中接收文件名时,可以使用如下代码: ```java @PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file, @RequestParam("filename") String filename) { try { // 解码文件名 String decodedFilename = URLDecoder.decode(filename, "UTF-8"); // 处理文件上传逻辑 return "File uploaded: " + decodedFilename; } catch (Exception e) { return "Error occurred while uploading file."; } } ``` 在 Insomnia 中发送请求时,应确保文件名参数已经通过 `URLEncoder.encode` 编码后再发送,这样可以保证中文字符在传输过程中不会被破坏: ```java String encodedFilename = URLEncoder.encode("中文文件名.txt", "UTF-8"); ``` 发送请求时,将 `encodedFilename` 作为参数传入 Insomnia 的请求体或 URL 参数中。服务器端接收到该参数后,再使用 `URLDecoder.decode` 进行解码,即可获得原始的中文文件名 [^1]。 此外,Insomnia 在处理请求路径中的 `%` 编码时,会自动进行反转义操作,因此需要确保路径中的参数在发送前已经正确编码,以避免因反转义导致的路径解析错误。 ### 文件名中包含 HTML 实体字符的处理 如果文件名中包含 HTML 实体字符(如 `&`、`<`、`>` 等),在存储到数据库或展示到前端时可能会出现问题。例如,前端展示时虽然可以自动识别这些实体字符并正常显示,但如果文件名用于运算或作为文件路径的一部分(特别是在 Linux 系统中),则可能导致文件或路径找不到的异常。 解决此类问题的方法是使用 `StringEscapeUtils.unescapeHtml4` 对文件名进行转义处理: ```java import org.apache.commons.text.StringEscapeUtils; String decodedFilename = StringEscapeUtils.unescapeHtml4(encodedFilename); ``` 通过这种方式,可以将 `&` 转换为 `&`,`<` 转换为 `<`,`>` 转换为 `>`,从而确保文件名在系统中可以正确使用 。 ### 总结 通过在客户端使用 `URLEncoder.encode` 编码文件名,并在服务器端使用 `URLDecoder.decode` 解码,可以有效解决 Insomnia 上传文件时中文文件名乱码的问题。对于文件名中包含 HTML 实体字符的情况,可以使用 `StringEscapeUtils.unescapeHtml4` 进行处理,以确保文件名在系统中正确解析和使用。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值