如何使用 RESTeasy 从多部分/表单数据请求中获取文本/xml 为 UTF-8? [英] How to get text/xml as UTF-8 from a multipart/form-data request with RESTeasy?

查看:30
本文介绍了如何使用 RESTeasy 从多部分/表单数据请求中获取文本/xml 为 UTF-8?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢您的回答,但使用 InputStream 而不是使用 getBody(...) 也不起作用.下面的代码返回的结果与我原来的帖子中的结果相同.

thanks for your answer, but using an InputStream instead of using getBody(...) does also not work. The code below returns the same result as the one from my original 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"请求中获取 UTF-8 格式的text/xml"?(我知道可以编写一个预处理器 - 拦截器并在那里获取原始字节,但我不能在我的应用程序中使用这种方法).

ORIGINAL POST:

I want to upload UTF-8 encoded XML files using the HTML form below and read it on the server using a RESTEasy MultipartFormDataInput, and the Java code shown below. On the server side I seem to be getting the content of the file(s) ASCII encoded, independent of the actual encoding of the uploaded files (which is UTF-8) (accessing it the way described below). All characters not part of the ASCII character set are are being replaced by ?. How can I get 'text/xml' as UTF-8 from a 'multipart/form-data' request with RESTeasy? (I know it is possible to write a PreProcessor - Interceptor and get the raw bytes there, but I can't use this approach in my application).

上传表单:

<html>
<body>
    <h1>JAX-RS Upload Form</h1>

    <form action="http://.../upload" method="POST" enctype="multipart/form-data">

       <p>Select a file : <input type="file" name="upload"/></p>
       <input type="submit" value="Upload It" />

    </form>
</body>
</html>

资源类:

@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<InputPart>> inputToInputPart = fileUploadInput.getFormDataMap();

        if(inputToInputPart.containsKey(searchedInput)) {

            final StringBuilder builder = new StringBuilder();
            final List<InputPart> 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:

MessageBodyReader:

@Provider
@Consumes ("text/xml")
public class XmlStringReader implements MessageBodyReader<String> {
    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<String> type,
                                        final Type genericType,
                                        final Annotation[] annotations,
                                        final MediaType mediaType,
                                        final MultivaluedMap<String, String> 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 请求的 content-type 标头中没有定义字符集时,resteasy 假定为 'charset=US-ASCII'.参见 org.jboss.resteasy.plugins.providers.multipart.InputPart:

When no charset is defined in the content-type header of your HTTP request, resteasy assumes 'charset=US-ASCII'. See org.jboss.resteasy.plugins.providers.multipart.InputPart:

/**
    * If there is a content-type header without a charset parameter, charset=US-ASCII
    * is assumed.
    * <p>
    * 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}.
    * </p>
     */

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

So, as a work-around you can do the following:

 @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;
    }

}

这篇关于如何使用 RESTeasy 从多部分/表单数据请求中获取文本/xml 为 UTF-8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆