好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

swagger2隐藏在API文档显示某些参数的操作

swagger2隐藏在API文档显示某些参数

有时候,利用swagger2建立API文档时,有些参数是需要隐藏在API文档显示,在方法中,参数的名字前加上

@ApiIgnore 就可以了:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

@PostMapping ( "modi/certificate" )

@ApiResponses ({ @ApiResponse (code = 0 , message = "请求成功" ),

         @ApiResponse (code = 10031 , message = "商家的营业执照已经存在,不能重复入驻" )

})

@ApiOperation (value = "修改商家证照资料" , notes = "修改商家证照资料" , response = MerchantExtendVdo. class )

@ApiImplicitParams ({

         @ApiImplicitParam (name = "merchantExtendVdo" , value = "商铺对象" , required = true , dataType = "MerchantExtendVdo" ),

         @ApiImplicitParam (name = "merchantProvepicVdo" , value = "商铺证明图片" , required = false , dataType = "MerchantProvepicVdo" ),

         @ApiImplicitParam (name = "merchantOtherVdoList" , value = "商家的其他资质图片对象,List数组形式" , required = false , dataType = "MerchantOtherVdo" , allowMultiple = true , paramType = "body" )})

public ResultData modiCertificate( @MultiRequestBody @ApiIgnore MerchantExtendVdo merchantExtendVdo,

                                   @MultiRequestBody @ApiIgnore MerchantProvepicVdo merchantProvepicVdo,

                                   @MultiRequestBody @ApiIgnore List<MerchantOtherVdo> merchantOtherVdoList) {

     String accessToken = getAccessToken();

     ResultData rd = storeService.modiCertificate(accessToken, merchantProvepicVdo, merchantOtherVdoList, merchantExtendVdo);

     return rd;

}

swagger2自定义隐藏实体类属性

问题:

假如接收参数的实体类中关联了其他对象,那么swagger2的页面中参数应该会多出来这些,dept.id,dept.deptName,或者集合属性,roles[0].id,roles[0].roleName等等。

???这些属性有可能是不需要用来接收参数的,出现在文档中会给前端开发人员带来困惑

笔者在swagger2提供的配置中没有找到隐藏此类参数的设置

解决

但是通过阅读源码找到了展开参数的类

springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander

笔者通过继承这个类,并添加

@Primary

注解覆盖了源码中的逻辑,修改了

getBeanPropertyNames

方法,其他不变

swagger2版本2.8.0 解决方案

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

package com.example.swagger;

import com.example.annotation.IgnoreSwaggerParameter;

import com.fasterxml.classmate.ResolvedType;

import com.fasterxml.classmate.members.ResolvedField;

import com.google测试数据mon.annotations.VisibleForTesting;

import com.google测试数据mon.base.Function;

import com.google测试数据mon.base.Optional;

import com.google测试数据mon.base.Predicate;

import com.google测试数据mon.collect.FluentIterable;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Primary;

import org.springframework.stereotype.Component;

import org.springframework.util.ClassUtils;

import springfox.documentation.builders.ParameterBuilder;

import springfox.documentation.schema.Maps;

import springfox.documentation.schema.Types;

import springfox.documentation.schema.property.field.FieldProvider;

import springfox.documentation.service.Parameter;

import springfox.documentation.spi.schema.AlternateTypeProvider;

import springfox.documentation.spi.schema.EnumTypeDeterminer;

import springfox.documentation.spi.service.contexts.DocumentationContext;

import springfox.documentation.spi.service.contexts.ParameterExpansionContext;

import springfox.documentation.spring.web.readers.parameter.ExpansionContext;

import springfox.documentation.spring.web.readers.parameter.ModelAttributeField;

import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;

 

import java.beans.BeanInfo;

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Field;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

 

import static com.google测试数据mon.base.Objects.equal;

import static com.google测试数据mon.base.Predicates.*;

import static com.google测试数据mon.base.Strings.isNullOrEmpty;

import static com.google测试数据mon.collect.FluentIterable.from;

import static com.google测试数据mon.collect.Lists.newArrayList;

import static com.google测试数据mon.collect.Sets.newHashSet;

import static springfox.documentation.schema.Collections.collectionElementType;

import static springfox.documentation.schema.Collections.isContainerType;

import static springfox.documentation.schema.Types.typeNameFor;

 

/**

  * 覆盖{@link ModelAttributeParameterExpander}

  * @see CustomizeModelAttributeParameterExpander#getBeanPropertyNames(Class)

  * @see ModelAttributeParameterExpander#getBeanPropertyNames(Class)

  * @see IgnoreSwaggerParameter

  */

@Component

@Primary

public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {

     private static final Logger LOG = LoggerFactory.getLogger(CustomizeModelAttributeParameterExpander. class );

     private final FieldProvider fieldProvider;

     private final EnumTypeDeterminer enumTypeDeterminer;

 

     @Autowired

     public CustomizeModelAttributeParameterExpander(FieldProvider fields, EnumTypeDeterminer enumTypeDeterminer) {

         super (fields, enumTypeDeterminer);

         this .fieldProvider = fields;

         this .enumTypeDeterminer = enumTypeDeterminer;

     }

 

     @Override

     public List<Parameter> expand(ExpansionContext context) {

         List<Parameter> parameters = newArrayList();

         Set<String> beanPropNames = getBeanPropertyNames(context.getParamType().getErasedType());

         Iterable<ResolvedField> fields = FluentIterable.from(fieldProvider.in(context.getParamType()))

                 .filter(onlyBeanProperties(beanPropNames));

         LOG.debug( "Expanding parameter type: {}" , context.getParamType());

         AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();

 

         FluentIterable<ModelAttributeField> modelAttributes = from(fields)

                 .transform(toModelAttributeField(alternateTypeProvider));

 

         FluentIterable<ModelAttributeField> expendables = modelAttributes

                 .filter(not(simpleType()))

                 .filter(not(recursiveType(context)));

         for (ModelAttributeField each : expendables) {

             LOG.debug( "Attempting to expand expandable field: {}" , each.getField());

             parameters.addAll(

                     expand(

                             context.childContext(

                                     nestedParentName(context.getParentName(), each.getField()),

                                     each.getFieldType(),

                                     context.getDocumentationContext())));

         }

 

         FluentIterable<ModelAttributeField> collectionTypes = modelAttributes

                 .filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));

         for (ModelAttributeField each : collectionTypes) {

             LOG.debug( "Attempting to expand collection/array field: {}" , each.getField());

 

             ResolvedType itemType = collectionElementType(each.getFieldType());

             if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {

                 parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));

             } else {

                 parameters.addAll(

                         expand(

                                 context.childContext(

                                         nestedParentName(context.getParentName(), each.getField()),

                                         itemType,

                                         context.getDocumentationContext())));

             }

         }

 

         FluentIterable<ModelAttributeField> simpleFields = modelAttributes.filter(simpleType());

         for (ModelAttributeField each : simpleFields) {

             parameters.add(simpleFields(context.getParentName(), context.getDocumentationContext(), each));

         }

         return FluentIterable.from(parameters).filter(not(hiddenParameters())).toList();

     }

 

     private Predicate<ModelAttributeField> recursiveCollectionItemType( final ResolvedType paramType) {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return equal(collectionElementType(input.getFieldType()), paramType);

             }

         };

     }

 

     private Predicate<Parameter> hiddenParameters() {

         return new Predicate<Parameter>() {

             @Override

             public boolean apply(Parameter input) {

                 return input.isHidden();

             }

         };

     }

 

     private Parameter simpleFields(

             String parentName,

             DocumentationContext documentationContext,

             ModelAttributeField each) {

         LOG.debug( "Attempting to expand field: {}" , each);

         String dataTypeName = Optional.fromNullable(typeNameFor(each.getFieldType().getErasedType()))

                 .or(each.getFieldType().getErasedType().getSimpleName());

         LOG.debug( "Building parameter for field: {}, with type: " , each, each.getFieldType());

         ParameterExpansionContext parameterExpansionContext = new ParameterExpansionContext(

                 dataTypeName,

                 parentName,

                 each.getField(),

                 documentationContext.getDocumentationType(),

                 new ParameterBuilder());

         return pluginsManager.expandParameter(parameterExpansionContext);

     }

 

     private Predicate<ModelAttributeField> recursiveType( final ExpansionContext context) {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return context.hasSeenType(input.getFieldType());

             }

         };

     }

 

     private Predicate<ModelAttributeField> simpleType() {

         return and(not(isCollection()), not(isMap()),

                 or(

                         belongsToJavaPackage(),

                         isBaseType(),

                         isEnum()));

     }

 

     private Predicate<ModelAttributeField> isCollection() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return isContainerType(input.getFieldType());

             }

         };

     }

 

     private Predicate<ModelAttributeField> isMap() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return Maps.isMapType(input.getFieldType());

             }

         };

     }

 

     private Predicate<ModelAttributeField> isEnum() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());

             }

         };

     }

 

     private Predicate<ModelAttributeField> belongsToJavaPackage() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith( "java.lang" );

             }

         };

     }

 

     private Predicate<ModelAttributeField> isBaseType() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return Types.isBaseType(input.getFieldType())

                         || input.getField().getType().isPrimitive();

             }

         };

     }

 

     private Function<ResolvedField, ModelAttributeField> toModelAttributeField(

             final AlternateTypeProvider

                     alternateTypeProvider) {

         return new Function<ResolvedField, ModelAttributeField>() {

             @Override

             public ModelAttributeField apply(ResolvedField input) {

                 return new ModelAttributeField(fieldType(alternateTypeProvider, input), input);

             }

         };

     }

 

     private Predicate<ResolvedField> onlyBeanProperties( final Set<String> beanPropNames) {

         return new Predicate<ResolvedField>() {

             @Override

             public boolean apply(ResolvedField input) {

                 return beanPropNames.contains(input.getName());

             }

         };

     }

 

     private String nestedParentName(String parentName, ResolvedField field) {

         String name = field.getName();

         ResolvedType fieldType = field.getType();

         if (isContainerType(fieldType) && !Types.isBaseType(collectionElementType(fieldType))) {

             name += "[0]" ;

         }

 

         if (isNullOrEmpty(parentName)) {

             return name;

         }

         return String.format( "%s.%s" , parentName, name);

     }

 

     private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedField field) {

         return alternateTypeProvider.alternateFor(field.getType());

     }

 

     private Set<String> getBeanPropertyNames( final Class<?> clazz) {

         try {

             Set<String> beanProps = new HashSet<String>();

             PropertyDescriptor[] propDescriptors = getBeanInfo(clazz).getPropertyDescriptors();

             for (PropertyDescriptor propDescriptor : propDescriptors) {

 

                 // 增加逻辑,忽略@IgnoreSwaggerParameter注解的字段

                 Field field = clazz.getDeclaredField(propDescriptor.getName());

                 if (field!= null ) {

                     field.setAccessible( true );

                     IgnoreSwaggerParameter ignoreSwaggerParameter = field.getDeclaredAnnotation(IgnoreSwaggerParameter. class );

                     if (ignoreSwaggerParameter != null ) {

                         continue ;

                     }

                 }

                 // 增加结束

 

                 if (propDescriptor.getReadMethod() != null ) {

                     beanProps.add(propDescriptor.getName());

                 }

             }

 

             return beanProps;

 

         } catch (Exception e) {

             LOG.warn(String.format( "Failed to get bean properties on (%s)" , clazz), e);

         }

         return newHashSet();

     }

 

     @VisibleForTesting

     BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {

         return Introspector.getBeanInfo(clazz);

     }

}

swagger2版本2.9.2 解决方案

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

package com.zihuiinfo.facesdk.framework测试数据mon.swagger;

import com.fasterxml.classmate.ResolvedType;

import com.fasterxml.classmate.members.ResolvedField;

import com.fasterxml.classmate.members.ResolvedMethod;

import com.google测试数据mon.annotations.VisibleForTesting;

import com.google测试数据mon.base.Function;

import com.google测试数据mon.base.Optional;

import com.google测试数据mon.base.Predicate;

import com.google测试数据mon.collect.FluentIterable;

import com.google测试数据mon.collect.Sets;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Primary;

import org.springframework.http.HttpMethod;

import org.springframework.http.MediaType;

import org.springframework.stereotype.Component;

import org.springframework.util.ClassUtils;

import springfox.documentation.builders.ParameterBuilder;

import springfox.documentation.schema.Maps;

import springfox.documentation.schema.Types;

import springfox.documentation.schema.property.bean.AccessorsProvider;

import springfox.documentation.schema.property.field.FieldProvider;

import springfox.documentation.service.Parameter;

import springfox.documentation.spi.schema.AlternateTypeProvider;

import springfox.documentation.spi.schema.EnumTypeDeterminer;

import springfox.documentation.spi.service.contexts.ParameterExpansionContext;

import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;

import springfox.documentation.spring.web.readers.parameter.ExpansionContext;

import springfox.documentation.spring.web.readers.parameter.ModelAttributeField;

import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;

import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterMetadataAccessor;

import java.beans.BeanInfo;

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.util.*;

import static com.google测试数据mon.base.Objects.equal;

import static com.google测试数据mon.base.Predicates.*;

import static com.google测试数据mon.base.Strings.isNullOrEmpty;

import static com.google测试数据mon.collect.FluentIterable.from;

import static com.google测试数据mon.collect.Lists.newArrayList;

import static com.google测试数据mon.collect.Sets.newHashSet;

import static springfox.documentation.schema.Collections.collectionElementType;

import static springfox.documentation.schema.Collections.isContainerType;

import static springfox.documentation.schema.Types.isVoid;

import static springfox.documentation.schema.Types.typeNameFor;

/**

  * 覆盖{@link ModelAttributeParameterExpander}

  *

  * @see CustomizeModelAttributeParameterExpander#getBeanPropertyNames(Class)

  * @see ModelAttributeParameterExpander#getBeanPropertyNames(Class)

  * @see IgnoreSwaggerParameter

  */

@Component

@Primary

public class CustomizeModelAttributeParameterExpander extends ModelAttributeParameterExpander {

     private static final Logger LOG = LoggerFactory.getLogger(ModelAttributeParameterExpander. class );

     private final FieldProvider fields;

     private final AccessorsProvider accessors;

     private final EnumTypeDeterminer enumTypeDeterminer;

     @Autowired

     protected DocumentationPluginsManager pluginsManager;

     @Autowired

     public CustomizeModelAttributeParameterExpander(FieldProvider fields, AccessorsProvider accessors, EnumTypeDeterminer enumTypeDeterminer) {

         super (fields, accessors, enumTypeDeterminer);

         this .fields = fields;

         this .accessors = accessors;

         this .enumTypeDeterminer = enumTypeDeterminer;

     }

     public List<Parameter> expand(ExpansionContext context) {

         List<Parameter> parameters = newArrayList();

         Set<PropertyDescriptor> propertyDescriptors = propertyDescriptors(context.getParamType().getErasedType());

         Map<Method, PropertyDescriptor> propertyLookupByGetter

                 = propertyDescriptorsByMethod(context.getParamType().getErasedType(), propertyDescriptors);

         Iterable<ResolvedMethod> getters = FluentIterable.from(accessors.in(context.getParamType()))

                 .filter(onlyValidGetters(propertyLookupByGetter.keySet()));

         Map<String, ResolvedField> fieldsByName = FluentIterable.from( this .fields.in(context.getParamType()))

                 .uniqueIndex( new Function<ResolvedField, String>() {

                     @Override

                     public String apply(ResolvedField input) {

                         return input.getName();

                     }

                 });

         LOG.debug( "Expanding parameter type: {}" , context.getParamType());

         final AlternateTypeProvider alternateTypeProvider = context.getDocumentationContext().getAlternateTypeProvider();

         FluentIterable<ModelAttributeField> attributes =

                 allModelAttributes(

                         propertyLookupByGetter,

                         getters,

                         fieldsByName,

                         alternateTypeProvider);

         FluentIterable<ModelAttributeField> expendables = attributes

                 .filter(not(simpleType()))

                 .filter(not(recursiveType(context)));

         for (ModelAttributeField each : expendables) {

             LOG.debug( "Attempting to expand expandable property: {}" , each.getName());

             parameters.addAll(

                     expand(

                             context.childContext(

                                     nestedParentName(context.getParentName(), each),

                                     each.getFieldType(),

                                     context.getOperationContext())));

         }

         FluentIterable<ModelAttributeField> collectionTypes = attributes

                 .filter(and(isCollection(), not(recursiveCollectionItemType(context.getParamType()))));

         for (ModelAttributeField each : collectionTypes) {

             LOG.debug( "Attempting to expand collection/array field: {}" , each.getName());

             ResolvedType itemType = collectionElementType(each.getFieldType());

             if (Types.isBaseType(itemType) || enumTypeDeterminer.isEnum(itemType.getErasedType())) {

                 parameters.add(simpleFields(context.getParentName(), context, each));

             } else {

                 ExpansionContext childContext = context.childContext(

                         nestedParentName(context.getParentName(), each),

                         itemType,

                         context.getOperationContext());

                 if (!context.hasSeenType(itemType)) {

                     parameters.addAll(expand(childContext));

                 }

             }

         }

         FluentIterable<ModelAttributeField> simpleFields = attributes.filter(simpleType());

         for (ModelAttributeField each : simpleFields) {

             parameters.add(simpleFields(context.getParentName(), context, each));

         }

         return FluentIterable.from(parameters)

                 .filter(not(hiddenParameters()))

                 .filter(not(voidParameters()))

                 .toList();

     }

     private FluentIterable<ModelAttributeField> allModelAttributes(

             Map<Method, PropertyDescriptor> propertyLookupByGetter,

             Iterable<ResolvedMethod> getters,

             Map<String, ResolvedField> fieldsByName,

             AlternateTypeProvider alternateTypeProvider) {

         FluentIterable<ModelAttributeField> modelAttributesFromGetters = from(getters)

                 .transform(toModelAttributeField(fieldsByName, propertyLookupByGetter, alternateTypeProvider));

         FluentIterable<ModelAttributeField> modelAttributesFromFields = from(fieldsByName.values())

                 .filter(publicFields())

                 .transform(toModelAttributeField(alternateTypeProvider));

         return FluentIterable.from(Sets.union(

                 modelAttributesFromFields.toSet(),

                 modelAttributesFromGetters.toSet()));

     }

     private Function<ResolvedField, ModelAttributeField> toModelAttributeField(

             final AlternateTypeProvider alternateTypeProvider) {

         return new Function<ResolvedField, ModelAttributeField>() {

             @Override

             public ModelAttributeField apply(ResolvedField input) {

                 return new ModelAttributeField(

                         alternateTypeProvider.alternateFor(input.getType()),

                         input.getName(),

                         input,

                         input);

             }

         };

     }

     private Predicate<ResolvedField> publicFields() {

         return new Predicate<ResolvedField>() {

             @Override

             public boolean apply(ResolvedField input) {

                 return input.isPublic();

             }

         };

     }

     private Predicate<Parameter> voidParameters() {

         return new Predicate<Parameter>() {

             @Override

             public boolean apply(Parameter input) {

                 return isVoid(input.getType().orNull());

             }

         };

     }

     private Predicate<ModelAttributeField> recursiveCollectionItemType( final ResolvedType paramType) {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return equal(collectionElementType(input.getFieldType()), paramType);

             }

         };

     }

     private Predicate<Parameter> hiddenParameters() {

         return new Predicate<Parameter>() {

             @Override

             public boolean apply(Parameter input) {

                 return input.isHidden();

             }

         };

     }

     private Parameter simpleFields(

             String parentName,

             ExpansionContext context,

             ModelAttributeField each) {

         LOG.debug( "Attempting to expand field: {}" , each);

         String dataTypeName = Optional.fromNullable(typeNameFor(each.getFieldType().getErasedType()))

                 .or(each.getFieldType().getErasedType().getSimpleName());

         LOG.debug( "Building parameter for field: {}, with type: " , each, each.getFieldType());

         ParameterExpansionContext parameterExpansionContext = new ParameterExpansionContext(

                 dataTypeName,

                 parentName,

                 determineScalarParameterType(

                         context.getOperationContext().consumes(),

                         context.getOperationContext().httpMethod()),

                 new ModelAttributeParameterMetadataAccessor(

                         each.annotatedElements(),

                         each.getFieldType(),

                         each.getName()),

                 context.getDocumentationContext().getDocumentationType(),

                 new ParameterBuilder());

         return pluginsManager.expandParameter(parameterExpansionContext);

     }

     private Predicate<ModelAttributeField> recursiveType( final ExpansionContext context) {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return context.hasSeenType(input.getFieldType());

             }

         };

     }

     private Predicate<ModelAttributeField> simpleType() {

         return and(not(isCollection()), not(isMap()),

                 or(

                         belongsToJavaPackage(),

                         isBaseType(),

                         isEnum()));

     }

     private Predicate<ModelAttributeField> isCollection() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return isContainerType(input.getFieldType());

             }

         };

     }

     private Predicate<ModelAttributeField> isMap() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return Maps.isMapType(input.getFieldType());

             }

         };

     }

     private Predicate<ModelAttributeField> isEnum() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return enumTypeDeterminer.isEnum(input.getFieldType().getErasedType());

             }

         };

     }

     private Predicate<ModelAttributeField> belongsToJavaPackage() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return ClassUtils.getPackageName(input.getFieldType().getErasedType()).startsWith( "java.lang" );

             }

         };

     }

     private Predicate<ModelAttributeField> isBaseType() {

         return new Predicate<ModelAttributeField>() {

             @Override

             public boolean apply(ModelAttributeField input) {

                 return Types.isBaseType(input.getFieldType())

                         || input.getFieldType().isPrimitive();

             }

         };

     }

     private Function<ResolvedMethod, ModelAttributeField> toModelAttributeField(

             final Map<String, ResolvedField> fieldsByName,

             final Map<Method, PropertyDescriptor> propertyLookupByGetter,

             final AlternateTypeProvider alternateTypeProvider) {

         return new Function<ResolvedMethod, ModelAttributeField>() {

             @Override

             public ModelAttributeField apply(ResolvedMethod input) {

                 String name = propertyLookupByGetter.get(input.getRawMember()).getName();

                 return new ModelAttributeField(

                         fieldType(alternateTypeProvider, input),

                         name,

                         input,

                         fieldsByName.get(name));

             }

         };

     }

     private Predicate<ResolvedMethod> onlyValidGetters( final Set<Method> methods) {

         return new Predicate<ResolvedMethod>() {

             @Override

             public boolean apply(ResolvedMethod input) {

                 return methods.contains(input.getRawMember());

             }

         };

     }

     private String nestedParentName(String parentName, ModelAttributeField attribute) {

         String name = attribute.getName();

         ResolvedType fieldType = attribute.getFieldType();

         if (isContainerType(fieldType) && !Types.isBaseType(collectionElementType(fieldType))) {

             name += "[0]" ;

         }

         if (isNullOrEmpty(parentName)) {

             return name;

         }

         return String.format( "%s.%s" , parentName, name);

     }

     private ResolvedType fieldType(AlternateTypeProvider alternateTypeProvider, ResolvedMethod method) {

         return alternateTypeProvider.alternateFor(method.getType());

     }

     private Set<PropertyDescriptor> propertyDescriptors( final Class<?> clazz) {

         try {

             Set<PropertyDescriptor> beanProps = new HashSet<>();

             PropertyDescriptor[] descriptors = getBeanInfo(clazz).getPropertyDescriptors();

             for (PropertyDescriptor descriptor : descriptors) {

             // 增加逻辑,忽略@IgnoreSwaggerParameter注解的字段

                 Field field = null ;

                 try {

                     field = clazz.getDeclaredField(descriptor.getName());

                 } catch (Exception e) {

                     LOG.debug(String.format( "Failed to get bean properties on (%s)" , clazz), e);

                 }

                 if (field != null ) {

                     field.setAccessible( true );

                     IgnoreSwaggerParameter ignoreSwaggerParameter = field.getDeclaredAnnotation(IgnoreSwaggerParameter. class );

                     if (ignoreSwaggerParameter != null ) {

                         continue ;

                     }

                 }

              // 增加结束

                 if (descriptor.getReadMethod() != null ) {

                     beanProps.add(descriptor);

                 }

             }

             return beanProps;

         } catch (Exception e) {

             LOG.warn(String.format( "Failed to get bean properties on (%s)" , clazz), e);

         }

         return newHashSet();

     }

     private Map<Method, PropertyDescriptor> propertyDescriptorsByMethod(

             final Class<?> clazz,

             Set<PropertyDescriptor> propertyDescriptors) {

         return FluentIterable.from(propertyDescriptors)

                 .filter( new Predicate<PropertyDescriptor>() {

                     @Override

                     public boolean apply(PropertyDescriptor input) {

                         return input.getReadMethod() != null

                                 && !clazz.isAssignableFrom(Collection. class )

                                 && ! "isEmpty" .equals(input.getReadMethod().getName());

                     }

                 })

                 .uniqueIndex( new Function<PropertyDescriptor, Method>() {

                     @Override

                     public Method apply(PropertyDescriptor input) {

                         return input.getReadMethod();

                     }

                 });

     }

     @VisibleForTesting

     BeanInfo getBeanInfo(Class<?> clazz) throws IntrospectionException {

         return Introspector.getBeanInfo(clazz);

     }

     public static String determineScalarParameterType(Set<? extends MediaType> consumes, HttpMethod method) {

         String parameterType = "query" ;

         if (consumes.contains(MediaType.APPLICATION_FORM_URLENCODED)

                 && method == HttpMethod.POST) {

             parameterType = "form" ;

         } else if (consumes.contains(MediaType.MULTIPART_FORM_DATA)

                 && method == HttpMethod.POST) {

             parameterType = "formData" ;

         }

         return parameterType;

     }

}

用到了自定义的IgnoreSwaggerParamer注解

?

1

2

3

4

5

6

7

8

9

10

11

package com.example.annotation;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

// swagger忽略的参数

@Target ({ElementType.FIELD})

@Retention (RetentionPolicy.RUNTIME)

public @interface IgnoreSwaggerParameter {

}

使用方式,在不需要递归展开的属性上加上IgnoreSwaggerParameter注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

package com.example.model.po;

import com.example.annotation.IgnoreSwaggerParameter;

import com.example.model.BaseModel;

import io.swagger.annotations.ApiModel;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;

import java.sql.Date;

import java.sql.Timestamp;

import java.util.List;

 

@Data

@ApiModel (value = "用户" )

public class User extends BaseModel {

     private static final long serialVersionUID = 1L;

     @ApiModelProperty (value = "用户id" )

     private Integer id;

     @ApiModelProperty (value = "用户名" )

     private String username;

     @ApiModelProperty (value = "密码" )

     private String password;

     @ApiModelProperty (value = "邮箱" )

     private String email;

     @ApiModelProperty (value = "昵称" )

     private String nickname;

     @ApiModelProperty (value = "生日" )

     private Date birth;

     @ApiModelProperty (value= "登录时间" )

     private Timestamp logintime;

     @ApiModelProperty (value = "部门id" )

     private Integer deptId;

 

     @ApiModelProperty (value = "部门信息" )

     @IgnoreSwaggerParameter // 在不需要递归展开的属性上加上IgnoreSwaggerParameter注解

     private Dept dept;

     @ApiModelProperty (value = "角色信息" )

     @IgnoreSwaggerParameter

     private List<Role> roles;

}

这样就可以自定义隐藏swagger2页面中的参数了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/tan_yh/article/details/103790796

查看更多关于swagger2隐藏在API文档显示某些参数的操作的详细内容...

  阅读:19次