还记得上次我写过一篇关于实际项目代码分层和规划的文章《看完这篇,别人的开源项目结构应该能看懂了》, 在文尾处提到过一些注意事项,其中第一条就是:

  • Contorller层参数传递建议不要使用HashMap,推荐使用数据模型定义

私信里竟然有很多小伙伴提问说,为什么不能这样做?

我心里暗自寻思:难道这么做的小伙伴都没有被同事捶吗?(滑稽)

得嘞,今天咱们就掰扯掰扯这件事,这是实际写代码时常忽略的一个问题


是不是有人也这么写过?

我自己曾经接手过一个前人留下来的老项目,拿到代码,导入IDEA的那一刻,我哭出了声。


因为它的Controller层代码都是类似这样写的:

@RestController@RequestMapping("/index")public class IndexController {

    // 获取App首页内容    @PostMapping("/getIndexContent")    public ResponseWrapper getIndexContent( @RequestBody Map paramMap ) {

        ResponseWrapper res = new ResponseWrapper();

        // 下面开始做传参有效性的校验        if (!paramMap.containsKey("article_id")) {            res.setCode(500);            res.setMsg("缺少 article_id 信息");            return res;        }

        if (!paramMap.containsKey("page")) {            res.setCode(500);            res.setMsg("缺少 page 信息");            return res;        }

        if (!paramMap.containsKey("size")) {            res.setCode(500);            res.setMsg("缺少 size 信息");            return res;        }

        if (!paramMap.containsKey("version")) {            res.setCode(500);            res.setMsg("缺少 version 信息");            return res;        }

        // ...... 此处省略

    }

    // ...... 此处省略

}

别的咱先不说,居然明目张胆地在Controller层里方法里用Map传参?!简直丧心病狂了。幸亏下面还有一波传参有效性的验证,对于传递的参数,我好歹也能猜个大概,不然那真是喵了个咪了。

接下来,我们就好好唠一唠:为什么不要在Controller层传参时使用Map类型!


Map一时爽,维护爽歪歪

正好,这地方有一个咱小伙伴活生生的例子。

前段时间,有个小伙伴跟我提问交流,说他接手了一个别人的老项目,问了我一个类似这样的问题:


看到没!

Map传参的第一个(也是最大的一个)弊端就是:这会导致后续接手和维护的人怀疑自己的人生,因为他根本不知道代码传的啥参数,想要构造参数去调试接口只能靠脑补摸瞎、以及猜测了。

试想一下,其实我们代码里任何一个地方的传参都可以使用Map来传,如果真的这么做了,代码中连任何数据模型类都不需要定义了,果真如此的话,这样的代码咱能看懂吗?

而且这位小伙伴接手的项目居然还用的是LinkedHashMap参数,可以说很秀了。


除此之外,紧接着还会带来下面这个问题。


好用的API工具与你无缘了

我之前写过一篇文章《前后端都分离了,该搞个好用的API管理系统了!》,聊过现在市面上一些比较好用的、能极大提升前后端开发效率的API管理工具,这对于前后端开发来说,简直是莫大的福音。

我们就以Swagger这个API工具为例,如果Controller传参使用Map的话:

// 获取App首页内容@ApiOperation("获取App首页内容")@PostMapping("/getIndexContent")public ResponseWrapper getIndexContent( @RequestBody Map paramMap ) {

    // ...... 此处省略

}

API工具无法读取具体参数项目和参数类型,所以传参什么的也看不出来:


换言之,我如果将上面的Map传参改为自定义数据模型类IndexQueryDto来传参的话:

// 获取App首页内容@ApiOperation("获取App首页内容(改造后)")@PostMapping("/getIndexContent")public ResponseWrapper getIndexContent( @RequestBody IndexQueryDto indexQueryDto ) {

    // ...... 此处省略

}
@ApiModel(value = "App首页内容请求参数实体对象")class IndexQueryDto {

    @ApiModelProperty(value = "文章ID号")    @NotNull(message = "缺少 article_id 信息")    private Long article_id;

    @ApiModelProperty(value = "页面数")    @NotNull(message = "缺少 page 信息")    private Integer page;

    @ApiModelProperty(value = "每页条目数")    @NotNull(message = "缺少 size 信息")    private Integer size;

    @ApiModelProperty(value = "App版本号")    @NotNull(message = "缺少 version 信息")    private String version;

    // ...... 此处省略set/get方法

}

则类似Swagger这种API工具就非常方便地能帮助我们管理参数了:


这样不管是自己调试,还是前、后端对接口都会方便得多。


同理,除了Swagger这种API管理工具之外,像在我的前文《没用过这些IDEA插件?怪不得写代码头疼》中推荐过的一个非常好用的接口管理插件RestfulToolkit也无法识别出Map类型所盛放的具体参数:


但是对于数据模型的定义参数,就能非常清晰的给出参数细节,并方便地提供接口测试:



优秀的注解没法使用了

还是以文章开头举例的代码来说,不管怎么样,写这段代码的哥们还是负责的,毕竟兢兢业业地用手工连环if()判断完成了所有参数的有效性校验:


但问题是,我们真的需要这种辣眼睛的手工连环if()判断来做参数校验吗?


同样在前文《啥?听说你还在手写复杂的参数校验?》中也说过了,我们其实可以通过注解来方便地规避繁杂的参数校验工作,但前提是不能使用Map类型传参,需要使用数据模型的定义,就像这样:

class IndexQueryDto {

    @NotNull(message = "缺少 article_id 信息")    private Long article_id;

    @NotNull(message = "缺少 page 信息")    private Integer page;

    @NotNull(message = "缺少 size 信息")    private Integer size;

    @NotNull(message = "缺少 version 信息")    private String version;

    // ...... 此处省略get/set方法}

一个NotNull注解即可搞定,它不香吗?


Map传参真的一无是处吗?

有些小伙伴表示用Map传参的好处就是可以随意扩展,后期变动灵活,想往里面塞几个参数就塞几个参数;而且也省去了各种对象定义和命名的烦恼。



如果非要用Map传参

如果实在不能避免用Map传参,也麻请配备完备的测试用例吧,省得让后来接手维护的人天天看着代码怀疑人生了。

通过测试用例,后来接手维护的人也能快速搞清代码间的参数传递和调用,不然真的只能靠脑补画面去调试了。


嘘...

好了,说了这么多,如果你项目的`Controller层代码还在使用HashMap传参的话,答应我,二话别说,赶快全部偷偷去改掉,快!速度!跑步前进!



每天进步一点点,Peace!

2020.04.02晚

给个[在看],是对程序羊最大的支持

@modelattribute注解用postman测试怎么传参_谁要是再敢用Map传参,我过去就是一JIO...相关推荐

  1. 获取map第一个的key和value_谁要是再敢用Map传参,我过去就是一JIO

    还记得上次我写过一篇关于实际项目代码分层和规划的文章<看完这篇,别人的开源项目结构应该能看懂了>, 在文尾处提到过一些注意事项,其中第一条就是: Contorller层参数传递建议不要使用 ...

  2. vue 事件调用 传参_对vue下点击事件传参和不传参的区别详解

    如下所示: {{btn_text1}} {{btn_text2}} var _vm = new Vue({ data : { btn_text1 : '点击1' , btn_text2 : '点击2' ...

  3. iphone和mac互传文件_mac和windows怎么互传文件_让mac和windows电脑互传文件的方法-系统城...

    由于工作需要要用到两台电脑,一台是安装windows电脑,一个则是使用macbook系统.偶尔会需要在两台电脑之间互传文件的需求,虽说QQ和微信可以实现传输,但是如果文件太大还得压缩,显得很麻烦.有什 ...

  4. java flex 上传文件_使用Flex和java servlet上传文件

    资源都是来自网上.本实例将展示使用Flex和java servlet上传文件. 事前准备就是到http://commons.apache.org 下载common-fileupload-1.1.1.j ...

  5. flex java 上传下载_完整的Flex多文件上传实例

    客户端代码:fileUpload.xml-------------------------------------------------------------------------------- ...

  6. java ftp上传失败_使用java进行ftp文件上传出现425错误

    /** * 向FTP服务器上传文件 * @param host FTP服务器hostname * @param port FTP服务器端口 * @param username FTP登录账号 * @p ...

  7. java上传刷新_用ajaxfileupload实现无刷新上传的代码示例

    本篇文章主要介绍了SpringMVC结合ajaxfileupload实现文件无刷新上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下. jQuery没有提供ajax的文件上传,我们可以通过ajax ...

  8. 如何向icloud上传文件_怎样用icloud把手机文件传到电脑上?

    在苹果手机升级到ios11后,就可以用icloud把手机文件传到电脑上了,为此,首先在电脑上下载电脑版icloud并安装.安装完成之后,登陆你的苹果手机ID,然后点击"开始",把鼠 ...

  9. 文件上传漏洞_通达OA前台任意文件上传漏洞+文件包含漏洞导致getshell

    点击蓝字|关注我们 通达OA前台任意文件上传漏洞 +文件包含漏洞导致getshell 一.漏洞介绍/Profile/ 通达OA介绍: 通达OA(Office Anywhere网络智能办公系统)是由北京 ...

最新文章

  1. 关于手机已处理里重复单据的处理办法
  2. Angular2入门教程-1
  3. python打包exe 之打包sklearn模型中的各种坑及其解决方法。
  4. python自学月收入20k_懂Python的资深测开月薪已经20K起啦!我要追上大佬的脚步!...
  5. 轻量级 Kubernetes K3s - Github热点
  6. 新巴巴运动网 项目第十一天
  7. 23种设计模式的优点与缺点概况
  8. c# AutoResetEvent和ManualResetEvent
  9. iptables的连接追踪机制和nf_conntrack调优
  10. return 的理解
  11. wxml、wxss、js 引入外部文件的方法
  12. flashfxpFTP链接显示PASV、列表错误
  13. linux ext4-fs error,Ubuntu 17.04升级后的EXT4-fs错误
  14. 腾讯翻译君在线翻译怎么翻译整个文件_Word文档翻译:分享下面几种方法
  15. arcgis自动完成面怎么用_ArcGIS 自动生成线或者面
  16. 程序员面试中注意事项
  17. 中级程序员还应该如何提高自己
  18. 快捷键没有响应的处理办法
  19. 《数学之美》读后感与商榷
  20. 在同时使用label和input标签下下label绑定click事件执行两次的问题

热门文章

  1. python3 可执行文件_将python3打包成为exe可执行文件(pyinstaller)
  2. 5000并发的qps是多少_高并发架构设计
  3. 怎么读取matlab程序包,Nifti程序包,用于写入,读取和处理医学影像,适用于MATLAB
  4. 利用python转换图片格式
  5. linux 内存溢出排查_【开发者成长】JAVA 线上故障排查完整套路!
  6. mysql一图秒懂秒清晰 - join连接 ,left join左连接 ,right join右连接 ,inner join内连接
  7. Java用sqlit拆分小数_如何将SQLite列中的分隔值拆分为多列
  8. 搞不懂,为啥现在什么公司都在考算法???
  9. 数据还是模型?人类知识在深度学习里还有用武之地吗?
  10. AC算法在美团上单系统的应用