问题
I'm using resteasy 2.3.4-Final and having UTF-8 problems in calls that accept multipart/form-data. The consumers of my API are iOS and Android devices. Any string params that are sent, don't contain a charset so resteasy seems to be decoding the strings with us-ascii encoding. I've done plenty of work to fix everything else involved from the db layer up to create a filter that will force the character encoding to utf-8. This solved the problem for all form-url-encoded POSTs, but now two calls still don't work and they are both multipart/form-data calls. I understand that the consumers should send the utf-8 charset in the message parts, but I'm trying to figure out if there's any way to force everything to be decoded using UTF-8 temporarily because it would take about 2 weeks for Apple to approve an update to our application which isn't ideal, but we may have to bite the bullet on that one. Has anyone done this before and had success with multipart form uploads?
Thanks!
回答1:
According to the RESTEasy documentation, it should be possible to override the default content type:
http://docs.jboss.org/resteasy/docs/2.3.4.Final/userguide/html_single/index.html#multipart_overwrite_default_content_type
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
@Provider
@ServerInterceptor
public class ContentTypeSetterPreProcessorInterceptor implements
PreProcessInterceptor {
public ServerResponse preProcess(HttpRequest request,
ResourceMethod method) throws Failure, WebApplicationException {
request.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY,
"*/*; charset=UTF-8");
return null;
}
}
回答2:
Here is a workaround for encoding problem. Also please vote for this bug RESTEASY-390.
Example:
import org.apache.james.mime4j.message.BodyPart;
import org.apache.james.mime4j.message.SingleBody;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
...
@POST
@Path("/uploadContacts")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public void uploadContacts(MultipartFormDataInput input) throws Exception {
List<InputPart> inputParts = uploadForm.get("uploadFieldName");
for (InputPart inputPart : inputParts) {
// bytes extracted
byte[] fileBytes = readByteArray(inputPart);
// now we can read it with right encoding
InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(fileBytes), "UTF-8");
...
}
}
private byte[] readByteArray(InputPart inputPart) throws Exception {
Field f = inputPart.getClass().getDeclaredField("bodyPart");
f.setAccessible(true);
BodyPart bodyPart = (BodyPart) f.get(inputPart);
SingleBody body = (SingleBody)bodyPart.getBody();
ByteArrayOutputStream os = new ByteArrayOutputStream();
body.writeTo(os);
byte[] fileBytes = os.toByteArray();
return fileBytes;
}
回答3:
Since org.jboss.resteasy.spi.interception.PreProcessInterceptor
is deprecated, I solved the problem using javax.ws.rs.container.ContainerRequestFilter
with an "injected" HttpServletRequest
.
Example:
@Provider
public class MyContentTypeFilter implements ContainerRequestFilter {
@Context
private HttpServletRequest servletRequest;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
servletRequest.setAttribute(InputPart.DEFAULT_CONTENT_TYPE_PROPERTY, "text/plain; charset=UTF-8");
}
}
来源:https://stackoverflow.com/questions/11215733/how-can-i-get-resteasy-multipartformdatainput-to-decode-strings-using-utf-8