这问题巧了,SpringMVC 不同参数处理机制引发的思考

这篇具有很好参考价值的文章主要介绍了这问题巧了,SpringMVC 不同参数处理机制引发的思考。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这个问题非常有趣,不是SpringMVC 的问题,是实际开发中混合使用了两种请求方式暴露出来的。

问题场景

功能模块中,提供两个 Http 服务。一个是列表查询(application/json 请求),一个是列表导出(表单请求)。运行环境发现个问题:MVC model 新添加的属性,类似的 Http 请求,一个有值,一个没有

代码如下:

/**
 * application/json 请求。 这种情况 param.field2 有值 ✔
 * @param param RequestResponseBodyMethodProcessr 处理 HttpServletRequest 参数
 */
@PostMapping(value = "query")
public ResponseResult<Page<SomeData>> queryByCondition(@RequestBody SomeParam param){
    // 业务逻辑...
}

/**
 * application/x-www-form-urlencoded 请求 这种情况 param.field2 没有有赋值 ❌
 * @param param ServletModelAttributeMethodProcessor 处理 HttpServletRequest 参数
 */
@PostMapping(value = "export")
public void exportExcel(SomeParam param) {
    // 业务逻辑...
}


public class SomeParam {

    // 这个是原有的,有 get set 方法
    private String field1;

    // 这个是新增的,没有get set 方法 (这是一个巧合、意外)。 问题就出在这里。
    private String field2;

}

❓ 根据代码分析,那应该是 SpringMVC 针对这两种参数处理的机制不同。
针对上述的参数处理,可以参考:
RequestResponseBodyMethodProcessor、 ServletModelAttributeMethodProcessor

Insight RequestResponseBodyMethodProcessor

处理 Http Body 的数据。解析注解 RequestBody 的参数。

针对 MimeType 为 application/json 的请求,按照json 格式进行反序列化。

默认参数处理器
MappingJackson2HttpMessageConverter

string 反序列化为对象,使用的是
com.fasterxml.jackson.databind.ObjectMapper。

上述工程中,对 ObjectMapper 开启 private 属性检测。新增的属性可以正常反序列化。

ObjectMapper mapper = new ObjectMapper();
// 这又是一个巧合、意外  咋还有这个用法 
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

Visibility 具体的用法示例参考: Jackson - Decide What Fields Get (De)Serialized | Baeldung

原理: 如果没有 setter 方法,jackson 会操作 field 来完成赋值。

/**
 * This concrete sub-class implements property that is set directly assigning to a Field.
 */
public final static class FieldProperty extends SettableBeanProperty {

    @Override
    public final void set(Object instance, Object value) throws IOException {
        try {
            _field.set(instance, value);
        } catch (Exception e) {
            _throwAsIOE(e, value);
        }
    }
}

Insight ServletModelAttributeMethodProcessor

自定义 Class 参数解析

通过解析 request parameters, 用来构造和初始化对应的方法入参。

主要通过
ServletRequestDataBinder.bind(request) 来完成。

/**
 * Apply given property values to the target object.
 * By default, unknown fields will be ignored.
 * 
 * @see org.springframework.validation.DataBinder#applyPropertyValues
 */
protected void applyPropertyValues(MutablePropertyValues mpvs) {
	try {
		// Bind request parameters onto target object.
		// 默认使用 BeanWrapperImpl.setPropertyValue()
		getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields());
	}
	catch (PropertyBatchUpdateException ex) {
		// Use bind error processor to create FieldErrors.
	}
}
public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {
    // 通过遍历 request parameters 来尝试对 target 进行赋值
	List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ? 			((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
	for (PropertyValue pv : propertyValues) {
		try {
			// etPropertyValue 使用 JDK 的 Introspector 来进行序列化操作。
            // 没有setter 方法,自然没法赋值。
			setPropertyValue(pv);
		}
	}
}

总结

  • 一件事情出错,不是一处问题造成的。
  • 工程开发要规范,用最常规、最稳定的办法来实现。遇到稀奇古怪的问题就是冷门用法带来的。
  • 对于常用的框架和工具库熟悉其底层原理,遇到问题可以很快定位。

作者:京东物流 杨攀

来源:京东云开发者社区文章来源地址https://www.toymoban.com/news/detail-502003.html

到了这里,关于这问题巧了,SpringMVC 不同参数处理机制引发的思考的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • epoll准备就绪列表保护机制,引发的锁问题讨论

    epoll 就绪队列应该使用什么数据结构?为什么? 在 Nginx 中,就绪队列通常使用链表来实现。具体来说,就绪队列是一个双向链表,其中每个节点都包含了一个 ngx_event_t 结构体,用于表示一个已经准备就绪的事件。当 epoll 检测到某个文件描述符上有 I/O 事件发生时,就会将相应

    2023年04月13日
    浏览(40)
  • 记一次线上问题引发的对 Mysql 锁机制分析

    最近双十一开门红期间组内出现了一次因 Mysql 死锁导致的线上问题,当时从监控可以看到数据库活跃连接数飙升,导致应用层数据库连接池被打满,后续所有请求都因获取不到连接而失败 整体业务代码精简逻辑如下: 数据库实例监控: 当时通过分析上游问题流量限流解决后

    2024年02月05日
    浏览(56)
  • cesium内部相同坐标在不同高度的2个点的属性机制坐标会gltf模型角度值异常问题mars3d的处理办法

    模型一直向上运动的正常效果: 问题场景: 1.new mars3d.graphic.ModelPrimitive({使用addDynamicPosition(设置并添加动画轨迹位置,按“指定时间”运动到达“指定位置”时发现,如果是同一个点位不同高度值的y轴竖直向上方向的运动。 指定pitch:270偏转角度的时候,会出现模型的角度值

    2024年01月18日
    浏览(47)
  • SpringMVC拦截器和异常处理机制

    SpringMVC拦截器类似于过滤器,用于进行预处理和后处理 将拦截器按照一定顺序连接成一条链,就是拦截器链 创建拦截器类实现HandlerInterceptor接口 配置拦截器 测试拦截器的拦截效果 三个方法的执行:在配置文件中依次配置两个拦截器分别为1和2,则执行顺序是:1的 preHandle

    2024年02月16日
    浏览(55)
  • 【SpringMVC】JSON注解&全局异常处理机制

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是 Java方文山 ,一个在CSDN分享笔记的博主。📚📚 🌟在这里,我要推荐给大家我的专栏《Spring MVC》。🎯🎯 🚀无论你是编程小白,还是有一定基础的程序员,这个专栏都能满足你的需求。我会用最简单易懂的语言,带你走进Spring

    2024年02月08日
    浏览(37)
  • SpringMVC中的拦截器不生效的问题解决以及衍生出的WebMvcConfigurationSupport继承问题思考

    过滤器代码(被Spring扫描并管理): 过滤器配置代码: 按理说我们发出请求 localhost/stu 之后,应该可以看到过滤器的效果,但是失效了。 网上的说法众说纷纭: 没加@Component或者@Configuration注解 @ComponentScan没扫描到 路径配置错了 以上三种说法一一排除之后,我发现一个博客提

    2024年02月01日
    浏览(39)
  • SpringMVC之JSON返回及异常处理机制

    目录 一、JSON处理 1.1 导入依赖 1.2 配置Spring-mvc.xml 1.3 @ResponseBody注解使用 ​编辑 1.4 Jackson 1.4.1 定义 1.4.2 用途  1.4.3 用法  1.4.4 常用注解 1.5 作用 二、统一异常处理 2.1 为什么要全局异常处理? 2.2 异常处理思路 2.3 SpringMVC异常分类 2.4 综合案例 2.4.1 异常处理方式一 2.4.2 异常处

    2024年02月09日
    浏览(36)
  • SpringMVC之JSON数据返回与异常处理机制

    目录 一.SpringMVC的JSON数据返回 1.导入Maven依赖 2.配置spring-mvc.xml 3.@ResponseBody注解的使用 3.1案例演示 1.List集合转JSON  2.Map集合转JSON  3.返回指定格式String 4. @ResponseBody用法  5.Jackson 5.1介绍 5.2常用注解 二.异常处理机制  1.为什么要全局异常处理 2.异常处理思路 3.SpringMVC异常分类

    2024年02月08日
    浏览(41)
  • “深入理解SpringMVC的JSON数据返回和异常处理机制“

    在现代Web开发中,SpringMVC是一个广泛使用的框架,它提供了丰富的功能和灵活的配置选项。本文将深入探讨两个重要的主题:SpringMVC中的JSON数据返回和异常处理机制。我们将逐步介绍相关的配置和使用方法,并通过案例和综合实例来加深理解。 1.1 导入依赖 1.2 配置弹簧-MVC

    2024年02月08日
    浏览(33)
  • 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam

    😀前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉 在csdn获奖荣誉: 🏆csdn城市之星2名 ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包