swagger 使用详解

本文主要介绍swagger的使用问题

swagger 依赖


        2.9.2



		
		    io.springfox
		    springfox-swagger-ui
		    ${swagger.version}
		    compile
		
		
		    io.springfox
		    springfox-swagger2
		    ${swagger.version}
		    compile
		
		
		    io.springfox
		    springfox-bean-validators
		    ${swagger.version}
		

swagger config

下面 demo in github 扩展了 basePackage,可以指定多个 目录,生成这些目录下的 api

@Configuration
@EnableSwagger2
public class Swagger2Config extends WebMvcConfigurationSupport {
    @Value("${swagger.enabled}")
    private boolean swaggerEnabled;

    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
//                .apis(RequestHandlerSelectors.basePackage("com.zhengcj.demo.swagger"))
//                .apis(basePackage(
//                        "com.zhengcj.demo.swagger.controller1",
//                        "com.zhengcj.demo.swagger.controller2"))
                .paths(PathSelectors.any())
//                .paths(PathSelectors.ant("/admin/*"))
                .build()
                .apiInfo(getApiInfo())
                .enable(swaggerEnabled);
    }

    private ApiInfo getApiInfo() {
        return new ApiInfoBuilder()
                .title("swagger title demo")
                .description("swagger description demo")
                .version("0.0.1")
                .license("@2019 demo Service. All Rights Reserved")
                .licenseUrl("https://www.demo.com")
                .contact(new Contact("zhengcj", "https://www.zhengcj.com", "[email protected]"))
                .build();
    }

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    public static Predicate basePackage(final String... basePackages) {
        return new Predicate() {
            @Override
            public boolean apply(RequestHandler input) {
                return declaringClass(input).transform(handlerPackage(basePackages)).or(true);
            }
        };
    }

    private static Function, Boolean> handlerPackage(final String... basePackages) {
        return new Function, Boolean>() {
            @Override
            public Boolean apply(Class input) {// 循环判断匹配
                for (String basePackage : basePackages) {
                    boolean isMatch = input.getPackage().getName().startsWith(basePackage);
                    if (isMatch) {
                        return true;
                    }
                }
                return false;
            }
        };
    }

    private static Optional> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }
}

swagger在Controller中使用的demo

@RestController
@Api(value = "User Controller", description = "用户控制器,相关用户接口服务")
public class UserController {
    @Autowired
    UserService userService;

    @ApiOperation(value = "根据 userId, 获取用户信息")
    @GetMapping(value = "/user/{id}")
    @ResponseBody
    public User getUser(@ApiParam(defaultValue = "1") @PathVariable Integer id) {
        return userService.getUserById(id);
    }
}

swagger在model,request param 中使用的demo

  • User model
// demo中User 有 mybatis-generator 直接生成
@Data
public class User implements Serializable {
    /**
     * user id
     */
    @ApiModelProperty(value = "user id")
    private Integer id;

    /**
     * user name
     */
    @ApiModelProperty(value = "user name")
    private String name;

    /**
     * user password
     */
    @ApiModelProperty(value = "user password")
    private String password;
}    

  • LoginRequest
@Data
public class LoginRequest {
    @Length(min=3,message = "min length of name is 3")
    @ApiModelProperty(notes = "user's name",example = "zhengcj")
    private String name;
    @Length(min=2,message = "min length of password is 2")
    @ApiModelProperty(notes = "user's password",example = "123")
    private String password;
}

全局异常处理

上面 LoginRequest 有关数据校验的部分(长度校验),当不满足条件时,会抛出全局异常,异常格式跟我们定义的不一致,可以全局捕获异常,做统一处理,如下:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public String exceptionHandler(Exception e) {
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            List errorList = exception.getBindingResult().getAllErrors();
            return errorList.stream()
                    .map(error -> error.getDefaultMessage())
                    .collect(Collectors.joining(";"));
        } else if (e instanceof HttpMessageNotReadableException) {
            return getParamErrorMessage(e);
        } else {
            e.printStackTrace();
            return "default error message";
        }
    }

    private static String getParamErrorMessage(Exception e) {
        String message = e.getMessage();
        Throwable throwable = e.getCause();
        if (throwable instanceof MismatchedInputException) {
            int start = message.lastIndexOf("[") + 2;
            int end = message.lastIndexOf("]") - 2;
            if (start >= 0 && start < end + 1 && end + 1 < message.length()) {
                String paramKey = message.substring(start, end + 1);
                return "param error: " + paramKey;
            }
        }
        return message;
    }
}

你可能感兴趣的:(源码剖析,java)