Swagger2接口API返回JSON、Map等對象的備註說明

描述

目前使用Swagger2形成接口文檔時,當系統設計的接口返回的類型不是實體對象時,Swagger2無法在接口文檔頁面中顯示返回結果字段說明,比如返回json、map等可以存儲key-val形式的類型;均無法在接口文檔頁面上顯示返回的字段備註說明,所以怎麼才能像實體對象一樣顯示正常的model字段說明是我們這次需要解決的問題;

  1. 首先告訴Swagger2該接口需要返回的字段具體有哪些
    定義兩個註解,方便來定義返回json或者map的固定參數;如
/** 
* @ClassName: ApiReturnJson 
* @Description: 返回對象的定義 (描述這個類的作用) 
* @author willem
* @date 2020年3月5日 15:25:01  
*/
  	
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiReturnJson {
	String key();  //對象名稱
    ApiReturnJsonPro[] value(); //對象屬性值
}
/** 
* @ClassName: ApiReturnJsonPro 
* @Description: 每一個字段的定義備註說明 (描述這個類的作用) 
* @author willem
* @date 2020年3月5日 15:30:25  
*/
  	
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiReturnJsonPro {
 
    String key();  //key
 
    String example() default "";
 
    Class<?> dataType() default String.class;
 
    String description() default "";
}
  1. 在Swagger2中將該字段封裝成一個model存進Swagger2容器中,繼承OperationModelsProviderPlugin類,實現如下方法:
public void apply(RequestMappingContext context) {
		// TODO Auto-generated method stub
		
		if (context.getReturnType().isInstanceOf(Map.class)) {
			// 根據參數上的ApiJsonObject註解中的參數動態生成Class
			Optional<ApiReturnJson> optional = context.findAnnotation(ApiReturnJson.class); 
			ApiReturnJsonPro[] properties = null;
			String name = null;
			try {
				Method method = Swagger2.class.getMethod("restApi");//系統默認取該處的全局變量
				ApiReturnJson apiReturnJson = method.getAnnotation(ApiReturnJson.class);
				name = apiReturnJson.key()+"_"+context.getName();
				ApiReturnJsonPro[] properties0 = apiReturnJson.value();
				if (optional.isPresent()) {
					name = optional.get().key(); // model名稱
					ApiReturnJsonPro[] properties1 = optional.get().value();
					properties = new ApiReturnJsonPro[properties1.length+properties0.length];
					int k=0;
					for(;k<properties0.length;k++)  properties[k] = properties0[k];
					for(int p=0;p<properties1.length;p++)  properties[k+p] = properties1[p];
				}
				else properties = properties0;
			} catch (Exception e) {
				e.printStackTrace();
			}
			ResolvedType rt = typeResolver.resolve(createRefModel(properties, name));
			// 像documentContext的Models中添加我們新生成的Class
			context.getDocumentationContext().getAdditionalModels().add(rt); 
			context.operationModelsBuilder().addReturn(rt).build();
		}
	}
  1. 然後在每一個生成的接口在BuilderPlugin進行解析,並將訪問正常的model更新,將json、map等替換,繼承OperationBuilderPlugin類,實現如下方法:
public void apply(OperationContext operationContext) {
		// TODO Auto-generated method stub
		if(operationContext.getReturnType().isInstanceOf(Map.class)) {
			//根據參數上的ApiJsonObject註解中的參數動態生成Class
			Optional<ApiReturnJson> optional = operationContext.findAnnotation(ApiReturnJson.class); 
			try {
				Method method = Swagger2.class.getMethod("restApi");//系統默認取該處的全局變量
				ApiReturnJson apiReturnJson = method.getAnnotation(ApiReturnJson.class);
				String name = apiReturnJson.key()+"_"+operationContext.getName();
	            if (optional.isPresent()) 
	                name = optional.get().key();  //model 名稱
	            Set<ResponseMessage> set = new HashSet<ResponseMessage>();
	            ModelRef mr = new ModelRef(name);
                set.add(new ResponseMessage(200,"返回json用例說明",mr,null,null));
                operationContext.operationBuilder().responseMessages(set);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
  1. Controller接口註解
@ApiOperation(value = "獲取上傳文件表單name值")
	@ApiImplicitParams({
        @ApiImplicitParam(paramType="query", name = "uploadFileType", value = "上傳文件類型:saveHeadImg", required = true, dataType = "string",defaultValue="")
    })
	@ApiReturnJson(key = "getUploadFileUrl_api", value = {
            @ApiReturnJsonPro(key = "uploadFileNamesVal", description = "上傳文件表單name值")
    })
	@GetMapping("/getUploadFileUrl")
	@ResponseBody
    public Result getUploadFileUrl(@RequestParam(required=true)String uploadFileType) {
		AssertUtil.assertNotFalse(MyConstants.CONFIG.UPLOAD_FILE_TYPES.containsKey(uploadFileType), MyConstants.RESULT.FI1000, "uploadFileType非法");
		String res = HttpUtil.httpGet(MyConstants.CONFIG.GET(SysParamKey.FILE_SYSTEM_AUTH_CODE_URL).toString());
		Result result = (Result) JSONObject.toBean(JSONObject.fromObject(res), Result.class);
		result.put("uploadFileNamesVal", MyConstants.CONFIG.UPLOAD_FILE_TYPES.get(uploadFileType));
		return result;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章