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

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

问题描述

感谢您的回答,但是使用InputStream而不是使用getBody(...)也无效。下面的代码返回的结果与我原来发布的结果相同。

  final InputStream inStream = fileUploadInput.getFormDataPart(SearchingInput,InputStream .class,null); 
//获取字节
最终字节[] inBytes = new byte [1024];
final ByteArrayOutputStream outBytes = new ByteArrayOutputStream(inBytes.length);
int length = 0; ((length = inStream.read(inBytes))> = 0){
outBytes.write(inBytes,0,length);
}
final byte [] rawInput = outBytes.toByteArray();

//获取编码
最终字符串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);
返回utf8;



ORIGINAL POST:



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

上传表单:

 < html> 
< body>
< h1> JAX-RS上传表单< / h1>

< form action =http://.../uploadmethod =POSTenctype =multipart / form-data>

< p>选择文件:< input type =filename =upload/>< / p>
< input type =submitvalue =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 searchingInput,final MultipartFormDataInput fileUploadInput)throws BadRequestException,IOException {

try {
final Map< String,List< InputPart>> inputToInputPart = fileUploadInput.getFormDataMap();

if(inputToInputPart.containsKey(searchingInput)){

final StringBuilder builder = new StringBuilder();
final List< InputPart> inputParts = inputToInputPart.get(searchingInput); (InputPart inputPart:inputParts){
builder.append(inputPart.getBody(String.class,null));


}

return builder.toString();
} else {
throw new BadRequestException(带请求的表单不包含输入元素+ searchingInput +。);

catch(Exception e){
throw new BadRequestException(The file upload failed。,e);




$ b $ MessageBodyReader:

pre code $ @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;
$ b @Override
public boolean isReadable(final Class<> type,
final类型genericType,
final Annotation []注释$ b $ final MediaType mediaType){

布尔结果= 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));
返回结果;

$ b @Override
public String readFrom(final Class< String> type,
final类型genericType,
final Annotation [] annotations,
final MediaType mediaType,$ b $ 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; ((length = entityStream.read(inBytes))> = 0){
outBytes.write(inBytes,0,length);

while
}

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);

返回utf8;


$ / code>


解决方案

在HTTP请求的内容类型头文件中没有定义字符集,resteasy假定为charset = US-ASCII。
查看org.jboss.resteasy.plugins.providers.multipart.InputPart:

  / ** 
*如果有一个没有charset参数的内容类型头,则假定charset = US-ASCII
*。
*< p>
*这可以通过在
* {@link org.jboss.resteasy.spi.HttpRequest#setAttribute(String,Object)}
*中设置一个不同的字符串值来覆盖, resteasy.provider.multipart.inputpart.defaultCharset)
*此处输入的代码字符串为`key`。它应该在
* {@link org.jboss.resteasy.spi.interception.PreProcessInterceptor}中完成。
*< / p>





$ b因此,作为解决方法,您可以执行以下操作: p>

  @Provider 
@ServerInterceptor
public class CharsetPreProcessInterceptor implements PreProcessInterceptor {

@Override
public ServerResponse preProcess(HttpRequest请求,ResourceMethod方法)抛出失败,WebApplicationException {
request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY,charset = UTF-8);
返回null;
}

}


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;

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).

Upload Form:

<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>

Resource class:

@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:

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

解决方案

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从多部分/表单数据请求中获取text / xml为UTF-8?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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