如何使用RESTeasy从multipart / form-data请求获取text / xml为UTF-8?

谢谢你的回答,但使用InputStream而不是使用getBody(…)也行不通。 下面的代码返回与原始post中的结果相同的结果。

final InputStream inStream = fileUploadInput.getFormDataPart(searchedInput, InputStream.class, null); // get bytes final byte[] inBytes = new byte[1024]; final ByteArrayOutputStream outBytes = new ByteArrayOutputStream(inBytes.length); int length = 0; while((length = inStream.read(inBytes)) >= 0) { outBytes.write(inBytes, 0, length); } final byte[] rawInput = outBytes.toByteArray(); // get Encoding final String asciiInput = new String(rawInput, ASCII); final String utf8 = new String(rawInput, UTF8); final String isoLatin1 = new String(rawInput, ISO8859_1); log.info("ASCII: " + ascii); log.info("UTF8: " + utf8); log.info("ISOLATIN1: " + isoLatin1); return utf8; 

原始邮寄:

我想使用下面的HTML表单上传UTF-8编码的XML文件,并使用RESTEasy MultipartFormDataInput在服务器上读取它,以及下面显示的Java代码。 在服务器端,我似乎得到了ASCII编码文件的内容,与上传文件的实际编码(UTF-8)无关(以下面描述的方式访问它)。 所有不属于ASCII字符集的字符都被替换为? 。 如何从RESTeasy的’multipart / form-data’请求中将’text / xml’作为UTF-8? (我知道可以编写一个PreProcessor – Interceptor并在那里获取原始字节,但我不能在我的应用程序中使用这种方法)。

上传表格:

   

JAX-RS Upload Form

Select a file :

资源类:

 @Path("/upload") @POST @Consumes("multipart/form-data") public Response createUploadTemplate( @Context HttpServletRequest req, MultipartFormDataInput formInput) { try { final String templateXml = getInput("upload", formInput); //... } catch (Exception e) { //... } } private static String getInput(final String searchedInput, final MultipartFormDataInput fileUploadInput) throws BadRequestException, IOException { try { final Map<String, List> inputToInputPart = fileUploadInput.getFormDataMap(); if(inputToInputPart.containsKey(searchedInput)) { final StringBuilder builder = new StringBuilder(); final List inputParts = inputToInputPart.get(searchedInput); for(InputPart inputPart : inputParts) { builder.append(inputPart.getBody(String.class,null)); } return builder.toString(); } else { throw new BadRequestException("The form send with the request does not contain an input element " + searchedInput + "."); } } catch(Exception e) { throw new BadRequestException("The file upload failed.", e); } } 

化MessageBodyReader:

 @Provider @Consumes ("text/xml") public class XmlStringReader implements MessageBodyReader { private static Logger log = LoggerFactory.getLogger(UploadedXmlStringReader.class); private static final String ASCII = "ASCII"; private static final String ISO8859_1 = "ISO8859_1"; private static final String UTF8 = "UTF8"; @Override public boolean isReadable(final Class type, final Type genericType, final Annotation[] annotations, final MediaType mediaType) { boolean result = type.equals(String.class) && MediaType.TEXT_XML_TYPE.equals(mediaType); log.info(MessageFormat.format("{0} == String.class && MediaType.TEXT_XML_TYPE == {1}: {2}", type, mediaType, result)); return result; } @Override public String readFrom(final Class type, final Type genericType, final Annotation[] annotations, final MediaType mediaType, final MultivaluedMap httpHeaders, final InputStream entityStream) throws IOException, WebApplicationException { final byte[] inBytes = new byte[1024]; final ByteArrayOutputStream outBytes = new ByteArrayOutputStream(inBytes.length); int length = 0; while((length = entityStream.read(inBytes)) >= 0) { outBytes.write(inBytes, 0, length); } final byte[] rawInput = outBytes.toByteArray(); final String ascii = new String(rawInput, ASCII); final String utf8 = new String(rawInput, UTF8); final String isoLatin1 = new String(rawInput, ISO8859_1); log.info("ASCII: " + ascii); log.info("UTF8: " + utf8); log.info("ISOLATIN1: " + isoLatin1); return utf8; } } 

如果在HTTP请求的内容类型标头中未定义字符集,则resteasy会假定为“charset = US-ASCII”。 请参阅org.jboss.resteasy.plugins.providers.multipart.InputPart:

 /** * If there is a content-type header without a charset parameter, charset=US-ASCII * is assumed. * 

* This can be overwritten by setting a different String value in * {@link org.jboss.resteasy.spi.HttpRequest#setAttribute(String, Object)} * with this ("resteasy.provider.multipart.inputpart.defaultCharset") * String`enter code here` as key. It should be done in a * {@link org.jboss.resteasy.spi.interception.PreProcessInterceptor}. *

*/

因此,作为一种解决方法,您可以执行以下操作:

  @Provider @ServerInterceptor public class CharsetPreProcessInterceptor implements PreProcessInterceptor { @Override public ServerResponse preProcess(HttpRequest request, ResourceMethod method) throws Failure, WebApplicationException { request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, "charset=UTF-8"); return null; } } 

我通常不会依赖getBody上的getBody方法。 您实际上可以将每个部分作为原始输入流并自己读取数据。 而不是依靠框架将内容转换为String。