swagger 404问题+解决跨域问题
缘起:今天做springboot集成swagger文档的时候。出现了404问题。什么集成swagger 这不有手就行?先加依赖:<!--swagger 依赖--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId&
缘起:今天做springboot集成swagger文档的时候。
出现了404问题。
什么集成swagger 这不有手就行?
先加依赖:
<!--swagger 依赖-->
<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配置类 SwaggerConfig
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2).
// 指定构建 api 文档的详细信息的方法:
apiInfo(apiInfo()).apiInfo(apiInfo())
.select()
// 指定要生成 api 接口的包路径,这里把 controller 作为包路径,生成 controller 中的所有接口
.apis(RequestHandlerSelectors.basePackage("com.zry.qiniu.controller"))
.paths(PathSelectors.any())
.build();
}
/**
* 构建 api 文档的详细信息
*
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 设置页面标题
.title("接口文档")
.contact(new Contact("基于树莓派的动态图片捕捉系统", "", "1447051936@qq.com"))
// 设置接口描述
.description("Api文档: 注意!! Date格式: yyyy-MM-dd HH:mm:ss")
// 设置版本
.version("1.0")
// 构建
.build();
}
}
浏览器访问:
啥404? what?
开始排查:
访问 http://localhost:8081/v2/api-docs 看一下swagger接口是否有数据
有数据说明配置没有问题。看来是静态资源被拦截了。
咱们就开放它的静态资源。
下面代码:
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 功能描述: 开放静态资源
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
//重写这个方法,映射静态资源文件
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/pages/")
;
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
}
再次访问 还是404? 没有啥变化。。。。
??????????
再次研究排查:
对比之前的项目,我发现我这次的项目中多了个解决跨域问题的代码:
@Configuration
public class WebApiConfig extends WebMvcConfigurationSupport {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true).maxAge(3600);
}
把这个configuration注释掉就可以了。
原因:
这个自定义的类继承自WebMvcConfigurationSupport,如果你在IDE中搜索这个类的实现类,可以发现spring boot有一个子类EnableWebMvcConfiguration,并且是自动config的.我们知道,如果一个类用户自己在容器中生成了bean,spring boot就不会帮你自动config。所以,问题的原因是我们把spring boot自定义的那个bean覆盖了。
那么我想既然使用跨域又使用swagger该怎么办呢?只需加上下面的代码。
/**
* @author zry
* @create 2022-04-09 17:31
*/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 功能描述: 开放静态资源
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
//重写这个方法,映射静态资源文件
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/pages/")
;
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
.allowCredentials(true).maxAge(3600);
}
}
这样就可以了。
扩展跨域问题解决:
来自:https://cloud.tencent.com/developer/article/1924258
方法1:全局配置
定义配置类,添加@Configuration注解,实现WebMvcConfigurer接口,再重写addCorsMappings方法:
就是上面的代码。
方法2:局部跨域
Controller层在需要跨域的类或者方法上加上@CrossOrigin该注解即可。
@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
final UserService userService;
@GetMapping("/getOne/{id}")
public User getOne(@PathVariable("id") Integer id) {
return userService.getById(id);
}
我们也可以设置更小的粒度,在方法上设置跨域:
@Controller
@RequestMapping("/shop")
public class ShopController {
@GetMapping("/")
@ResponseBody
//更小的解决跨域 设置只能某些地址访问
@CrossOrigin(originPatterns = "http://localhost:8080")
public Map<String, Object> findAll() {
//返回数据
return DataSchool.getStudents();
}
}
方法3:定义跨域过滤器
1)编写过滤器
// 跨域过滤器
@Component
public class CORSFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//*号表示对所有请求都允许跨域访问
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Credentials", "true");
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
response.getWriter().println("Success");
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
2)注册过滤器
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
更多推荐
所有评论(0)