springboot 在集成swagger中會不會遇到各種問題:
1、swagger 進行接口鑒權(比如設置header的token,接口進行攔截處理)。
2、swagger 進行實體屬性解析(pojo類的屬性注解無法解析)。
3、swagger 進行響應碼統一(code狀態嗎標識、200響應成功,響應體解析)。
4、swagger 設置接口共用參數(統一每個接口都存在的參數)。
以下是解決問題配置信息
一、引入依賴包
使用之前請更新或直接引用該版本依賴包
更新版本地址:接口依賴jar https://mvnrepository.com/artifact/io.springfox/springfox-swagger2
ui 依賴jar https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
二、創建swagger 配置類
1、全局參數
2、全局響應參數,每個接口都存在響應值,方便溝通
3、設置安全認證
點擊 authorize 按鈕輸入驗證信息,則每次調試接口都會傳響應的信息
廢話少說!上配置代碼
package com.example.config.swagger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.web.bind.annotation.RequestMethod; import springfox.documentation.builders.*; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; import java.util.ArrayList; import java.util.List; /** * * @author niunafei * * @Profile 注解 標識加載在dev和test文件使用 */ @Configuration @EnableSwagger2 //@Profile({"dev", "test"}) public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).groupName("spring-test-interface") //加載配置信息 .apiInfo(apiInfo()) //設置全局參數 .globalOperationParameters(globalParamBuilder()) //設置全局響應參數 .globalResponseMessage(RequestMethod.GET,responseBuilder()) .globalResponseMessage(RequestMethod.POST,responseBuilder()) .globalResponseMessage(RequestMethod.PUT,responseBuilder()) .globalResponseMessage(RequestMethod.DELETE,responseBuilder()) .select() //加載swagger 掃描包 .apis(RequestHandlerSelectors.basePackage("com.example")) .paths(PathSelectors.any()).build() //設置安全認證 .securitySchemes(security()); } /** * 獲取swagger創建初始化信息 * @return */ private ApiInfo apiInfo() { Contact contact = new Contact("niunafei", "", "niunafei0315@163.com"); return new ApiInfoBuilder().title("swagger 測試文檔").description("dev by niunafei").contact(contact) .version("1.0.0").build(); } /** * 安全認證參數 * @return */ private List<ApiKey> security() { List<ApiKey> list=new ArrayList<>(); list.add(new ApiKey("token", "token", "header")); return list; } /** * 構建全局參數列表 * @return */ private List<Parameter> globalParamBuilder(){ List<Parameter> pars = new ArrayList<>(); pars.add(parameterBuilder("token","令牌","string","header",false).build()); return pars; } /** * 創建參數 * @return */ private ParameterBuilder parameterBuilder(String name,String desc,String type ,String parameterType,boolean required) { ParameterBuilder tokenPar = new ParameterBuilder(); tokenPar.name(name).description(desc).modelRef(new ModelRef(type)).parameterType(parameterType).required(required).build(); return tokenPar; } /** * 創建全局響應值 * @return */ private List<ResponseMessage> responseBuilder() { List<ResponseMessage> responseMessageList = new ArrayList<>(); responseMessageList.add(new ResponseMessageBuilder().code(200).message("響應成功").build()); responseMessageList.add(new ResponseMessageBuilder().code(500).message("服務器內部錯誤").build()); return responseMessageList; } }
以上代碼中 @Profile({"dev", "test"})注解是在開發環境和測試環境的時候加載該類,線上生產環境為安全不建議創建swagger的bean
三、引入配置文件,並且配置好掃描類,但是仍然不能訪問swagger 頁面,這時候請考慮springboot的mvc指定訪問路徑
addResourceHandlers 方法中已經指定swagger-ui訪問頁的路徑
同時該配置中處理了mvc 跨域的問題
addCorsMappings 方法中是在攔截 addInterceptors 方法執行后進行的跨域設置
corsFilter可以解決所有跨域問題
package com.example.config.mvc; //import com.example.config.interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; /** * @author niunafei * @function * @email niunafei0315@163.com * @date 2019/6/28 下午12:28 */ @Configuration public class WebMvcConfigurerAdapter extends WebMvcConfigurationSupport { // @Autowired // private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 添加攔截接口請求處理, // registry.addInterceptor(loginInterceptor).addPathPatterns("/api/**"); } @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { //定向swagger 位置 registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } /** * 攔截后的跨域解決 * * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowCredentials(true).allowedHeaders("*").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "OPTIONS"); } /** * 處理攔截前處理檢測 授權跨域問題 * * @return */ @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig()); return new CorsFilter(source); } /** * @return */ private CorsConfiguration corsConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); // 請求常用的三種配置,*代表允許所有,當時你也可以自定義屬性(比如header只能帶什么,只能是post方式等等) corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setAllowCredentials(true); corsConfiguration.setMaxAge(3600L); return corsConfiguration; } }
四、swagger 返回掃描的問題
接口層請使用泛型返回,個人定義的統一返回類
ApiModel是生成swagger時掃描的實體注解
ApiModelProperty 是屬性注解
ApiHttpCode 是一個響應值的枚舉類
package com.example.config.response; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * @author niunafei * @function * @email niunafei0315@163.com * @date 2019/6/28 下午2:00 */ @ApiModel() public class ApiResult<T> { private static final Object RESULT_OBJECT=new Object(); @ApiModelProperty(value = "編碼", name = "code", dataType = "int", example = "200") private Integer code; @ApiModelProperty(value = "提示", name = "msg", dataType = "string", example = "success") private String msg; @ApiModelProperty(value = "內容", name = "data", dataType = "t") private T data; public ApiResult() { } public ApiResult(ApiHttpCode code, T data) { this.code = code.getCode(); this.msg = code.getDesc(); this.data = data; } public ApiResult(Integer code, String msg, T data) { this.code = code; this.msg = msg; this.data = data; } public static ApiResult<Object> ok() { return ApiResult.ok(ApiHttpCode.SUCCESS, RESULT_OBJECT); } public static <T> ApiResult<T> ok(T data) { return ApiResult.ok(ApiHttpCode.SUCCESS, data); } public static <T> ApiResult<T> ok(ApiHttpCode code, T data) { return ApiResult.ok(code.getCode(), code.getDesc(), data); } public static <T> ApiResult<T> ok(Integer code, String msg, T data) { return new ApiResult(code, msg, data); } public static ApiResult<Object> error() { return ApiResult.error(ApiHttpCode.ERROR, new Object()); } public static <T> ApiResult<T> error(T data) { return ApiResult.error(ApiHttpCode.ERROR, data); } public static <T> ApiResult<T> error(ApiHttpCode code) { return ApiResult.error(code.getCode(),code.getDesc(),null); } public static <T> ApiResult<T> error(ApiHttpCode code, T data) { return ApiResult.error(code.getCode(), code.getDesc(), data); } public static <T> ApiResult<T> error(Integer code, String msg) { return ApiResult.error(code, msg, null); } public static <T> ApiResult<T> error(Integer code, String msg, T data) { return new ApiResult(code, msg, data); } public Integer getCode() { return code; } public String getMsg() { return msg; } public T getData() { return data; } }
ApiHttpCode枚舉類
package com.example.config.response; /** * @author niunafei * @function * @email niunafei0315@163.com * @date 2019/6/28 下午2:02 */ public enum ApiHttpCode { /** * 響應成功 */ SUCCESS(200, "OK"), /** * 服務器異常 */ ERROR(500, "ERROR"), /** * 未授權訪問 */ UNAUTHORIZED(401, "訪問未授權"); private int code; private String desc; ApiHttpCode(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } public String getDesc() { return desc; } public static ApiHttpCode valueOf(int value) { for (ApiHttpCode role : ApiHttpCode.values()) { if (role.code == value) { return role; } } return null; } }
五、接口層引用
@Api注解添加
接口方法上添加@ApiOperation 才可以生成文檔
@ApiImplicitParams 用來定義接口參數,並指定描述的,
@ApiResponses 用來定義添加額外的響應值,與配置類中的全局響應功能一致。
訪問接口頁面 http://localhost:8888/spring-demo/swagger-ui.html
訪問格式:http://IP地址或域名:端口/應用名稱/swagger-ui.html
無關后話,與swagger 無關:授權檢測的創建繼承HandlerInterceptorAdapter 方法
package com.example.config.interceptor; import org.springframework.stereotype.Component; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author niunafei * @function * @email niunafei0315@163.com * @date 2019/6/28 下午12:31 */ @Component public class LoginInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //未開啟權限檢測 跳過 return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
token出現驗證異常 https://www.cnblogs.com/fengli9998/p/7852685.html