使用
multipart/form-data
时,您可以为每个部分指定带编码的 Content-Type:
POST /some-resource HTTP/1.1
Content-Type: multipart/form-data
--AaB03x
Content-Disposition: form-data
Content-Type: text/plain
... 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();
}