我創建了一個自定義提供程序,它將對象序列化爲JSON,因爲默認的Jackson序列化在使用UTF-8編碼時似乎無法正常工作(它添加了額外的非法字符不被客戶解碼)。Jersey自定義提供程序爲UTF-8編碼拋出IOException
提供者:
@Provider
@Produces(MediaType.APPLICATION_JSON+"; charset=UTF-8")
public class JsonSerializer implements MessageBodyWriter<ResponseModel> {
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public long getSize(ResponseModel t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return 0;
}
@Override
public void writeTo(ResponseModel entity, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException {
Gson gson = new GsonBuilder().setDateFormat("dd/MM/yyyy HH:mm:ss").create();
JSONObject output = new JSONObject();
output = (JSONObject) JSONValue.parse(gson.toJson(entity));
entityStream.write(output.toString().getBytes());
entityStream.flush();
}
}
這裏是我的球衣的servlet的web.xml:
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>gr.modus.ext</param-value>
</init-param>
<!--init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param-->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>gr.modus.ext</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
下面是一個Web服務方法的樣本邏輯:
ResponseModel<AnnouncementStatus> rm = new ResponseModel<AnnouncementStatus>();
rm.setData(AnnouncementUtils.getStatuses(userId));
rm.setSuccess(true);
return Response.ok(rm).build();
每當我打電話這個方法,它正確地通過我的JsonSerializer,但它給出了以下內部服務器錯誤:
java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(CoderResult.java:260) at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:781) at com.sun.faces.application.ByteArrayWebOutputStream.writeTo(ByteArrayWebOutputStream.java:112) at com.sun.faces.application.ViewHandlerResponseWrapper.flushToWriter(ViewHandlerResponseWrapper.java:162)
奇怪的是,當我的註釋產生只是MediaType.APPLICATION_JSON
時,一切正常工作。然而,響應數據沒有正確編碼,所以我不得不手動添加編碼,現在我有這個問題...
我讀到JSON總是使用UTF-8序列化,但由於某種原因,如果我沒有指定它的UTF-8字符集,我的響應頭部會有'ISO-8859'charse。當我使用servlet時,只需設置響應的內容類型即可完美工作:'response.setContent(「text/javascript; charset = utf-8」)'。 另外我沒有得到關於'write'的部分。我應該避免使用entityStream? – Konstantine
將'getBytes()'改爲'getBytes(StandardCharsets.UTF_8)'似乎可以避免異常。 – Konstantine