谁要是再敢用Map传参,我过去就是一JIO

image


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

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

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

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

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


是不是有人也这么写过?

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

image

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

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

    // 获取App首页内容
    @PostMapping("/getIndexContent")
    public ResponseWrapper getIndexContent( @RequestBody Map<String, Object> 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一时爽,维护爽歪歪

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

记得之前有个小伙伴提问,问过一个这样的问题,说他接手了一个别人的老项目,问了我一个类似这样的问题:

image

看到没!

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

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

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

image

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


好用的API工具与你无缘了

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

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

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

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

}

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

image

换言之,我如果将上面的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工具就非常方便地能帮助我们管理参数了:

image

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


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

image

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

image


优秀的注解没法使用了

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

image

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

image

同样在前文《啥?听说你还在手写复杂的参数校验?》中也说过了,我们其实可以通过注解来方便地规避繁杂的参数校验工作,但前提是不能使用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传参的好处就是可以随意扩展,后期变动灵活,想往里面塞几个参数就塞几个参数;而且也省去了各种对象定义和命名的烦恼。

image


如果非要用Map传参

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

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


嘘...

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

image

#Java工程师#
全部评论
b站
1 回复 分享
发布于 2020-04-30 09:47
还好吧  感觉只需要创建单表的bean,多表查询用map多方便啊😂
点赞 回复 分享
发布于 2021-04-26 10:26
我也在公众号看到过这篇文章 没想到 养哥在 牛客也有发文章呀 优秀优秀!🤣
点赞 回复 分享
发布于 2020-04-30 09:45
我怎么记得我在公众号上看过
点赞 回复 分享
发布于 2020-04-05 20:33
&平时最喜欢这么干😂😂
点赞 回复 分享
发布于 2020-04-05 18:22
&我之前实习公司,有个数据端接口response 竟然是二位数组,每一个字段都要猜。文档也没。也不说清楚。
点赞 回复 分享
发布于 2020-04-05 16:09
&杨哥666
点赞 回复 分享
发布于 2020-04-05 13:08
我们小组都是用jsonobject传参数的🤔🤔。我也惊呆了
点赞 回复 分享
发布于 2020-04-05 12:05
我怎么记得在B站看过😢
点赞 回复 分享
发布于 2020-04-05 11:48

相关推荐

2025-12-24 08:50
已编辑
上海工程技术大学 数据分析师
9.21-28参加第一轮七牛云秋招项目比赛,三人组队做一个AI角色对话网站。我们的目标是争取拿offer和前16名的奖金(最低500元)10.11打电话通知我们准备参加终面10.14参加终面(官网上说就一次终面),面试官为技术人员。我们来回路程4小时。10.23打电话通知我们,进了前20,10.27还有一次路演面试,评出前16名10.27再次参加终面,面试官为高管。来回路程4小时,告知我们一周内出结果。10.31在群里询问是否出结果,没有回复。11.5公司人员告知第一批有一波通知结果了,另外还有一波。11.12一位队员收到offer,两位队员被拒绝,评奖没消息。12.2在群里询问公司人员是否有消息,一位公司人员退群,没有回复。12.4在群里询问公司人员是否有消息,说是会帮忙反馈。12.12我们打听到HR主动告知某位参赛选手获奖500元。12.13在群里询问是否有消息,公司人员说在最终确认中,近期会联系,或者通过官网了解情况。12.23在群里询问是否有结果,公司人员告知没有获奖。————分割线————图1图2为群里聊天记录,图3为奖项设置,可怜的学生党为了个offer和500块都被硬拖3个月。我说实话辛苦了一周做项目参加比赛,没有offer,没有获奖也是做好心理准备的,但是不能这么无视我们的消息,并且拖着我们三个月吧。所有的方案、代码、产品说明文档等等参赛资料都是公开透明提交给公司的,我在的群参赛者大群是第11个,200多人,最多三人一队,有两批比赛,所以至少上百个队伍,上百个方案吧,很难说不是白嫖这么大规模的方案和创意。中间在群里问比赛结果,每次要么是不回复,要么是说问问负责人,还在确定中等等,然后就拖着。10月23号前20都已经出来了,排个名次要整整2个月吗?一直到今天12月23号跟我们说没获奖(不知道是不是因为队员没有接受他们offer的原因,给的薪资白菜价,所以队员拒绝了offer)官网说的第一批十月中旬公布结果,结果到现在花了3个月时间,之前有别人说是不是来窃取创意的,我还说这么大公司不至于吧。现在看来就是来白嫖方案的,做项目做了一个星期,后面又花精力,又花时间的做PPT搞了两次终演,最后因为队伍不是公司招聘候选,所以这么无视我们?
程序员小白条:七牛云好几年这样的事情了,这玩意都是潜规则搞好的,没啥,能有这能力的,说实话也不去七牛云了
秋招落幕,你是He or...
点赞 评论 收藏
分享
2025-12-26 10:52
河北传媒学院 Java
点赞 评论 收藏
分享
评论
4
14
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务