SpringBoot集成MybatisPlus, Redis,hikari ,swagger2 带配置写法

版权声明:博客原创,转载须标明出处 https://blog.csdn.net/qq_24232123/article/details/84388123

工具idea , 模块化项目搭建

1:先创建一个project 删掉其中的src等多余目录 ,留一个 pom.xml

pom.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.text</groupId>
   <artifactId>demo</artifactId>
   <version>1.0-SNAPSHOT</version>
   
<!-- 定义版本-->
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.0.4.RELEASE</version>
   </parent>

</project>

2:右键项目,创建一个module 项目 【demoAdmin】 , 注:创建项目后,外层pom会多个 modules

此模块 pom.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <parent>
       <artifactId>demo</artifactId>
       <groupId>com.text</groupId>
       <version>1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>

   <artifactId>demoAdmin</artifactId>


   <dependencies>

   <!-- 支持web -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>

   <!--get  set   data 等插件  -->
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <optional>true</optional>
   </dependency>

   <!--mybatis-plus 核心包 -->
   <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.0.5</version>
   </dependency>

   <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus</artifactId>
       <version>3.0.5</version>
   </dependency>


   <!-- mybatis-plus velocity 模板引擎, 默认-->
   <dependency>
       <groupId>org.apache.velocity</groupId>
       <artifactId>velocity-engine-core</artifactId>
       <version>2.0</version>
   </dependency>



   <!-- 连接池 6以上版本在连接属性中要加上[ &serverTimezone=Asia/Shanghai ]  6.0 版本以上必须配置此参数-->
   <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
       <version>8.0.11</version>
   </dependency>


   <!-- redis -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-redis</artifactId>
       <version>2.0.4.RELEASE</version>
   </dependency>

   <!-- swagger2 -->
   <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger2</artifactId>
       <version>2.8.0</version>
   </dependency>
   <dependency>
       <groupId>io.springfox</groupId>
       <artifactId>springfox-swagger-ui</artifactId>
       <version>2.8.0</version>
   </dependency>

   <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>fastjson</artifactId>
       <version>1.2.47</version>
   </dependency>

       <!-- 自定义jar  ,名字随便起,尽量统一规范(此处防止打包时,打不进去第三方jar)-->
       <!--   <dependency>
              <groupId>custom</groupId>
              <artifactId>customSelf</artifactId>
              <version>1.0.0</version>
              <scope>system</scope>
              <systemPath>${project.basedir}/src/main/resources/lib/custom-3.3.1.jar</systemPath>
          </dependency>-->

   </dependencies>

   <build>
          <resources>
              <resource>
                  <directory>src/main/resources</directory>
              </resource>
              <resource>   <!-- 将jar统一打进lib目录下 -->
                  <directory>src/main/resources/lib</directory>
                  <targetPath>BOOT-INF/lib</targetPath>
              </resource>
          </resources>

       <!-- 配置打包及打包后的项目存放路径 outputDirectory -->
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
               <configuration>
                   <fork>true</fork>
                   <finalName>${project.name}</finalName>
                   <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                   <outputDirectory>E:/compose/demoJar</outputDirectory>
               </configuration>
           </plugin>
       </plugins>



   </build>



</project>

3:代码写法 项目结构如下图:

项目结构

包文件解释:

              common:  公共类配置
              config:  配置文件
              config.interceptor:  拦截器配置
              controller: 控制器
              dao: dao层
              model.dto: 入参类
              model.entity: 实体类
              model.vo : 出参类
              service : 接口类
              service.impl: 接口实现类
              shiro: 权限类
              util: 工具类
              AdminApplication.class :  启动入口

3-1:resources 配置

application.yml 如下图:

# 服务器配置 以自己的配置为主
server:
 port: 8070
 servlet:
   context-path: /admin

mybatis-plus:
 mapper-locations: classpath:/mapper/*.xml
 type-aliases-package: com.demo.model.entity

logging:
 config: classpath:logback-spring.xml

spring:
 profiles:
   #active: main # 正式环境
    active: demo     #测试环境

application-demo.yml 如下图:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      maximum-pool-size: 15
      max-lifetime: 180000
      idle-timeout: 60000
      connection-timeout: 20000
      minimum-idle: 5
  redis:
    port: 6379
    host: 127.0.0.1
    password:123456

banner.txt 如下图:

${AnsiColor.BRIGHT_YELLOW}
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//     佛祖保佑    Admin    永不宕机     永无BUG               //
////////////////////////////////////////////////////////////////////

${AnsiColor.BRIGHT_RED}
Application Version: ${application.version}${application.formatted-version}
Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}

logback-spring.xml 如下图:

<?xml version="1.0" encoding="UTF-8"?>


<configuration debug="false" scan="false">
    <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue="home"/>
    <property name="LOG_HOME" value="/home/demo/logs/admin" />
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%yellow(%d{yyyy-MM-dd HH:mm:ss}) [%-5level] [ %boldMagenta(%logger{50}) ] - %cyan(%msg%n)
            </pattern>
        </encoder>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/admin.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <fileNamePattern>${LOG_HOME}/admin.log.%d{yyyy-MM-dd}.part%i.gz</fileNamePattern>
            <!-- 同时按照大小和日期分割日志文件 -->
            <maxFileSize>2GB</maxFileSize>
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>


    <logger name="com.demo.dao" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </logger>

    <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 -->
    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>

</configuration>

3-2 common 包结构class如下图:

common 结构

类文件解释:
     ApiCommonController:  自定义父类 ,封装了自定义异常监控
     BaseController: 自定义父类 ,封装了返回结果对象,获取ip
     BaseDto:  分页类,用于传参对象继承使用
     BusinessException: 自定义异常
     CodeGeneration:  mybatisPlus 代码生成器
     Result:  返回结果对象

ApiCommonController.java 代码如下

package com.demo.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@Slf4j
public class ApiCommonController extends BaseController {

   /**
    * 抛出自定义BusinessException异常
    */
   @ExceptionHandler({BusinessException.class})
   @ResponseBody
   public Result business(BusinessException ex) {
       log.info(ex.toString());
       return new Result(Result.ERROR,ex.getMessage());
   }



   protected void check(String code ,Object obj){
       if (obj==null||obj.toString().trim().equals("null")||obj.toString().trim().length()==0) {
           throw new BusinessException("参数[" +code+ "]不能为空");
       }
   }



}

BaseController.java 如下图:

package com.demo.common;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;

@Slf4j
public class BaseController {

    @Autowired
    protected HttpServletRequest request;

    /**
     * 返回成功结果集
     */
    protected Result ajaxDoneSuccess(Object data) {
        return new Result(Result.SUCCESS, Result.SUCCESSMSG, data);
    }

    protected Result ajaxDoneSuccess(Object data,Integer total) {
        return new Result(Result.SUCCESS, Result.SUCCESSMSG, data,total);
    }

    /**
     * 返回成功结果
     */
    protected Result ajaxDoneSuccess(String message) {
        return new Result(Result.SUCCESS, message);
    }

    /**
     * 返回成功结果和对象
     */
    protected Result ajaxDoneSuccess(String message,Object data) {
        return new Result(Result.SUCCESS, message,data);
    }

    /**
     * 返回失败结果集
     */
    protected Result ajaxDoneError(String message) {
        return new Result(Result.ERROR, message);
    }

    /**
     * 获取ip
     */
    protected String getRealIp(){
        String ip = request.getHeader("X-Real-IP");
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("x-forwarded-for");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }



}

BaseDto.java 代码如下图:

package com.demo.common;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
public class BaseDto {

    @ApiModelProperty(value = "当前第几页")
    private Integer pageIndex = 1;//当前第几页

    @ApiModelProperty(value = "每页显示数")
    private Integer pageSize = 10;  //每页显示数

    @ApiModelProperty(value = "开始时间 -查询")
    private String beginTime;

    @ApiModelProperty(value = "结束时间 -查询")
    private String endTime;//结束时间 -查询
}

BusinessException.java 如下图:

package com.demo.common;


/**
 * 自定义异常
 */
public class BusinessException extends  RuntimeException  {
	public BusinessException(String msg){
		super(msg);  
	}

}

Result.java 如下图:

package com.demo.common;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;


@Data
public class Result {
    public static final int SUCCESS = 200;
    public static final int ERROR= 500;
    public static final String SUCCESSMSG = "成功";

    @ApiModelProperty(value = "状态码 200")
    private int code = 0;

    @ApiModelProperty(value = "说明信息")
    private String msg = "";

    @ApiModelProperty(value = "数据")
    private Object data;

    @ApiModelProperty(value = "数据总条数")
    private Integer total=0; //条数

    public Result(int code,String msg){
        this.code=code;
        this.msg=msg;
    }

    public Result(int code,String msg,Object data){
        this.code=code;
        this.msg=msg;
        this.data=data;
    }

    public Result(int code,String msg,Object data ,Integer total){
        this.code=code;
        this.msg=msg;
        this.data=data;
        this.total=total;
    }
}

CodeGeneration.java 代码生成器 如下图:

package com.demo.common;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class CodeGeneration {

    /**
     *
     * @Title: main
     * @Description: 文件生成器 运行main方法即可
     * @param args
     */
    public static void main(String[] args) {
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir("E://generation//temp");
        gc.setFileOverride(true);
        gc.setActiveRecord(false);// 不需要ActiveRecord特性的请改为false
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(true);// XML ResultMap
        gc.setBaseColumnList(false);// XML columList
        gc.setAuthor("ccm");// 作者

        // 自定义文件命名,注意 %s 会自动填充表实体属性!
        //gc.setControllerName("%sAction");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setMapperName("%sDao");
        gc.setXmlName("%sMapper");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8");
        mpg.setDataSource(dsc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //strategy.setTablePrefix(new String[] { "sys_" });// 此处可以修改为您的表前缀
        strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
        //strategy.setInclude(new String[] { "sys_user" }); // 需要生成的表

        strategy.setSuperServiceClass(null);
        strategy.setSuperServiceImplClass(null);
        strategy.setSuperMapperClass(null);

        mpg.setStrategy(strategy);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.demo");
        //pc.setController("controller");
        pc.setService("service");
        pc.setServiceImpl("service.serviceImpl");
        pc.setMapper("dao");
        pc.setEntity("model.entity");
        pc.setXml("xml");
        mpg.setPackageInfo(pc);

        // 执行生成
        mpg.execute();

    }

}

3-3 config 包结构class如下图:

在这里插入图片描述

类文件解释:
     HandlerInterceptorConfig:  拦截器
     MyHandlerInterceptorConfig:  自定义拦截
     corsFilter:   跨域
     MybatisPlusConfig:  MybatisPlus配置
     RedisConfig:  	Redis配置
     SwaggerConfig:   Swagger2配置

HandlerInterceptorConfig.java 代码如下:

package com.demo.config.interceptor;

import com.demo.common.BusinessException;
import com.demo.config.RedisConfig;
import com.demo.shiro.ShiroAdmin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class HandlerInterceptorConfig implements HandlerInterceptor {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        HttpSession session= request.getSession();
        String keyName=RedisConfig.reids_prefix+session.getId();
        ShiroAdmin shiroAdmin= (ShiroAdmin) redisTemplate.opsForValue().get(keyName);
        if (shiroAdmin==null){
          throw  new BusinessException("当前账号未登录,请先登陆");
       }
        String token = request.getHeader("token");
         if (token == null || token.trim().length() == 0) {
             throw new BusinessException("token 禁止为空");
         }
         if (!shiroAdmin.getToken().equals(token)) {
             throw new BusinessException("账号在其他地方登录,请重新登录");
         }
        shiroAdmin.setSessionId(" 被拦截 当前会话:"+session.getId());
        request.getSession().setAttribute("shiroAdmin",shiroAdmin);
        redisTemplate.expire(keyName,2,TimeUnit.HOURS);
        return true;
    }



}

CorsConfig.java 代码如下:

package com.demo.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * 跨域配置
 */

@Configuration
public class CorsConfig {

    // CORS
    @Bean
    FilterRegistrationBean corsFilter(@Value("*") String origin) {
        return new FilterRegistrationBean(new Filter() {
            public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                    throws IOException, ServletException {
                HttpServletRequest request = (HttpServletRequest) req;
                HttpServletResponse response = (HttpServletResponse) res;
                String method = request.getMethod();

                response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
                response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE");
                response.setHeader("Access-Control-Max-Age", Long.toString(60 * 60));
                response.setHeader("Access-Control-Allow-Credentials", "true");
                response.setHeader("Access-Control-Allow-Headers", "token,Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
                if ("OPTIONS".equals(method)) {
                    response.setStatus(HttpStatus.OK.value());
                } else {
                    chain.doFilter(req, res);
                }
            }
            public void init(FilterConfig filterConfig) {
            }

            public void destroy() {
            }
        });
    }

}

MyHandlerInterceptorConfig.java 代码如下:

package com.demo.config.interceptor;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class MyHandlerInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private HandlerInterceptor handlerInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(handlerInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/login/**")
                .excludePathPatterns("/*.html")
                .excludePathPatterns("/webjars/**")
                .excludePathPatterns("//swagger-resources/**");
    }



}

MybatisPlusConfig.java 代码如下:

package com.demo.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan({"com.demo.dao"})
public class MybatisPlusConfig {

    /**
     * 性能优化  复杂查询可能会报错 建议关掉
     * @return
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        /*<!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 -->*/
        performanceInterceptor.setMaxTime(1000);
        /*<!--SQL是否格式化 默认false-->*/
        performanceInterceptor.setFormat(false);
        return performanceInterceptor;
    }

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

}

RedisConfig.java 代码如下 :

package com.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig extends CachingConfigurerSupport {

   public final static String reids_prefix="demo_admin_" ; //redis前缀

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        ObjectMapper mapper = new ObjectMapper();
        template.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }



}

SwaggerConfig.java 代码如下

package com.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@EnableSwagger2
@Configuration
public class SwaggerConfig {

    @Bean
    public Docket createRestApi(){
        ParameterBuilder ticketPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        ticketPar.name("token").description("登录校验token")//name表示对象名称,description表示描述
                .modelRef(new ModelRef("string")).parameterType("header")
                .required(false).build();//required表示是否必填,defaultvalue表示默认值
        pars.add(ticketPar.build());//添加完此处一定要把下边的带***的也加上否则不生效

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.demo.controller"))
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars);//************把消息头添加

    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("测试接口")
                .description("admin端接口")
                .termsOfServiceUrl("none")
                .version("1.0").build();
    }

}

3-4 shiro包结构class如下图:

在这里插入图片描述
ShiroAdmin.java 封装对象 代码如下:

package com.demo.shiro;


import io.swagger.annotations.ApiModelProperty;
import lombok.Data;


/**
 * 登陆对象
 */

@Data
public class ShiroAdmin {
    @ApiModelProperty(value = "管理员id")
    private Integer adminId;

    @ApiModelProperty(value = "token")
    private String token;

    @ApiModelProperty(value = "登陆id")
    private String loginCode;

    @ApiModelProperty(value = "权限id")
    private Integer roleId;

    @ApiModelProperty(value = "手机号")
    private String phone;

    @ApiModelProperty(value = "会话id")
    private String sessionId;
}

AuthManager.java 获取当前登陆的对象

package com.demo.shiro;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class AuthManager {


    public static ShiroAdmin getShiroAdmin() {

        return (ShiroAdmin)getSession().getAttribute("shiroAdmin");

    }

    public static String getSessionId(){
        return getSession().getId();
    }

     public static HttpSession getSession(){
         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
         return request.getSession();
     }

}

3-5 : 控制器 LoginController.java 代码如下s

package com.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.demo.common.ApiCommonController;
import com.demo.common.Result;
import com.demo.config.RedisConfig;
import com.demo.model.dto.LoginDto;
import com.demo.model.entity.TSysAdmin;
import com.demo.service.TSysAdminService;
import com.demo.shiro.AuthManager;
import com.demo.shiro.ShiroAdmin;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/login")
@Api(description = "登陆注册")
public class LoginController extends ApiCommonController {
    @Autowired
    private TSysAdminService tSysAdminService;
    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation(value = "登陆", response = String.class)
    @PostMapping("/loginDo")
    public Result loginDo(@RequestBody LoginDto dto){
        if (AuthManager.getSessionId()==null){
            return  ajaxDoneError("登陆异常,错误代码-10000");
        }
        TSysAdmin tSystemAdmin=tSysAdminService.getOne(new QueryWrapper<TSysAdmin>().eq("login_code",dto.getLoginCode()).eq("pwd",dto.getPwd()));
        if (tSystemAdmin==null){
            return  ajaxDoneError("账号或密码有误");
        }
        System.out.println("--------------------------------------");
        ShiroAdmin shiroAdmin=new ShiroAdmin();
        shiroAdmin.setAdminId(tSystemAdmin.getId());
        shiroAdmin.setLoginCode(tSystemAdmin.getLoginCode());
        shiroAdmin.setPhone(tSystemAdmin.getPhone());
        shiroAdmin.setRoleId(tSystemAdmin.getRoleId());
        shiroAdmin.setSessionId(AuthManager.getSessionId());
        shiroAdmin.setToken(RandomStringUtils.randomAlphanumeric(24)+tSystemAdmin.getId());
        String keyName=RedisConfig.reids_prefix+shiroAdmin.getSessionId();
        redisTemplate.opsForValue().set(keyName,shiroAdmin,2,TimeUnit.HOURS);
        return  ajaxDoneSuccess("登陆成功 good",shiroAdmin.getToken());

    }


}

3-6 : 入口类 AdminApplication.java

package com.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EnableTransactionManagement    //开启事务
@ComponentScan(basePackages = {"com.demo.*"})
public class AdminApplication {

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

}

4: 项目配置完成 项目完整接口入下图:

图1
图2

**

项目demo地址:https://download.csdn.net/download/qq_24232123/10802950

下载后 1:将CodeGeneration.java文件中的数据库连接改成实际的
2:将配置文件中的数据库,redis 改成实际的

猜你喜欢

转载自blog.csdn.net/qq_24232123/article/details/84388123
今日推荐