zoukankan      html  css  js  c++  java
  • Spring Boot 集成 Swagger 2

    工程创建

    当然,首先是创建一个Spring Boot项目,加入web依赖,创建成功后,加入两个Swagger2相关的依赖,完整的依赖如下:

    <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>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    Swagger2配置

    Swagger2的配置也是比较容易的,在项目创建成功之后,只需要开发者自己提供一个Docket的Bean即可,如下:

    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .pathMapping("/")
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.nvn.controller"))
                    .paths(PathSelectors.any())
                    .build().apiInfo(new ApiInfoBuilder()
                            .title("SpringBoot整合Swagger")
                            .description("SpringBoot整合Swagger,详细信息......")
                            .version("9.0")
                            .contact(new Contact("啊啊啊啊","blog.csdn.net","aaa@gmail.com"))
                            .license("The Apache License")
                            .licenseUrl("http://www.baidu.com")
                            .build());
        }
    }

    这里提供一个配置类,首先通过@EnableSwagger2注解启用Swagger2,然后配置一个Docket Bean,这个Bean中,配置映射路径和要扫描的接口的位置,在apiInfo中,主要配置一下Swagger2文档网站的信息,例如网站的title,网站的描述,联系人的信息,使用的协议等等。

    如此,Swagger2就算配置成功了,非常方便。

    此时启动项目,输入http://localhost:8080/swagger-ui.html,能够看到如下页面,说明已经配置成功了:

    创建接口

    接下来就是创建接口了,Swagger2相关的注解其实并不多,而且很容易懂,下面我来分别向小伙伴们举例说明:

    @RestController
    @Api(tags = "用户管理相关接口")
    @RequestMapping("/user")
    public class UserController {
    
        @PostMapping("/")
        @ApiOperation("添加用户的接口")
        @ApiImplicitParams({
                @ApiImplicitParam(name = "username", value = "用户名", defaultValue = "李四"),
                @ApiImplicitParam(name = "address", value = "用户地址", defaultValue = "深圳", required = true)
        }
        )
        public RespBean addUser(String username, @RequestParam(required = true) String address) {
            return new RespBean();
        }
    
        @GetMapping("/")
        @ApiOperation("根据id查询用户的接口")
        @ApiImplicitParam(name = "id", value = "用户id", defaultValue = "99", required = true)
        public User getUserById(@PathVariable Integer id) {
            User user = new User();
            user.setId(id);
            return user;
        }
        @PutMapping("/{id}")
        @ApiOperation("根据id更新用户的接口")
        public User updateUserById(@RequestBody User user) {
            return user;
        }
    }

    这里边涉及到多个API,我来向小伙伴们分别说明:

    1. @Api注解可以用来标记当前Controller的功能。
    2. @ApiOperation注解用来标记一个方法的作用。
    3. @ApiImplicitParam注解用来描述一个参数,可以配置参数的中文含义,也可以给参数设置默认值,这样在接口测试的时候可以避免手动输入。
    4. 如果有多个参数,则需要使用多个@ApiImplicitParam注解来描述,多个@ApiImplicitParam注解需要放在一个@ApiImplicitParams注解中。
    5. 需要注意的是,@ApiImplicitParam注解中虽然可以指定参数是必填的,但是却不能代替@RequestParam(required = true),前者的必填只是在Swagger2框架内必填,抛弃了Swagger2,这个限制就没用了,所以假如开发者需要指定一个参数必填,@RequestParam(required = true)注解还是不能省略。
    6. 如果参数是一个对象(例如上文的更新接口),对于参数的描述也可以放在实体类中。例如下面一段代码:
    @ApiModel
    public class User {
        @ApiModelProperty(value = "用户id")
        private Integer id;
        @ApiModelProperty(value = "用户名")
        private String username;
        @ApiModelProperty(value = "用户地址")
        private String address;
        //getter/setter

     config  配置实例(实战已经用过的配置)

    package com.kmair.offical.member.config;
    
    import com.google.common.base.Function;
    import com.google.common.base.Optional;
    import com.google.common.base.Predicate;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Profile;
    import springfox.documentation.RequestHandler;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    
    @Configuration
    @EnableSwagger2
    @Profile({ "dev", "test", "predeploy" })
    public class SwaggerConfig {
    
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder().title("api").description("仅供测试,开发,产品参考")
                    // 服务条款网址
                    .termsOfServiceUrl("").version("1.0")
                    .contact(new Contact("name", "http://name.cn", "ssstt.com")).build();
        }
    
        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
                    // 自行修改为自己的包路径
                    .apis(SwaggerConfig.basePackage(
                            "com.kmair.offical.common,com.kmair.offical.member"))
                    .paths(PathSelectors.any()).build();
        }
         public static Predicate<RequestHandler> basePackage(final String basePackage) {
            return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
        }
    
        private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
            return input -> {
                for (String strPackage : basePackage.split(",")) {
                    boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                    if (isMatch) {
                        return true;
                    }
                }
                return false;
            };
        }
    
        private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
            return Optional.fromNullable(input.declaringClass());
        }
    }

     解决不能访问的问题

    /**
     * LY.com Inc.
     * Copyright (c) 2004-2017 All Rights Reserved.
     */
    package com.kmair.offical.member.config;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = "com.kmair.offical")
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
            // 解决swagger-ui不能访问问题
            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("/**")
    //                .allowedHeaders("*")
    //                .allowedMethods("*")
    //                .allowedOrigins("*");
    //    }
             /*@Bean
        public GsonHttpMessageConverter responseBodyConverter() {
            GsonHttpMessageConverter gsonHttpMessageConverter = new GsonHttpMessageConverter();
            gsonHttpMessageConverter.setDefaultCharset(Charset.forName("UTF-8"));
            gsonHttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
            gsonHttpMessageConverter.setGson(new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd").create());
            return gsonHttpMessageConverter;
        }
    
        @Bean
        RiskHandlerInterceptor riskInterceptor() {
            return new RiskHandlerInterceptor();
        }
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            super.configureMessageConverters(converters);
            converters.add(responseBodyConverter());
        }
    
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(riskInterceptor()).addPathPatterns("/**");
        }*/
    }

     跨域配置

    package com.kmair.offical.member.config;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    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;
    
    
    @Configuration
    public class CorsConfig {
    
        @Bean
        public FilterRegistrationBean corsFilter() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration config = new CorsConfiguration();
            config.setAllowCredentials(true); // 允许cookies跨域
            config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
            config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
            config.setMaxAge(1800L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
            config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
            source.registerCorsConfiguration("/**", config);
            FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
            bean.setOrder(0); // 跨域的过滤器要放在第一位
            return bean;
        }
    }

    在Security中的配置

    如果我们的Spring Boot项目中集成了Spring Security,那么如果不做额外配置,Swagger2文档可能会被拦截,此时只需要在Spring Security的配置类中重写configure方法,添加如下过滤即可:

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                .antMatchers("/swagger-ui.html")
                .antMatchers("/v2/**")
                .antMatchers("/swagger-resources/**");
    }
    故乡明
  • 相关阅读:
    ASP.NET Core 2.0 : 四. _Layout与_ViewStart
    [ASP.NET MVC 小牛之路]04
    [ASP.NET MVC 小牛之路]03
    [ASP.NET MVC 小牛之路]02
    [ASP.NET MVC 小牛之路]01
    Ext JS 4 的类系统
    生活沉思录 via 哲理小故事(一)
    ExtJS框架基础:事件模型及其常用功能
    ExtJS初探:了解 Ext Core
    ExtJS初探:在项目中使用ExtJS
  • 原文地址:https://www.cnblogs.com/luweiweicode/p/14276170.html
Copyright © 2011-2022 走看看