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
来源:oschina
链接:https://my.oschina.net/u/4285053/blog/4404825