java - RestEasy 文件上传 - 如何正确确定文件名编码?

标签 java encoding resteasy multipartform-data

我正在使用下一个代码进行文件上传:

@Path("/files/")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public OrderData uploadFile(MultipartFormDataInput input) {
    List<InputPart> parameterParts = input.getFormDataMap().get("Filename");
    String filename = parameterParts.get(0).getBody(String.class, null);
    ...
}

它对拉丁字符没问题,但我对西里尔字母有问题 (据我了解,因为 Java 默认情况下将 rawpost 数据编码为 un​​icode)

如何正确确定编码并将数据从 post 编码为有效的 Java 字符串?

最佳答案

使用 multipart/form-data 时您可以为每个部分指定一个带有编码的内容类型:

POST /some-resource HTTP/1.1
Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="file"; filename="file1.txt"
Content-Type: text/plain; charset=utf-8

... contents of file1.txt ...
--AaB03x--

如果您为每个部分添加此 Content-Type,它应该开箱即用(至少对于 RESTeasy 的当前版本 3.0.x 而言)。您可以使用 RESTeasy 客户端对此进行测试:

WebTarget target = client.target("/some-resource");
MultipartFormDataOutput formData = new MultipartFormDataOutput();
formData.addFormData("file", fileContent, MediaType.TEXT_PLAIN_TYPE.withCharset("utf-8"));
Entity<MultipartFormDataOutput> entity = Entity.entity(formData, MediaType.MULTIPART_FORM_DATA);
Response response = target.request().post(entity);

如果您的客户不允许您为每个部分设置内容类型,您可以 change the default encoding例如,取决于自定义 header (我正在添加修改后的代码示例,因为 PreProcessInterceptor 被标记为 @deprecated ):

@Provider
public class CharsetFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        String charset = requestContext.getHeaderString("X-Charset");
        if (charset != null) {
            requestContext.setProperty(InputPart.DEFAULT_CHARSET_PROPERTY, charset);
        }
    }

}

如果您使用纯 HTML 表单,您可以尝试添加 <input type="hidden" name="_charset_" />到你的表格。如 multipart/form-data encoding algorithm 中所定义客户应该用他正在使用的字符集填充这个字段。然后您需要自己对 ResourceClass 中的内容进行编码:

@POST
@Path("/form")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.TEXT_PLAIN)
public Response uploadForm(MultipartFormDataInput input) throws IOException {
    String charset = input.getFormDataMap().get("_charset_").get(0).getBodyAsString();
    InputPart file = input.getFormDataMap().get("file").get(0);
    InputStream inputStream = file.getBody(InputStream.class, null);
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, charset));
    String line;
    StringBuilder content = new StringBuilder();
    while ((line = br.readLine()) != null) {
        content.append(line);
    }
    return Response.ok(content).header("Content-Type", MediaType.TEXT_PLAIN_TYPE.withCharset(charset)).build();
}

关于java - RestEasy 文件上传 - 如何正确确定文件名编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24730860/

相关文章:

java - 如何在Spring java中设置存储库?

java - 如何在 Java Web 应用程序之间共享通用组件?

mysql - 让 MySQL 显示用于特定列的编码

java - 将 TargetDataLine 数据编码到 Ogg Vorbis 文件中

java - RESTeasy 中的原始图像

java - 有什么方法可以强制使用某些特定的注释以及 Java 中的某些特定方法

java - Selenium Chrome 开发者工具 : Unknown error: cannot connect to chrome at localhost:6666 from chrome not reachable

php - 如何在 SOAP 响应中发送纯 XML?

java - GAE 上的 Resteasy 多部分/数据格式文件上传

java - Jetty MultipartFormDataInput 未调度