在我的休息客户端中,我传递了以下JSON请求数据:
{
"jobName":"test1",
"source":{ "name":"prod1","type":"teradata"},
"target":{ "name":"prod2","type":"teradata"},
"objects":{ "name":"table1"}<br/>
}
junkdata ; @#%$@#%
所以额外的&#34; junkdata; @#%$ @#%&#34;未经其他客户或Spring jackson开箱即用的消息转换器验证 我做了调试代码,spring HttpServletRequest正文包含完整的数据,包括垃圾数据。因此,它没有失败,Spring忽略了垃圾数据并将起始JSON数据转换为Java对象 我尝试在休息控制器调用(@RestController)中为@RequestBody添加@JsonFormat等注释。但它没有验证似乎Spring开箱即用的消息转换器jackson没有正确验证传入的请求JSON数据。
答案 0 :(得分:0)
在我获得解决方案的不同方式之后,@ Pete yes我已经验证了无效的JSON输入。 谷歌gson api正在验证它,我们需要使用自定义消息转换器在其余的WebMvcConfigurationSupport类中验证它。
@Configuration
@ComponentScan(basePackages = { "com.teradata.datamovement.rest.controllers",
"com.teradata.rest.controller" })
public class RestControllerConfiguration extends WebMvcConfigurationSupport
{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
log.debug("Adding custom message converter.");
converters.add(new AbstractHttpMessageConverter<Object>(MediaType.APPLICATION_JSON, new MediaType("application", "*+json")){
@Override
protected Object readInternal(Class<? extends Object> clazz,
HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
try{
log.debug("Converting and validating the http request body data.");
String httpRequestBody = convertStreamToString(inputMessage.getBody());
log.debug("Http request body data:"+httpRequestBody);
return new Gson().fromJson(httpRequestBody, clazz);
}
catch(JsonSyntaxException e){
throw new HttpMessageNotReadableException("Invalid input JSON data: " + e.getMessage(), e);
}
}
private String convertStreamToString(InputStream is) throws IOException {
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
@Override
protected boolean supports(Class clazz) {
return true;
}
@Override
protected void writeInternal(Object t, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
outputMessage.getBody().write(new Gson().toJson(t).getBytes());
}
});
}
}
但我注意到的奇怪之处在于,只有当我将它作为匿名类或通过在同一个文件中添加类时才能工作。如果我在这个RestControllerConfiguration.java文件旁边创建这个自定义消息转换器,那么它不会验证它。 这是一个例子:
{
"jobName":"test1",
"source":{ "name":"prod1","type":"teradata"},
"target":{ "name":"prod2","type":"teradata"},
"objects":{ "name":"table1"}
}
junkdata ; @#%$@#%
这将得到验证,并将抛出错误,如
{"message":"Invalid input JSON data: com.google.gson.stream.MalformedJsonException: Expected EOF at line 7 column 1; nested exception is com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected EOF at line 7 column 1"}
答案 1 :(得分:0)
现在,此问题(基于尾随令牌或数据失败)已在春季杰克逊https://github.com/FasterXML/jackson-databind/issues/1583中修复 使用DeserializationFeature.FAIL_ON_TRAILING_TOKENS,这是解决此问题的代码示例:
@Configuration
public class RestControllerConfiguration extends WebMvcConfigurationSupport
{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true);
converters.add(new MappingJackson2HttpMessageConverter(objectMapper));
}
}