• swagger基本使用


    在spring-boot中使用

    以前总是看各种博客来配置,这次也不例外。百度了千篇一律却又各有细微的差别,甚至时间上、版本上各有不同。最终还是去看官方文档,终于发现了官方的sample。针对于各种option的操作完全在demo中了,所以clone照抄就可以用了。

    github sample源码

    配置

    1.需要依赖两个包:

    
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${springfox-version}</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>${springfox-version}</version>
            </dependency>

    第一个是API获取的包,第二是官方给出的一个ui界面。这个界面可以自定义,默认是官方的,对于安全问题,以及ui路由设置需要着重思考。

    2.swagger的configuration

    需要特别注意的是swagger scan base package,这是扫描注解的配置,即你的API接口位置。

    
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
    
        public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.test.web.controllers";
        public static final String VERSION = "1.0.0";
    
        ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("Swagger API")
                    .description("This is to show api description")
                    .license("Apache 2.0")
                    .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
                    .termsOfServiceUrl("")
                    .version(VERSION)
                    .contact(new Contact("","", "miaorf@outlook.com"))
                    .build();
        }
    
        @Bean
        public Docket customImplementation(){
            return new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
                    .build()
                    .directModelSubstitute(org.joda.time.LocalDate.class, java.sql.Date.class)
                    .directModelSubstitute(org.joda.time.DateTime.class, java.util.Date.class)
                    .apiInfo(apiInfo());
        }
    }

    当然,scan package 也可以换成别的条件,比如:

        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    .build();
        }

    3.在API上做一些声明

    //本controller的功能描述
    @Api(value = "pet", description = "the pet API")
    public interface PetApi {
    
        //option的value的内容是这个method的描述,notes是详细描述,response是最终返回的json model。其他可以忽略
        @ApiOperation(value = "Add a new pet to the store", notes = "", response = Void.class, authorizations = {
            @Authorization(value = "petstore_auth", scopes = {
                @AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
                @AuthorizationScope(scope = "read:pets", description = "read your pets")
                })
        }, tags={ "pet", })
    
        //这里是显示你可能返回的http状态,以及原因。比如404 not found, 303 see other
        @ApiResponses(value = { 
            @ApiResponse(code = 405, message = "Invalid input", response = Void.class) })
        @RequestMapping(value = "/pet",
            produces = { "application/xml", "application/json" }, 
            consumes = { "application/json", "application/xml" },
            method = RequestMethod.POST)
        ResponseEntity<Void> addPet(
        //这里是针对每个参数的描述
        @ApiParam(value = "Pet object that needs to be added to the store" ,required=true ) @RequestBody Pet body);

    案例:

    package com.test.mybatis.web.controllers;
    
    import com.test.mybatis.domain.entity.City;
    import com.test.mybatis.domain.entity.Hotel;
    import com.test.mybatis.domain.mapper.CityMapper;
    import com.test.mybatis.domain.mapper.HotelMapper;
    import com.test.mybatis.domain.model.common.BaseResponse;
    import io.swagger.annotations.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * Created by miaorf on 2016/9/10.
     */
    
    @Api(value = "Test", description = "test the swagger API")
    @RestController
    public class TestController {
    
        @Autowired
        private CityMapper cityMapper;
        @Autowired
        private HotelMapper hotelMapper;
    
        @ApiOperation(value = "get city by state", notes = "Get city by state", response = City.class)
        @ApiResponses(value = {@ApiResponse(code = 405, message = "Invalid input", response = City.class) })
        @RequestMapping(value = "/city", method = RequestMethod.GET)
        public ResponseEntity<BaseResponse<City>>  getCityByState(
                @ApiParam(value = "The id of the city" ,required=true ) @RequestParam String state){
    
            City city = cityMapper.findByState(state);
            if (city!=null){
                BaseResponse response = new BaseResponse(city,true,null);
                return new ResponseEntity<>(response, HttpStatus.OK);
            }
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    
        @ApiOperation(value = "save city", notes = "", response = City.class)
        @RequestMapping(value = "/city", method = RequestMethod.POST)
        public ResponseEntity<BaseResponse<City>> saveCity(
                @ApiParam(value = "The id of the city" ,required=true ) @RequestBody City city){
    
            int save = cityMapper.save(city);
            if (save>0){
                BaseResponse response = new BaseResponse(city,true,null);
                return new ResponseEntity<>(response, HttpStatus.OK);
            }
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    
        @ApiOperation(value = "save hotel", notes = "", response = Hotel.class)
        @RequestMapping(value = "/hotel", method = RequestMethod.POST)
        public ResponseEntity<BaseResponse<Hotel>> saveHotel(
                @ApiParam(value = "hotel" ,required=true ) @RequestBody Hotel hotel){
    
            int save = hotelMapper.save(hotel);
            if (save>0){
                BaseResponse response = new BaseResponse(hotel,true,null);
                return new ResponseEntity<>(response, HttpStatus.OK);
            }
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    
        @ApiOperation(value = "get the hotel", notes = "get the hotel by the city id", response = Hotel.class)
        @RequestMapping(value = "/hotel", method = RequestMethod.GET)
        public ResponseEntity<BaseResponse<Hotel>> getHotel(
                @ApiParam(value = "the hotel id" ,required=true ) @RequestParam Long cid){
    
            List<Hotel> hotels = hotelMapper.selectByCityId(cid);
            return new ResponseEntity<>(new BaseResponse(hotels,true,null), HttpStatus.OK);
        }
    
        @ApiOperation(value = "update the hotel", notes = "update the hotel", response = Hotel.class)
        @RequestMapping(value = "/hotel", method = RequestMethod.PUT)
        public ResponseEntity<BaseResponse<Hotel>> updateHotel(
                @ApiParam(value = "the hotel" ,required=true ) @RequestBody Hotel hotel){
    
            int result = hotelMapper.update(hotel);
            return new ResponseEntity<>(new BaseResponse(result,true,null), HttpStatus.OK);
        }
    
    
        @ApiOperation(value = "delete the  hotel", notes = "delete the hotel by the hotel id", response = City.class)
        @RequestMapping(value = "/hotel", method = RequestMethod.DELETE)
        public ResponseEntity<BaseResponse<Hotel>> deleteHotel(
                @ApiParam(value = "the hotel id" ,required=true ) @RequestParam Long htid){
    
            int result = hotelMapper.delete(htid);
            return new ResponseEntity<>(new BaseResponse(result,true,null), HttpStatus.OK);
        }
    
    
    }

    4.设定访问API doc的路由

    在配置文件中,application.yml中声明:

    springfox.documentation.swagger.v2.path: /api-docs

    这个path就是json的访问request mapping.可以自定义,防止与自身代码冲突。

    API doc的显示路由是:http://localhost:8080/swagger-ui.html

    如果项目是一个webservice,通常设定home / 指向这里:

    @Controller
    public class HomeController {
    
        @RequestMapping(value = "/swagger")
        public String index() {
            System.out.println("swagger-ui.html");
            return "redirect:swagger-ui.html";
        }
    }

    5.访问

    就是上面的了。但是,注意到安全问题就会感觉困扰。首先,该接口请求有几个:

    http://localhost:8080/swagger-resources/configuration/ui
    http://localhost:8080/swagger-resources
    http://localhost:8080/api-docs
    http://localhost:8080/swagger-resources/configuration/security
    

    除却自定义的url,还有2个ui显示的API和一个安全问题的API。关于安全问题的配置还没去研究,但目前发现一个问题是在我的一个项目中,所有的url必须带有query htid=xxx,这是为了sso portal验证的时候需要。这样这个几个路由就不符合要求了。

    如果不想去研究安全问题怎么解决,那么可以自定ui。只需要将ui下面的文件拷贝出来,然后修改请求数据方式即可。

    6. 设置在生产环境关闭swagger


    前言

    Swagger使用起来简单方便,几乎所有的API接口文档都采用swagger了。

    使用示例:http://www.cnblogs.com/woshimrf/p/swagger.html

    现在开发中可以参考文档,但生产环境并不想暴露出去。

    在dropwizard中使用

    详细信息见另一篇在dropwizard中使用Swagger

    配置

    只要在不同环境中配置是否启用就可以了。

    @Value("${swagger.enable}")
    private boolean enableSwagger;
    
    @Bean 
    public Docket customImplementation(){
        return new Docket(SWAGGER_2)
            .apiInfo(apiInfo())
            .enable(enableSwagger) //<--- Flag to enable or disable possibly loaded using a property file
            .includePatterns(".*pet.*");
    }

    然后,我想在dev和test环境中启用,直接在配置文件中添加配置:

    swagger:
      enable: true
    正因为当初对未来做了太多的憧憬,所以对现在的自己尤其失望。生命中曾经有过的所有灿烂,终究都需要用寂寞来偿还。
  • 相关阅读:
    绿有四季关于需求沟通
    模板引擎开发(二)值标签的处理
    Jquery插件浮动广告
    项目经理的“势能”培养
    模板引擎开发(一)
    c#读取apk 信息
    golang读取文件信息插入mongodb
    白话MongoDB(二)(转载)
    golang 读取mongob数据写入sqlserver
    golang 通用Contains方法
  • 原文地址:https://www.cnblogs.com/candlia/p/11920138.html
Copyright © 2020-2023  润新知