程序笔记   发布时间:2022-07-11  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Spring MVC 解析JSON入参意外的丢失参数大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

表现

有如下两个接口:

@PostMapping
public R<?> save(@requestBody @Valid ArticleDTO dto) {
    return R.ok(service.saveArticle(dto));
}


@PutMapping
public R<?> updateById(@requestBody @Valid ArticleDTO dto) {
    return R.ok(service.updateArticle(dto));
}

类似的请求参数(同一个页面的表单), 保存时 dto 中大部分属性都是 NULL 更新时则没有任何问题,

确认请求参数已发出, Spring MVC org.springframework.web.servlet.DispatcherServlet 中断点还能看到, 到达Controller 中参数丢失

前提条件:

请求参数包含一个特殊属性: coverUrl 与之对应的控制器入参对象中 coverUrl 类型为 String (AVue Upload 类型表单组件默认值)

{
    ...
  "coverUrl": [],
  "images": [],
    ...
}

项目中 ....common.xss.core.JacksonXssClean 重写了 com.fasterxml.jackson.databind.JsonDeserializer#deserialize 方法, 处理所有的反序列化

deserialize 方法实现如下:

@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    // XSS filter
    String text = p.getValueAsString();
    if (text == null) {
        return null;
    } else if (XssHolder.isEnabled()) {
        String value = XssUtil.clean(text);
        log.trace("Json property value:{} cleaned up by mica-xss, current value is:{}.", text, value);
        return value;
    } else {
        return text;
    }
}

万恶之源

JsonParser.getValueAsString() 方法注释:

方法将尝试将当前标记的值转换为{@link java.lang.String}。JSON字符串自然映射;标量值被转换为它们的文本表示形式。如果表示不能转换为字符串值(包括结构化类型,如对象、数组和空令牌),将返回默认值null;没有抛出异常。

当处理到请求参数: coverUrl 的属性 [ 时, getValueAsString() 直接返回 null 导致方法退出. 后续没有抛出异常, 而是中断所有解析! 也就导致了 content 属性没能正确赋值

而更新方法携带的 coverUrl 属性是查询是返回的, 默认为 NULL, 会跳过 deserialize() 方法的解析. 如果查询结果 coverUrl 非 NULL, 再次提交同样会丢失 coverUrl 之后解析的所有属性 (解析顺序未知, 和入参类型属性的定义顺序, 请求参数的传递顺序 无关)

2021-09-11 02:15:23.502  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 type 	 ArticleDTO(images=null) 	 2 	 2 
2021-09-11 02:15:23.624  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: 2 过滤后: 2

2021-09-11 02:15:23.625  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 title 	 ArticleDTO(images=null) 	 文章标题 	 文章标题 
2021-09-11 02:15:23.625  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: 文章标题 过滤后: 文章标题

2021-09-11 02:15:23.625  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
START_ARRAY 	 coverUrl 	 NULL 	 [ 	 [ 
2021-09-11 02:15:23.625 ERROR 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 下一个令牌: END_ARRAY
2021-09-11 02:15:23.625  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: [ 过滤后: [

2021-09-11 02:15:23.626  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 profile 	 ArticleDTO(images=[]) 	  	  
2021-09-11 02:15:23.626  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原:  过滤后: 

2021-09-11 02:15:23.626  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 content 	 ArticleDTO(images=[]) 	 <p>详情内容</p> 	 <p>详情内容</p> 
2021-09-11 02:15:23.629  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: <p>详情内容</p> 过滤后: <p>详情内容</p>

2021-09-11 02:15:23.631  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 visibleStatus 	 ArticleDTO(images=[]) 	 0 	 0 
2021-09-11 02:15:23.632  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: 0 过滤后: 0

2021-09-11 02:15:23.633  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 
 JSON Token 	 当前属性名 	 当前值 	 当前文本 	 ValueAsString(NULL) 
VALUE_StriNG 	 validStatus 	 ArticleDTO(images=[]) 	 0 	 0 
2021-09-11 02:15:23.633  WARN 10560 --- [  XNIO-1 task-1] n.v.gms.common.xss.core.JacksonXssClean  : 触发XSS过滤, 原: 0 过滤后: 0

2021-09-11 02:15:23.775  INFO 10560 --- [  XNIO-1 task-1] n.v.g.cms.controller.ArticleController   : 新增文章: {"visitor@R_673_10586@l":0,"images":[],"profile":"","sort":9999,"title":"文章标题","type":"2","content":"<p>详情内容</p>","coverUrl":"[","visibleStatus":"0","validStatus":"0","chAnnelId":0}

解决方案

前端页面

删除 coverUrl 属性即可

后端

一个有限的解决方案, 只能处理空数组, 修改 deserialize 方法实现:

@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
    // XSS filter
    // String text = p.getValueAsString();
    
    // Method can be called for any token type.
    String text = p.getText();
    
    // 当前 token 为数组开始字符
    if (p.isExpectedStartArrayToken()) {
        // 快进到下一个 token
        JsonToken jsonToken = p.nextToken();
    }
    
    
    if (text == null) {
        return null;
    } else if (XssHolder.isEnabled()) {
        String value = XssUtil.clean(text);
        log.trace("Json property value:{} cleaned up by mica-xss, current value is:{}.", text, value);
        return value;
    } else {
        return text;
    }
}

对于非空数组, if 中的 jsonToken 会得到 com.fasterxml.jackson.core.JsonToken#VALUE_StriNG 类型枚举, 然后在退出方法后报错

大佬总结

以上是大佬教程为你收集整理的Spring MVC 解析JSON入参意外的丢失参数全部内容,希望文章能够帮你解决Spring MVC 解析JSON入参意外的丢失参数所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。