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

3

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

@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默认将原始POST数据编码为Unicode)

我应该如何正确确定编码并将POST数据编码为有效的Java字符串?

1个回答

5
使用 multipart/form-data 时,您可以为每个部分指定带编码的 Content-Type:
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);

如果您的客户端不允许您针对每个部分设置内容类型,则可以根据自定义标头更改默认编码(我添加了一个修改后的代码示例,因为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编码算法的定义,客户端应该使用他所使用的字符集填充此字段。然后您需要自己对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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接