HandlerMethodArgumentResolver(四):自定参数解析器处理特定场景需求,介绍PropertyNamingStrategy的使用【享学Spring MVC】(下)

简介: HandlerMethodArgumentResolver(四):自定参数解析器处理特定场景需求,介绍PropertyNamingStrategy的使用【享学Spring MVC】(下)
场景二:


在微服务场景中有个特别常见的现象:跟第三方服务做对接时(如python老系统),你不乏会遇到如下两个痛点:


  1. 对方系统是以下划线形式命名的(和Java命名规范相悖)
  2. 对方系统的参数json串层次较深,而对你有用的仅仅是深处的一小部分


例如这个参数串:


{
    "data": {
        "transport_data": {
            "demo_name": "fsx",
            "demo_age": 18
        },
        "secret_info": {
            "code": "fkldshjfkldshj"
        }
    },
    "code": "200",
    "msg": "this is a message"
}


对你真正有用的只有demo_name和demo_age两个值,怎么破???

我相信绝大部分小伙伴都这么做:按照此结构先定义一个DTO全部接收回来(字段命名也用下划线方式命名),然后再一个个处理。若这么做虽然简单,我觉得还是有如下两个不妥的地方:


Java属性名也必须用下划线命名,看起来影响了命名体系(其实就是看着不爽,哈哈)

按照参数这种复杂结构书写,使得我们关注点分散,不能聚焦到真真关心的那一块数据上

针对这些痛点,废话不多说,直接上我的处理方案:


1、定义一个模型(只写我自己关注的属性)

@Getter
@Setter
@ToString
public class TranUserVo {
    private String demoName;
    private Long demoAge;
}


定义的模型非常之简单,不仅只关心我要的数据,而且还是标准的java驼峰命名,没必要去迁就别的语言而丧失自己优雅性,否则容易把自己弄得四不像(万一又接python,又接.net呢?)~


2、自定义一个参数解析器并且注册上去


public class TranUserArgumentResolver implements HandlerMethodArgumentResolver {
    // 只处理这个类型,不需要注解
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Class<?> parameterType = parameter.getParameterType();
        return TranUserVo.class.isAssignableFrom(parameterType);
    }
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        HttpMethod httpMethod = HttpMethod.valueOf(request.getMethod());
        // 本例为了简单,演示get的情况(这里使用key为:demoKey)
        if (httpMethod == HttpMethod.GET) {
            String value = request.getParameter("demoKey");
            JSONObject transportData = (JSONObject) ((JSONObject) JSON.parseObject(value).get("data")).get("transport_data");
            // 采用命名策略,转换TranUserVo实例对象再返回
            // 序列化配置对象
            ParserConfig config = new ParserConfig();
            config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
            TranUserVo tranUserVo = transportData.toJavaObject(TranUserVo.class, config, 0);
            return tranUserVo;
        } else { // 从body提里拿
            // ...
            return null;
        }
    }
}
// 注册此自定义的参数解析器
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new TranUserArgumentResolver());
}


对此部分我说明一点:对于json到对象的解析,理应还加上@Valid校验的能力的,此部分我就省略了,毕竟也不是本文所关心的重点


测试用例:


@ResponseBody
@GetMapping("/test/tranuser")
public Object testCurrUser(TranUserVo tranUser) {
    return tranUser;
}


请求:/test/tranuser?demoKey=上面那一大长串json串,得到的结果就是预期的结果喽:


image.png


完美~


说明:这种长传现在需要使用post/put传递,本文只是为了简化演示,所以使用了GET请求,毕竟解析Body体不是本文所需讨论的~


总结


我认为,自定义参数解析器HandlerMethodArgumentResolver最重要不是它本身的实现,而是它的指导思想:分离关注,业务解耦。当然本文我摘出来的两个使用场景案例只是冰山一角,各位需要举一反三,才能融会贯通。


既然我们可以自定义参数处理器HandlerMethodArgumentResolver,自然也就可以自定义返回值处理器HandlerMethodReturnValueHandler喽,作为课后作业,有兴趣者不妨一试,还是非常有作用的。特别在处理"老项目"的兼容性上非常好使,或许能让你大放异彩~

相关文章
|
3月前
|
并行计算 数据挖掘 大数据
[go 面试] 并行与并发的区别及应用场景解析
[go 面试] 并行与并发的区别及应用场景解析
|
22天前
|
JSON 前端开发 Java
Spring MVC——获取参数和响应
本文介绍了如何在Spring框架中通过不同的注解和方法获取URL参数、上传文件、处理cookie和session、以及响应不同类型的数据。具体内容包括使用`@PathVariable`获取URL中的参数,使用`MultipartFile`上传文件,通过`HttpServletRequest`和`@CookieValue`获取cookie,通过`HttpSession`和`@SessionAttribute`获取session,以及如何返回静态页面、HTML代码片段、JSON数据,并设置HTTP状态码和响应头。
41 1
Spring MVC——获取参数和响应
|
8天前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
91 1
|
24天前
|
存储
让星星⭐月亮告诉你,HashMap的put方法源码解析及其中两种会触发扩容的场景(足够详尽,有问题欢迎指正~)
`HashMap`的`put`方法通过调用`putVal`实现,主要涉及两个场景下的扩容操作:1. 初始化时,链表数组的初始容量设为16,阈值设为12;2. 当存储的元素个数超过阈值时,链表数组的容量和阈值均翻倍。`putVal`方法处理键值对的插入,包括链表和红黑树的转换,确保高效的数据存取。
50 5
|
26天前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
51 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
90 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】

推荐镜像

更多