I'm using next code for file uploading:
@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);
...
}
It works ok for latin characters, but I have problems with cyrillic (As I understand, because Java by default encodes rawpost data to unicode)
How can I correctly determine encoding and encode data from post to valid Java string?
When using multipart/form-data you can specify a Content-Type with encoding for every part:
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--
If you add this Content-Type for every part it should work out of the box (at least for the current version 3.0.x of RESTeasy). You can test this with the RESTeasy client:
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);
If your client does not give you the possibility to set Content-Type per part you can change the default encoding for instance depending on a custom header (I'm adding a modified code-example because the PreProcessInterceptor is marked @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);
}
}
}
If you are using a plain HTML Form you can try to add <input type="hidden" name="_charset_" /> to your form. As defined in the multipart/form-data encoding algorithm the client should populate this field with the charset he is using. You then need to encode the content in your ResourceClass on your own:
@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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With