当前位置: 首页 > 知识库问答 >
问题:

Spring boot rest mvc json解析器没有验证非法的或有尾随数据的输入json数据

钱哲茂
2023-03-14

在我的rest客户端中,我传递以下JSON请求数据:

  { 
    "jobName":"test1", 
    "source":{ "name":"prod1","type":"teradata"}, 
    "target":{ "name":"prod2","type":"teradata"}, 
    "objects":{ "name":"table1"}<br/>
    } 
junkdata ; @#%$@#% 

所以额外的“垃圾数据;@#%$@#%“ 未经其余客户端或 spring jackson 开箱即用消息转换器验证。
我确实调试了代码,SpringHttpServletRequest主体具有完整的数据,包括垃圾数据。因此,它没有失败,Spring正在忽略垃圾数据并将起始JSON数据转换为Java对象
我确实尝试在Rest控制器调用中添加注释,例如@JsonFormat@RequestBody(@RestController)。但它没有验证似乎Spring开箱即用的消息转换器jackson没有正确验证传入的请求JSON数据。

共有2个答案

纪佐
2023-03-14

在研究了使用Google gson的不同方法之后.jar,@Pete是的,我已经验证了无效的JSON输入。google 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"}
蓝恩
2023-03-14

现在,spring jackson中修复了这个问题(跟踪令牌或数据失败)https://github.com/FasterXML/jackson-databind/issues/1583使用反序列化功能。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));
    }
}
 类似资料:
  • 问题内容: 我是这个C ++世界的新手,正在尝试为数字密码编写输入验证功能。这是我到目前为止所得到的: 对于不正确的值,它工作得很好,但在有效输入时不会中断循环。知道我在这里缺少什么吗?干杯!! James Kanze脚本的ErroR: 新代码: 使用 和 验证作为字符串 感谢所有人(尤其是James Kanze)的帮助。这件事在这里很有效。 那里还有进一步改进的空间吗?干杯!! 问题答案: 这看

  • 这个程序创建了一个名为datafile.txt的文件,并且应该使用文本I/O将100个随机创建的整数写入文件中。但是,我的输出是“java.util.Random@30c221”100次。我如何得到100个随机数?提前谢谢。

  • 问题内容: 我有一个Json Array作为没有名称的字符串,我想解析它如何在android中进行? 我的JsonArray是: 问题答案: 试试这个..

  • 我正在验证银行的CAB代码。 规则是CAB必须是数字,由5位数字组成。我试图在Laravel 5.3中的FormRequest类中验证这一点 我尝试这样设置验证: 它可以工作,但如果用户在这两个字符之间传递一个普通字符(非数字),则验证将通过,因为字符串长度不超过5个字符。所以这很糟糕。 我尝试这样设置验证: 但是如果用户通过55555,它将失败,因为该数字大于5。 我想知道是否有一种方法可以执行

  • json文档如下所示。我想在qml中为它定义一个类,就像typescript中的关键字一样。 我试图定义一个qml类在文件 那就用吧 但是在键下很难处理对象的向量。因为qml不允许在类A下定义类B。 那么有人知道如何定义强类型类来保存qml中从json解析的对象吗?然后我可以在qtcreator中使用自动完成的类。

  • 问题内容: 我想读取存储在文件中的数据。我尚未决定要存储什么格式,但是我正在寻找一种易于解析的格式。最初我以为我会使用JSON,但似乎Java没有内置的JSON解析器。 存储的数据将是一堆记录,每个记录由一组字段组成。因此,将其存储在可以逐行读取的文本文件中还不够简单。这就是为什么我认为我需要类似JSON的原因。但是我不想添加外部库只是为了解析格式。有什么建议?我是Java新手。 问题答案: 尽管