【报错解决】The Unicode character [进] at code point [36,827] cannot be encoded as it is outside the permitted range of 0 to 255
读取文件的时候报错
: The HTTP response header [Content-Disposition] with value [attachment; filename="进度(导入模板).xlsx.xlsx"] has been removed from the response because it is invalid
java.lang.IllegalArgumentException: The Unicode character [进] at code point [36,827] cannot be encoded as it is outside the permitted range of 0 to 255
AI 解答
从错误信息来看,问题是由于HTTP响应头Content-Disposition
中的文件名包含了非ASCII字符(中文字符“进”),而Tomcat服务器尝试将这个值转换为字节数组时失败了。因为Unicode字符“进”的代码点是36,827,超出了单字节表示的0到255的范围,所以导致了IllegalArgumentException
。
要解决这个问题,可以采取以下几种方法之一:
-
URL编码:对
Content-Disposition
头中的文件名进行URL编码,确保所有非ASCII字符都被正确地转义。例如,使用URLEncoder.encode()
方法来编码文件名部分。 -
RFC 5987兼容性:遵循RFC 5987规范,它允许在HTTP头部中使用UTF-8编码的参数值。你可以构建一个符合该规范的
Content-Disposition
头,比如:Content-Disposition: attachment; filename*=UTF-8''%E8%BF%9B%E5%BA%A6%EF%BC%88%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF%EF%BC%89.xlsx
-
设置正确的字符集:确保你的应用服务器配置支持UTF-8编码。对于Tomcat,可以在
server.xml
中配置Connector
元素的URIEncoding
属性为UTF-8
,以确保所有的URI被正确地解码。 -
使用简单的文件名:如果可能的话,避免在文件名中使用非ASCII字符,采用仅包含ASCII字符的简单文件名。
以下是使用RFC 5987格式的示例代码,假设你正在使用Spring框架:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.nio.charset.StandardCharsets;
import java.net.URLEncoder;
import java.util.Objects;
@RestController
public class FileDownloadController {
@GetMapping("/download")
public ResponseEntity<byte[]> downloadFile() {
String filename = "进度(导入模板).xlsx";
byte[] fileContent = {/* ... 文件内容 ... */};
// 使用RFC 5987格式编码文件名
String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8)
.replaceAll("\\+", "%20");
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + filename + "\"; filename*=UTF-8''" + encodedFilename);
return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
}
}
这段代码确保了Content-Disposition
头部能够正确处理包含非ASCII字符的文件名,并且应该能避免你遇到的异常。请根据你的具体环境和需求调整解决方案。
应用代码
@Override
public ResponseEntity<Resource> getFileObj(String fileMd5) {
List<SystemFile> systemFiles = fileMapper.getFileByMd5(fileMd5);
if (systemFiles.isEmpty()) {
return ResponseEntity.notFound().build();
}
SystemFile systemFile = systemFiles.get(0);
String realAddress = configMapper.getKeyValue(SystemConfigKey.SYS_FILE_SAVE_PATH)+systemFile.getPath(); // 真实的文件存储地址
log.info("真实文件地址:{}", realAddress);
Resource resource = new FileSystemResource(realAddress);
if (resource.exists() && resource.isReadable()) {
// return ResponseEntity.ok()
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + systemFile.getFileName()+systemFile.getFileType() + "\"")
// .contentType(MediaType.APPLICATION_OCTET_STREAM)
// .body(resource);
// 使用RFC 5987格式编码文件名
String encodedFilename = URLEncoder.encode(systemFile.getFileName(), StandardCharsets.UTF_8)
.replaceAll("\\+", "%20");
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + systemFile.getFileMd5()+systemFile.getFileType()+ "\"; filename*=UTF-8''" + encodedFilename)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}
版 权 声 明
作者:萌狼蓝天
QQ:3447902411(仅限技术交流,添加请说明方向)
转载请注明原文链接:https://www.cnblogs.com/zwj/p/18641406/solve-problem-java-file-upload-response-error-encoding