引入pom依赖
<!-- knife4j start -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.9</version>
<exclusions>
<exclusion>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-metadata</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-metadata</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<!-- knife4j end -->
knife4j配置类
import com.fas.base.model.FasConstants;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* <br> @author yb
* <br> @date 2022/12/26 17:50
* <br> @version 1.0
* <br> MyWebConfiguration 设置默认 Content-Type 和 响应数据编码
*/
@Configuration
@EnableSwagger2WebMvc
@EnableKnife4j
public class MyWebConfiguration implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
}
@Bean
public HttpMessageConverter responseBodyConverter(){
return new StringHttpMessageConverter(Charset.forName("UTF-8"));
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(responseBodyConverter());
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Bean
public Docket commonDocket(){
List<Parameter> pars = new ArrayList<>();
ParameterBuilder tokenPar = new ParameterBuilder();
// 设置全局公共参数,需要token的可在此设置,所有接口都会追加该参数
tokenPar.name("Authorization").description("token").modelRef(new ModelRef("String")).parameterType("header").required(true);
pars.add(tokenPar.build());
return new Docket(DocumentationType.SWAGGER_2)
// .groupName("yb")
.apiInfo(apiInfo("项目API文档"))
.pathMapping("/")
.select()
// 需要扫描的接口层
.apis(RequestHandlerSelectors.basePackage("com.yb.controller"))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(pars)
.enable(true);// 是否启用接口文档,上生产后关闭
}
private ApiInfo apiInfo(String desc) {
return new ApiInfoBuilder()
.title(desc)
// .contact(new Contact("yb", "http://localhost:8080/doc.html", "123@163.com"))
.version("1.0.0")
.description("API 描述")
.termsOfServiceUrl("")
.build();
}
}
对跨域提供支持
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 对跨域提供支持
*/
//@Configuration
@Component
public class CorsConfig extends AccessControlFilter {
@Override
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
return false;
}
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
return false;
}
/**
* 对跨域提供支持
*
* @param request
* @param response
* @return
* @throws Exception
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Content-Type", MediaType.APPLICATION_JSON_UTF8_VALUE);
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpServletResponse.setStatus(HttpStatus.OK.value());
return false;
}
return super.preHandle(request, response);
}
}
如果项目集成了shiro,需要对以下请求进行放行
/webjars/**
/swagger-resources/**
/v2/**
/doc.html
接口类注释
![](https://img-blog.csdnimg.cn/img_convert/14b10032dca44850cf4af7687adcf52e.png)
方法注释
![](https://img-blog.csdnimg.cn/img_convert/4cfb222cba58413698569d56c1499066.png)
实体类注释
实体类属性字段如果是大写,需要用 @JsonProperty 进行注释,否则生成接口属性文档会无法对应。纯小写则不需要
![](https://img-blog.csdnimg.cn/img_convert/27fa087ee2582362bc1b9bdd1d7d93d6.png)
![](https://img-blog.csdnimg.cn/img_convert/a015ae4017ce5d8ebe6d5b5dc6d6bf98.png)
请求地址
ip:port/projectName/doc.html
![](https://img-blog.csdnimg.cn/img_convert/8bb2b86648bae13a65a49558b2872f3a.png)