前提
- 框架 spring/spring-boot + swagger2 + swagger-ui
- 变动 springfox-core 2.9.2 => springfox-core 3.0.0
解决方法
先说下解决方法
- 方式1:将所以错误写法修改正确
- 方式2:springfox-core包指定成 version 2.9.2
分析
问题1:使用了空的@ApiImplicitParam()
错误日志
java.lang.NullPointerException: null
at springfox.documentation.builders.ParameterMerger.lambda$mergedParameters$2(ParameterMerger.java:87) ~[springfox-core-3.0.0.jar:3.0.0]
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) ~[na:1.8.0_282]
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1361) ~[na:1.8.0_282]
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) ~[na:1.8.0_282]
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:499) ~[na:1.8.0_282]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:486) ~[na:1.8.0_282]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[na:1.8.0_282]
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152) ~[na:1.8.0_282]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_282]
at java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:531) ~[na:1.8.0_282]
at springfox.documentation.builders.ParameterMerger.mergedParameters(ParameterMerger.java:87) ~[springfox-core-3.0.0.jar:3.0.0]
at springfox.documentation.builders.ParameterMerger.merged(ParameterMerger.java:64) ~[springfox-core-3.0.0.jar:3.0.0]
at springfox.documentation.builders.OperationBuilder.parameters(OperationBuilder.java:224) ~[springfox-core-3.0.0.jar:3.0.0]
错误代码
// 错误在末尾@ApiImplicitParam()
@ApiImplicitParams({ @ApiImplicitParam(name = "id", value = "主键", dataType = "String"), @ApiImplicitParam() })
看下源码springfox.documentation.builders.ParameterMerger#mergedParameters
这个类中解析时
newParam.getName() == null
如果是springfox-core-2.9.2没有问题
// springfox-core-2.9.2.jar
// springfox.documentation.builders.ParameterMerger#mergedParameters
private List<Parameter> mergedParameters(
SetView<String> paramsToMerge,
List<Parameter> existingParameters,
List<Parameter> newParams) {
List<Parameter> parameters = newArrayList();
for (Parameter newParam : newParams) {
// newParam.getName() == null 时,匹配失败, 不会有异常
Optional<Parameter> original = from(existingParameters).firstMatch(withName(newParam.getName()));
if (paramsToMerge.contains(newParam.getName()) && original.isPresent()) {
if (newParam.getOrder() > original.get().getOrder()){
parameters.add(merged(newParam, original.get()));
} else {
parameters.add(merged(original.get(), newParam));
}
}
}
return parameters;
}
如果是springfox-core-3.0.0那就有问题了,input -> newParam.getName().equals(input.getName())
这段代码要报空指针了
private List<springfox.documentation.service.Parameter> mergedParameters(
Set<String> paramsToMerge,
List<springfox.documentation.service.Parameter> existingParameters,
List<springfox.documentation.service.Parameter> newParams) {
List<springfox.documentation.service.Parameter> parameters = new ArrayList<>();
for (springfox.documentation.service.Parameter newParam : newParams) {
Optional<springfox.documentation.service.Parameter> original = existingParameters.stream()
// newParam.getName() == null 时,直接空指针异常
// 所以使用@ApiImplicitParam(),name属性为null时, 空指针异常, 文档生成失败。
.filter(input -> newParam.getName().equals(input.getName())).findFirst();
if (paramsToMerge.contains(newParam.getName()) && original.isPresent()) {
if (newParam.getOrder() > original.get().getOrder()) {
parameters.add(merged(newParam, original.get()));
} else {
parameters.add(merged(original.get(), newParam));
}
}
}
return parameters;
}
问题2:paramType只能使用ParameterType
这个类里面的类型。或者dataType参数错写成paramType
public enum ParameterType {
QUERY("query"),
HEADER("header"),
PATH("path"),
COOKIE("cookie"),
FORM("form"),
FORMDATA("formData"),
BODY("body");
}
现象:程序启动时,出现异常日志
// 遇到此类错误信息,就需要检查@ApiImplicitParam注解中paramType参数是否错误
java.lang.IllegalArgumentException: No enum constant springfox.documentation.service.ParameterType.LONG
at java.lang.Enum.valueOf(Enum.java:238) ~[na:1.8.0_282]
at springfox.documentation.service.ParameterType.valueOf(ParameterType.java:6) ~[springfox-core-3.0.0.jar:3.0.0]
// 反例
@ApiImplicitParam(name = "orgId", value = "组织ID", paramType = "Long")
// 修正,此处业务同学应该是想使用dataType
@ApiImplicitParam(name = "orgId", value = "组织ID", dataType = "Long")
// 正例
@ApiImplicitParam(name = "test", paramType = "query")
问题3:@ApiImplicitParam(name=’{不存在参数}’)包含了不存在参数名称
现象:程序正常启动,获取swagger文档时报错
// 遇到此类错误, 就是解析参数遇到空指针,参数名不存在
java.lang.NullPointerException: null
at springfox.documentation.swagger2.mappers.RequestParameterMapper.bodyParameter(RequestParameterMapper.java:264) ~[springfox-swagger2-3.0.0.jar:3.0.0]
at springfox.documentation.swagger2.mappers.RequestParameterMapper.mapParameter(RequestParameterMapper.java:149) ~[springfox-swagger2-3.0.0.jar:3.0.0]
反例:
// 反例: orgId参数已经不存在
@ApiImplicitParams({@ApiImplicitParam(name = "orgId", value = "组织Id", dataType = "Long")})
public ApiResponse<String> list(@RequestBody BotTagLinkRequest tagLinkRequest) {
}