Bootstrap

Swagger2 | 05. 使用Swagger2调试时,部分接口不可传入参数

1. 发现问题

在使用swagger2生成接口文档时,发现参数能正常显示出来,但是在调试的时候,有的却不能传入参数
在这里插入图片描述

在这里插入图片描述

2. 推敲尝试

2.1. 不同之处①:提交方式

第一个接口提交方式为GET,第二个接口提交方式为PUT
试着将第二个接口提交方式换成GET
结果成功了。
但与此同时,发现请求类型从原来的body变成了query
在这里插入图片描述

2.2. 不同之处②:请求类型

仔细观察,第一个接口(可以传参)的参数请求类型为query
第二个接口(不可传参)的参数请求类型为body

那是否和请求类型有关呢?

带着这样的疑问,在第二个接口请求方式仍然是PUT的情况下,将参数请求类型改成query

结果成功了,在PUT请求类型下,也可以传入参数进行调试

	@ApiOperation(value = "使邮件状态变为已解决")
	//原来是用@Param注解,这样参数的请求类型被设置成了"body"
	//现在用@ApiImplicitParams和@ApiImplicitParam注解,手动将请求类型设置成"query"
	@ApiImplicitParams({
			@ApiImplicitParam(name = "emailId", value = "邮件id", required = true, paramType = "query")
	})
	@PutMapping("settleEmail")
	public Result<Integer> settleEmail(int emailId) {
		return new Result<>(emailService.settleEmail(emailId));
	}

2.3. 反复尝试

经过多次尝试,发现有以下结论
(1) 能否在调试中传参,和请求方式(GET,POST,PUT,DELETE)无关
(2) 如果有多个body请求类型的参数,在调试中可以传参
(3) 如果只有一个body请求类型的参数,在调试中不可传参

3. 总结

3.1. 请求类型为body,且参数唯一时无法传参

使得接口在调试时无法传参的原因,并不在于请求的方式(PUT,GET)

关键在于请求类型。如果参数唯一,且请求类型为body,则无法在调试中传参。

3.2. 解决方案:设置请求类型为query

使用@ApiImplicitParams和@ApiImplicitParam注解,然后设置paramType属性即可(原来的@ApiParam注解无法设置请求类型)

同时记得使用dataType属性指定参数类型,否则swagger2将统一解析为String,高版本(3.0.0)甚至会在控制台报错。

	@ApiImplicitParams({
			@ApiImplicitParam(name = "file", dataType = "MultipartFile", value = "附件", required = false, paramType = "query"),
			@ApiImplicitParam(name = "emailTitle", dataType = "String", value = "邮件标题", required = true, paramType = "query"),
			@ApiImplicitParam(name = "emailType", dataType = "String", value = "邮件类型", required = true, paramType = "query"),
			@ApiImplicitParam(name = "emailContent", dataType = "String", value = "邮件内容", required = true, paramType = "query"),
			@ApiImplicitParam(name = "emailAttachment", dataType = "int", value = "是否有附件", required = true, paramType = "query"),
			@ApiImplicitParam(name = "senderId", dataType = "int", value = "寄信者id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "seniorDepartmentId", dataType = "int", value = "投递的一级部门id", required = true, paramType = "query"),
			@ApiImplicitParam(name = "publicity", dataType = "int", value = "是否公开", required = true, paramType = "query")
	})
	@ApiResponses({
			@ApiResponse(code = 10021, message = "邮件标题为空"),
			@ApiResponse(code = 10022, message = "邮件内容为空"),
			@ApiResponse(code = 20000, message = "系统异常"),
			@ApiResponse(code = 10000, message = "发送成功")
	})
	@PostMapping("sendEmail")
	public Result<Integer> sendEmail(MultipartFile file, String emailTitle, String emailType, String emailContent, Integer emailAttachment, Integer senderId, Integer seniorDepartmentId, Integer publicity
	) throws IOException {
	//此处代码省略
	}

关于这两个注解:

传送门 == 》 Swagger2常用注解

在这里插入图片描述
在这里还有一个新发现:如果设置paramType为form,直接就不显示参数了QAQ…
在这里插入图片描述
可以看到,这里所有的paramType都为form
在这里插入图片描述
这个暂时作为遗留问题,以后再解决…

3.3. 为什么?

询问过很多大佬,目前还无法得出结论。
但是可以明确的是,@ApiParam注解属性相较@ApiImplicitParam更少,在使用时并不能实现需要的所有功能,因此该舍弃

3.4. 通过这次尝试发现的其他问题

3.4.1. 自己对于请求方式(GET,POST等)认识不全面

自己对于请求方式的认知,就停留在:
(1) 增 – > POST
(2) 删 – > DELETE
(3) 改 – > PUT
(4) 查 – > GET
但在实际开发上,基本上都使用GET和POST。
其中GET请求会将参数暴露在url上,安全性不高,因此适用于不传参的请求
相比之下,POST请求更加安全。
这一块知识还需要多花时间好好补课,重新总结。

3.4.2. 完全不理解请求类型(body,form,query)

目前就我的认知而言,我对这几个请求类型的理解是:
(1) body:类似于用map将参数封装起来,然后传递
(2) form:form表单中传递,就是requestParameter
(3) query:类似于xxx?action=1&name=xyx 这种就是query(在url上传参)
但显然我对请求类型的认知还过分浅薄。需要后续重新总结。

4. 额外补充

可以发现,在使用@ApiParam注解时,没有指定请求类型。此时请求类型有的会变成body,有的会变成query。
关于这一点:

传送门 == 》 Swagger解析请求类型为query还是body?

日后供自己重新查阅。

;