关于RestEasy 上传文件,中文名乱码问题
公司使用Resteasy做 REST 框架,web容器用的是Undertow
服务端上传文件相关代码
1 @POST 2 @Path("/normal/upload/{bizType}") 3 @Consumes(MediaType.MULTIPART_FORM_DATA) 4 public RpcResponse<List<FileDTO>> upload(@PathParam("bizType") String bizType, @Context HttpServletRequest request) { 5 try { 6 List<FileDTO> files = new LinkedList<>(); 7 for (Part part : request.getParts()) { 8 logger.debug("upload {} file:{}", part.getName(), part.getSubmittedFileName()); 9 if (StringUtil.nonNullAndEmpty(part.getSubmittedFileName())) { 10 AttachFilePO info = fileService.saveFile(CurrentContext.getTenantId(), bizType, "", part.getSubmittedFileName(),part.getSize(), part.getInputStream()); 11 12 FileDTO dto = BeanCopier.copy(info, FileDTO.class); 13 dto.setCdnPath(dto.getCdnPath().replace("${{real.domain.path}}", serverUrl)); 14 files.add(dto); 15 } 16 } 17 18 if (files.isEmpty()) { 19 return new RpcResponse<>(BaseError.FILE_WRITE_FAILED.getCode(), "not found"); 20 } 21 else { 22 return new RpcResponse<List<FileDTO>>(files); 23 } 24 } 25 catch (Exception exp) { 26 Tuple.Pair<Integer, String> error = ParameterValidator.onException(exp); 27 return new RpcResponse<>(error.getFirst(), error.getSecond()); 28 } 29 }
前端使用的是 form-data 方式进行的文件提交。但是运行过程中发现,非中文的文件上传正常。中文名称的文件则会出现乱码。
此处使用postman截图进行展示
服务端日志截图如下
通过跟踪源码,发现处理类为 io.undertow.server.handlers.form.MultiPartParserDefinition.MultiPartUploadHandler
1 private MultiPartUploadHandler(final HttpServerExchange exchange, final String boundary, final long maxIndividualFileSize, final long fileSizeThreshold, final String defaultEncoding) { 2 this.exchange = exchange; 3 this.maxIndividualFileSize = maxIndividualFileSize; 4 this.defaultEncoding = defaultEncoding; 5 this.fileSizeThreshold = fileSizeThreshold; 6 this.data = new FormData(exchange.getConnection().getUndertowOptions().get(UndertowOptions.MAX_PARAMETERS, 1000)); 7 String charset = defaultEncoding; 8 String contentType = exchange.getRequestHeaders().getFirst(Headers.CONTENT_TYPE); 9 if (contentType != null) { 10 String value = Headers.extractQuotedValueFromHeader(contentType, "charset"); 11 if (value != null) { 12 charset = value; 13 } 14 } 15 this.parser = MultipartParser.beginParse(exchange.getConnection().getByteBufferPool(), this, boundary.getBytes(StandardCharsets.US_ASCII), charset); 16 17 }
当 Content-Type 为multipart/form-data;时,进入该类,代码种获取了charset 字符编码,由于没有显示声明编码,所以程序使用的时默认的 ISO-8859-1 编码。最终导致的乱码。
解决方法:在前端传文件前,手动设置 Content-Type 为 multipart/form-data;charset=utf8;
搞定收工!!!