![](/img/trans.png)
[英]UTF-8 text is garbled when form is posted as multipart/form-data
[英]How to get text/xml as UTF-8 from a multipart/form-data request with RESTeasy?
謝謝你的回答,但使用InputStream而不是使用getBody(...)也行不通。 下面的代碼返回與原始帖子中的結果相同的結果。
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並在那里獲取原始字節,但我不能在我的應用程序中使用這種方法)。
上傳表格:
<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:
@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請求的內容類型標頭中未定義字符集,則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.
* <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>
*/
因此,作為一種解決方法,您可以執行以下操作:
@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
的方法InputPart
。 您實際上可以將每個部分作為原始輸入流並自己讀取數據。 而不是依靠框架將內容轉換為String。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.