我正在使用jackson框架在JSON和Java之间编组和解组数据。一切都运作良好,只要输入不包含任何字符,如:
对于我尝试的输入数据:
String jsonData = "{\"id\":1,\"street\":\"Straße\",\"number\":\"1c\",\"zipCode\":1111,\"city\":\"MyCity\"}";
以及:
String jsonData = "{\"id\":1,\"street\":\"Stra\u00DFe\",\"number\":\"1c\",\"zipCode\":1111,\"city\":\"MyCity\"}";
并且我一直得到同样的例外。
从json数据到java实体对象的映射是通过以下方式完成的:
/*
* Convert stream to data entity
*/
ObjectMapper m = new ObjectMapper();
T entity = (T) m.readValue(stringToStream(jsonData), readableClass);
我还执行了一个json数据验证,它可以像预期的那样工作,也可以使用上面的字符。
如何处理这些数据?
的更新 的
这些是MessageBodyReader
类
@Override
public T readFrom(Class<T> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
final String jsonData = getStringFromInputStream(entityStream);
System.out.println(jsonData);
InputStream isSchema = new FileInputStream(jsonSchemaFile);
String jsonSchema = getStringFromInputStream(isSchema);
/*
* Perform JSON data validation against schema
*/
validateJsonData(jsonSchema, jsonData);
/*
* Convert stream to data entity
*/
ObjectMapper m = new ObjectMapper();
T entity = (T) m.readValue(stringToStream(jsonData), readableClass);
return entity;
}
/**
* Validate the given JSON data against the given JSON schema
*
* @param jsonSchema
* as String
* @param jsonData
* as String
* @throws MessageBodyReaderValidationException
* in case of an error during validation process
*/
private void validateJsonData(final String jsonSchema, final String jsonData)
throws MessageBodyReaderValidationException {
try {
final JsonNode d = JsonLoader.fromString(jsonData);
final JsonNode s = JsonLoader.fromString(jsonSchema);
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
JsonValidator v = factory.getValidator();
ProcessingReport report = v.validate(s, d);
System.out.println(report);
if (!report.toString().contains("success")) {
throw new MessageBodyReaderValidationException(
report.toString());
}
} catch (IOException e) {
throw new MessageBodyReaderValidationException(
"Failed to validate json data", e);
} catch (ProcessingException e) {
throw new MessageBodyReaderValidationException(
"Failed to validate json data", e);
}
}
/**
* Taken from <a href=
* "http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/"
* >www.mkyong.com</a>
*
* @param is
* {@link InputStream}
* @return Stream content as String
*/
private String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
private InputStream stringToStream(final String str) {
return new ByteArrayInputStream(str.getBytes());
}
答案 0 :(得分:11)
JSON规范规定,只有有效的编码是UTF-8,UTF-16和UTF-32。不能使用其他编码(如Latin-1)。您的stringToStream实现未显式设置编码,因此使用系统默认值。这就是你如何得到非utf流。在下一步中,Jakson尝试使用UTF编码之一(内置检测算法)解析流并失败。尝试设置显式编码:
new ByteArrayInputStream(str.getBytes("UTF-8"));
答案 1 :(得分:1)
你已经得到了答案,但这里有一个显而易见的问题是:你为什么要从String
转换为流?这是不必要和浪费的事情 - 所以只需按原样传递String。这也将解决问题;字符串本身没有编码(即:只有一个内存中表示,不需要转换)。