依赖

    <!--swagger        -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <!--swagger-ui.html模式        -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
    <!--doc.html模式        -->
    <dependency>
        <groupId>com.github.xiaoymin</groupId>
        <artifactId>swagger-bootstrap-ui</artifactId>
        <version>1.9.2</version>
    </dependency>

配置端口号

server.port=1313
#启动会报错(原因:Springfox使用的路径匹配基于AntPathMatcher,而Spring Boot 2.6.X使用的是PathPatternMatcher。)
#org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
spring.mvc.pathmatch.matching-strategy=ant_path_matcher

启动类添加注解( @EnableSwagger2 )

@EnableSwagger2
@SpringBootApplication
public class JavaApplication {

    public static void main(String[] args) {
        SpringApplication.run(JavaApplication.class, args);
    }

}

注解介绍

/**
 * Api注解:定义接口名称
 * ApiOperation注解:定义方法名称
 * ApiImplicitParam注解:定义param参数的各个属性
 *
 * ApiModel注解:定义对象名称
 * ApiModelProperty注解:定义参数名称
 */
@Api(tags = "测试接口")
@RestController
public class TestController {

    @ApiOperation(value = "测试01")
    @GetMapping("/test01")
    public String Test01(){
        return "Test01";
    }

}

访问地址:http://localhost:1313/swagger...
或者http://localhost:1313/doc.html

新增配置类

/**
 * @EnableSwagger2:开启swagger,此处也需要使用。
 * @Profile("swagger"):指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件。
 * 
 * spring.profiles.active=swagger
 *
 */
@Configuration
@EnableSwagger2
@Profile("swagger")
public class SwaggerConfig {
    /**
     * 创建API应用 apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     *
     * @return
     */
    @Bean
    public Docket createRestApi() {
        // 选择那些路径和api会生成document
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).pathMapping("/").select()
                // 对所有api进行监控
                .apis(RequestHandlerSelectors.any())
                .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)).build()
                // 配置token
                .globalOperationParameters(setHeaderToken());
    }

    /**
     * 配置token
     *
     * @return
     */
    private List<Parameter> setHeaderToken() {
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        tokenPar.name("Authorization").description("token").modelRef(new ModelRef("string")).parameterType("header")
                .required(false).build();
        pars.add(tokenPar.build());
        return pars;
    }

    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     *
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("测试接口文档").description("测试接口文档").version("1.0").build();
    }

}

拦截器

@Component
public class TokenInterceptor implements HandlerInterceptor {

    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        userMapper.selectList(null);
        //跨域请求会首先发一个option请求,直接返回正常状态并通过拦截器
        if (request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        response.setCharacterEncoding("utf-8");
        String token = request.getHeader("token");
        if (token!=null){
            Boolean result = TokenUtils.verify(token);
            if (result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        response.setContentType("application/json; charset=utf-8");
        try {
            JSONObject json = new JSONObject();
            json.put("msg","token verify fail");
            json.put("code","500");
            response.getWriter().append(json.toString());
            System.out.println("认证失败,通过拦截器失败");
        }catch (Exception e){
            return false;
        }

        return false;
    }
}

WebMVC配置

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Bean
    public HandlerInterceptor getTokenInterceptor(){
        return new TokenInterceptor();
    }

    /**
     * 异步请求配置
     * @param configurer
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(new ConcurrentTaskExecutor(Executors.newFixedThreadPool(3)));
        configurer.setDefaultTimeout(30000);
    }

    /**
     * 配置拦截器、拦截路径
     * 每次请求到拦截的路径,就会去执行拦截器中的方法
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> excludePath = new ArrayList<>();
        //排除拦截,除了注册登录(此时还没token),其他都拦截
        excludePath.add("/login");  //登录
        excludePath.add("/register");     //注册
        excludePath.add("/doc.html");     //swagger
        excludePath.add("/swagger-ui.html");     //swagger
        excludePath.add("/swagger-resources/**");     //swagger
        excludePath.add("/v2/api-docs");     //swagger
        excludePath.add("/webjars/**");     //swagger
//        excludePath.add("/static/**");  //静态资源
//        excludePath.add("/assets/**");  //静态资源
        registry.addInterceptor(getTokenInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(excludePath);
        WebMvcConfigurer.super.addInterceptors(registry);

    }

    /**
     * 解决跨域请求
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("*")
                .allowedMethods("*")
//                .allowedOrigins("*")
                .allowedOriginPatterns("*")
                .allowCredentials(true);
    }

}

token生成

public class TokenUtils {

    //token到期时间10小时
    private static final long EXPIRE_TIME= 10*60*60*1000;
    //密钥盐
    private static final String TOKEN_SECRET="ljdyaishijin**3nkjnj??";

    /**
     * 生成token
     * @param user
     * @return
     */
    public static String sign(User user){

        String token=null;
        try {
            Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
            token = JWT.create()
                    //发行人
                    .withIssuer("auth0")
                    //存放数据
                    .withClaim("username",user.getUserName())
                    //过期时间
                    .withExpiresAt(expireAt)
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (IllegalArgumentException| JWTCreationException je) {

        }
        return token;
    }


    /**
     * token验证
     * @param token
     * @return
     */
    public static Boolean verify(String token){

        try {
            //创建token验证器
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT decodedJWT=jwtVerifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("username: " + decodedJWT.getClaim("username").asString());
            System.out.println("过期时间:      " + decodedJWT.getExpiresAt());
        } catch (IllegalArgumentException | JWTVerificationException e) {
            //抛出错误即为验证不通过
            return false;
        }
        return true;
    }

}

token生成

public class Token {

    //token到期时间(毫秒)
    private static final long TIME = 10 * 60 * 1000;
    //密钥盐
    private static final String TOKEN = "123";

    /**
     * 生成token
     *
     * @return
     */
    public static String sign() {
        String token = null;
        try {
            Date date = new Date(System.currentTimeMillis() + TIME);
            token = JWT.create()
                    //发行人
                    .withIssuer("lll")
                    //存放数据
                    .withClaim("username", "linweibin")
                    //设置过期时间
                    .withExpiresAt(date)
                    //加密
                    .sign(Algorithm.HMAC256(TOKEN));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }

    /**
     * token验证
     *
     * @param token
     * @return
     */
    public static Boolean verify(String token) {
        try {
            //创建token验证器
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(TOKEN)).withIssuer("lll").build();
            DecodedJWT verify = jwtVerifier.verify(token);
            //解密获取数据
            System.out.println("username: " + verify.getClaim("username").asString());
            System.out.println("过期时间:      " + verify.getExpiresAt());
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}

LLL_
15 声望3 粉丝

« 上一篇
JAVA
下一篇 »
Java定时任务