JAX-RS文件下载接口返回文件名丢失西班牙特殊字符如何解决
问题解决方案
错误点说明
- 自定义的编码方法逻辑错误:你写的
encodeDefaultISO方法是将字符串按ISO-8859-1编码取字节,再强行用UTF-8解码,会直接丢失非ASCII字符的编码信息,输出乱码属于预期结果 - Content-Disposition头构造不符合规范:HTTP标准中传统的
filename属性仅支持US-ASCII字符,非ASCII字符需要按照RFC 5987规范使用filename*属性声明,同时做URL编码处理 @Produces中指定的charset仅对响应体生效,和文件名编码无关,修改此处不会解决文件名乱码问题
正确实现步骤
- 移除错误的自定义编码方法,直接使用JDK自带的
URLEncoder做URL编码 - 同时配置
filename(兼容旧浏览器)和filename*(适配现代浏览器)两个属性 - 编码时注意将空格对应的
+替换为标准的%20,避免文件名空格识别错误
修复后的代码示例
import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @GET @Path("/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response downloadFileWithGet(@QueryParam("IdFile") String idFile) throws IOException { try { FileCloudStream controllerResponse = ArchivosController.descargarArchivo(Integer.parseInt(idFile)); ResponseBuilder response = Response.ok((Object) controllerResponse.getStream()); // 取原始文件名 String originalFileName = controllerResponse.getArchivoOracle().getArchivo().getNombreArchivo(); // 按UTF-8做URL编码,替换空格的+为%20 String encodedFileName = URLEncoder.encode(originalFileName, StandardCharsets.UTF_8) .replaceAll("\\+", "%20"); // 同时设置兼容格式的Content-Disposition头 String contentDisposition = String.format("attachment; filename=\"%s\"; filename*=UTF-8''%s", encodedFileName, encodedFileName); response.header("Content-Disposition", contentDisposition); return response.build(); } catch (Exception e) { return Response.status(500).entity("No se puede descargar el archivo.").build(); } }
上述代码兼容所有主流浏览器,西语的á、ñ这类特殊字符都会正常识别,不会出现丢失或者乱码的情况。
内容的提问来源于stack exchange,提问作者Nexus Blade
相关产品推荐
相关产品推荐

