全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2023-12-18_《优化接口设计的思路》——接口参数的一些弯弯绕绕

您的位置:首页 >> 新闻 >> 行业资讯

《优化接口设计的思路》——接口参数的一些弯弯绕绕 本文参考项目源码地址:summo-springboot-interface-demo 前言大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 作为一名从业已达六年的老码农,我的工作主要是开发后端Java业务系统,包括各种管理后台和小程序等。在这些项目中,我设计过单/多租户体系系统,对接过许多开放平台,也搞过消息中心这类较为复杂的应用,但幸运的是,我至今还没有遇到过线上系统由于代码崩溃导致资损的情况。这其中的原因有三点:一是业务系统本身并不复杂;二是我一直遵循某大厂代码规约,在开发过程中尽可能按规约编写代码;三是经过多年的开发经验积累,我成为了一名熟练工,掌握了一些实用的技巧。 接口参数是导致很多BUG产生的始作俑者,原因在于接口参数有3多:接口参数的取值地方多,如查询参数(Query Parameters)、路径参数(Path Parameters)、请求体(Request Body)等;数据类型多,如数字、字符、日期、文件等;判断情况多,如空值判断、格式判断、大小判断等; 一、接口参数的取值1. 放在查询参数和请求体里 a、方法参数示例代码如下: @GetMapping("/testParams1") publicResponseEntityStringtestParams1(Stringparam1,Integerparam2){ returnResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]",param1,param2)); } 调用请求:http://localhost:8080/testParams1?param1=111¶m2=222返回如下: 没啥坑。 b、请求对象GET请求示例代码如下 @GetMapping("/testParams2") publicResponseEntityStringtestParams2(ParamsReqparamsReq){ returnResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]",paramsReq.getParam1(),paramsReq.getParam2())); } ParamsReq.java publicclassParamsReq{ privateStringparam1; privateStringparam2; publicParamsReq(){ } publicParamsReq(Stringparam1,Stringparam2){ this.param1=param1; this.param2=param2; } publicStringgetParam1(){ returnparam1; } publicvoidsetParam1(Stringparam1){ this.param1=param1; } publicStringgetParam2(){ returnparam2; } publicvoidsetParam2(Stringparam2){ this.param2=param2; } @Override publicStringtoString(){ return"ParamsReq{"+ "param1='"+param1+'\''+ ",param2='"+param2+'\''+ '}'; } } 调用请求:http://localhost:8080/testParams2?param1=111¶m2=222返回如下: 这种有一个坑,Spring默认使用无参构造函数来实例化对象,所以ParamsReq不能是接口、抽象类等特殊类。 POST请求示例代码如下: @PostMapping("/testParams3") publicResponseEntityStringtestParams3(ParamsReqparamsReq){ returnResponseEntity.ok(MessageFormat.format("param1:[{0}];param2:[{1}]",paramsReq.getParam1(),paramsReq.getParam2())); } ParamsReq类代码同上 调用方式1:参数放在链接上和GET请求类似,没啥坑。 调用方式2:放在Form表单中,content-type为application/x-www-form-urlencoded没啥坑。 调用方式3:放在body参数中,content-type为application/json这里有坑了,当content-type为application/json时,接口参数取值为空。这时就需要在参数前加上一个注解:@RequestBody,原因是通过@RequestBody注解,Spring Boot可以自动地将请求体中的JSON数据转换为Java对象,从而方便地进行数据的处理和转换。如果不加@RequestBody注解,Spring Boot默认会将请求体中的JSON数据作为普通的表单数据来处理,而不会自动转换为Java对象。: 改成这样就行:public ResponseEntityString testParams3(@RequestBody ParamsReq paramsReq) 2. 放在路径参数上 示例代码如下: @GetMapping("/testParams4/{pathParam}") publicResponseEntityStringtestParams4(@PathVariable("pathParam")StringpathParam){ returnResponseEntity.ok(MessageFormat.format("pathParam:[{0}];",pathParam)); } 参数使用{和}框起来,然后使用@PathVariable即可获取到值,坑不多。 3. 放在请求头和Cookie 这两种情况里面的参数主要是标识类的参数如userToken,一般都是不变的,业务中很少使用到。 二、接口参数的类型1. 数字、字符串 没啥坑。 2. 日期 示例代码如下: @GetMapping("/testParams5") publicResponseEntityStringtestParams5(Datedate){ returnResponseEntity.ok(MessageFormat.format("pathParam:[{0}];",date)); } 这里有个问题,这样的接口前端怎么传这个date值,字符串?时间戳?我已经替大家试过了,都不行,接口直接报400。 正确的做法是在日期参数前加上@DateTimeFormat注解,改成这样就行了:public ResponseEntityString testParams5(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date date)。传参的话传字符串:2023-09-14 00:00:00 即可 3. 列表 示例代码如下: @GetMapping("/testParams6") publicResponseEntityStringtestParams6(ListIntegerparamList){ returnResponseEntity.ok(MessageFormat.format("paramList:[{0}];",paramList)); } 这串代码不用测试,它本身就是错误的,前面说过Spring默认使用无参构造函数来实例化对象,但是List是一个接口,没有无参构造函数。为了解决这个问题,可以使用Spring的@RequestParam注解来指定参数名,并将多个参数值绑定到一个List对象中。 修改代码如下:public String testParams6(@RequestParam("paramList") ListInteger paramList) 即可 然后,通过使用逗号分隔的参数值来访问接口,如:http://localhost:8080/testParams6?paramList=1,2,3这样就可以成功传递参数列表并访问接口了。 4. 文件 先写一个简单上传界面 upload.html !DOCTYPEhtml html head titleFileUploadDemo/title /head body h1FileUploadDemo/h1 formaction="http://localhost:8080/upload"method="post"enctype="multipart/form-data" inputtype="file"name="file"/ br/br/ inputtype="submit"value="Upload"/ /form /body /html 后端上传代码 FileUploadController.java importorg.springframework.http.HttpStatus; importorg.springframework.http.ResponseEntity; importorg.springframework.stereotype.Controller; importorg.springframework.web.bind.annotation.PostMapping; importorg.springframework.web.bind.annotation.RequestParam; importorg.springframework.web.multipart.MultipartFile; @Controller publicclassFileUploadController{ @PostMapping("/upload") publicResponseEntityStringuploadFile(@RequestParam("file")MultipartFilefile){ //Checkiffileisempty if(file.isEmpty()){ returnnewResponseEntity("Fileisempty",HttpStatus.BAD_REQUEST); } //Savethefile try{ byte[]bytes=file.getBytes(); //Logictosavethefiletoadesiredlocation returnnewResponseEntity("Fileuploadedsuccessfully",HttpStatus.OK); }catch(Exceptione){ returnnewResponseEntity("Failedtouploadfile",HttpStatus.INTERNAL_SERVER_ERROR); } } } 上传接口后端其实还好,主要是前端需要处理的内容多一些,由于MultipartFile类也是一个接口,所以这里也需要加上@RequestParam注解。 三、接口参数的判断前面提到的@RequestBody、@RequestParam注解都是SpringBoot自带的,它们主要的功能是将请求参数转换为我们接口定义的变量或者Java对象,而校验参数值是否合法通常有下面几种做法: 自己写校验逻辑,一般是配合使用Assert进行参数校验使用javax.validation包的校验注解,如@NotNull、@NotBlank这里主要讲一下javax.validation如何使用! 1. pom.xml引入 !--接口参数校验-- dependency groupIdjavax.validation/groupId artifactIdvalidation-api/artifactId version2.0.1.Final/version /dependency 2. 注解分类 a. 空值检查注解说明使用频率@NotNull不能为null,常用于数字、日期常用@NotBlank不能为null也不能为空,常用于字符串常用@NotEmpty集合不能为空,常用于List、Map、Set常用b. 数值检查注解说明使用频率@Max被注释的元素必须小于等于指定的值常用@Min被注释的元素必须大于等于指定的值常用@Positive被注释的元素必须是正数不常用@Negative被注释的元素必须是负数不常用c. Boolean 检查注解说明使用频率@AssertFalse被注释的元素必须是false常用@AssertTrue被注释的元素必须是true常用d. 日期检查注解说明使用频率@Future被注释的元素必须是将来的日期不常用@Past被注释的元素必须是过去的日期不常用e. 日期检查注解说明使用频率@Email被注释的元素必须是电子邮箱地址常用@Pattern被注释的元素必须是符合正则表达式,我经常使用这个判断手机号是否合法常用3. 使用方法 下面是一个经典的案例 @Data publicclassStudentReq{ @NotBlank(message="主键不能为空") privateString @NotBlank(message="名字不能为空") @Size(min=2,max=4,message="名字字符长度必须为2~4个") privateStringname; @Pattern(regexp="^1[3456789]\\d{9}$",message="手机号格式错误") privateStringphone; @Email(message="邮箱格式错误") privateStringemail; @Past(message="生日必须早于当前时间") privateDatebirth; @Min(value=0,message="年龄必须为0~100") @Max(value=100,message="年龄必须为0~100") privateInteger @PositiveOrZero privateDoublescore; } 这些东西看看就行了,用的时候翻一下文档就行,记也记不住。 四、一些可以直接获取到的参数HttpServletRequest:用于获取HTTP请求的相关信息,包括请求头、请求参数、请求方法等。HttpServletResponse:用于控制HTTP响应,包括设置响应状态码、设置响应头、发送响应内容等。HttpSession:用于获取当前会话的信息,可以用来存储和获取会话级别的数据。Principal:用于获取当前用户的身份信息,通常用于认证和授权。Model/ModelMap:用于在请求处理方法中传递数据给前端视图。BindingResult:用于获取请求参数绑定和验证的结果,包含了校验的错误信息。Locale:用于获取当前请求的语言环境,可以用来进行国际化处理。MultipartFile(或者List):用于处理上传的文件,包括文件的名称、大小、内容等。RedirectAttributes:用于在重定向时传递数据给目标页面。ServletRequest/ServletResponse:HttpServletRequest/HttpServletResponse的父类,可以使用其提供的通用方法。@ModelAttribute注解:用于获取请求参数,并将其绑定到一个对象上。这些对象可以直接在接口参数上使用,通过框架自动注入的方式获取其实例。在使用时,需要保证框架已经正确配置和启用了对应的注解和拦截器。用的最多的就是HttpServletRequest和HttpServletResponse了。 阅读原文

上一篇:2017-01-12_公告 | 招聘 下一篇:2025-03-14_FP8模型不再挑卡!DeepSeek推理成本减半速度翻番,清华团队开源「赤兔」推理引擎

TAG标签:

16
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价