跳转至

起步配置

  • Maven仓库

Maven Repository: Search/Browse/Explore

  • 阿里云

阿里云登录页

Spring配置yaml

application.yaml

#mysql
spring:
  datasource:
       url: jdbc:mysql://localhost:3306/tlias_db  # 数据库连接地址
       username: root # 数据库用户名
       password: 1234 # 数据库密码
       driver-class-name: com.mysql.cj.jdbc.Driver # 数据库驱动
#mybatis
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   # 打印sql语句到控制台
    map-underscore-to-camel-case: true #开启驼峰
  mapper-locations: classpath:mapper/*.xml  # 指定mapper的xml映射文件的位置
  type-aliases-package: com.itheima.tliasmanage.pojo  # 指定实体类包名
#端口被占用时使用
#server:
#  port: 9999

MyBatis xml

[实体类名称]Mapper.xml

1
2
3
4
5
6
7
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">

</mapper>

log配置

logback.xml

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

<!--
    配置1:日志的输出位置
          <appender  class="控制台/文件/数据库/MQ/... ...">
    配置2:日志的输出形式
          <pattern>时间/级别/类名称/线程名称/信息/... ...</pattern>
    配置3:日志的开关
          <root level="开启/关闭/日志级别">
-->
<configuration>
    <!--CONSOLE :表示当前的日志信息是可以输出到控制台的。-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--输出流对象 默认 System.out 改为 System.err-->
        <target>System.out</target>
        <encoder>
            <!--格式化输出:
                %d表示日期,
                %thread表示线程名,
                %-5level:级别从左显示5个字符宽度
                %msg:日志消息,
                %n是换行符
                -->
            <pattern>雪之下雪乃=:%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level]  %c [%thread] : %msg%n</pattern>
        </encoder>
    </appender>

    <!-- File是输出的方向通向文件的 -->
<!--    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!--        <encoder>-->
<!--            <pattern>东阳妹妹&#45;&#45;&#45;&#45;&#45;&#45;&#45;&#45;:%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>-->
<!--            <charset>utf-8</charset>-->
<!--        </encoder>-->
<!--        &lt;!&ndash;日志输出路径&ndash;&gt;-->
<!--        <file>E:/tlias_log/itheima-data.log</file>-->
<!--        &lt;!&ndash;指定日志文件拆分和压缩规则&ndash;&gt;-->
<!--        <rollingPolicy-->
<!--                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
<!--            &lt;!&ndash;通过指定压缩文件名称,来确定分割文件方式&ndash;&gt;-->
<!--            <fileNamePattern>D:/log/itheima-data-%i-%d{yyyy-MM-dd}-.log.gz</fileNamePattern>-->
<!--            &lt;!&ndash;文件拆分大小&ndash;&gt;-->
<!--            <maxFileSize>1MB</maxFileSize>-->
<!--        </rollingPolicy>-->
<!--    </appender>-->

    <!--
        1、控制日志的输出情况:如,开启日志,取消日志
    -->
    <root level="info">
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>

阿里云依赖

pom.xml

<!--阿里云oss-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.17.4</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- no more than 2.3.3-->
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>

阿里云参数配置化

applications.yaml

1
2
3
4
5
aliyun:
  oss:
    endpoint: oss-cn-beijing.aliyuncs.com
    bucketName: hua-bei-huabei
    region: cn-beijing

使用参数

  1. @Value注解
1
2
3
4
5
6
7
8
@Value("${aliyun.oss.endpoint}")
private String endpoint;

@Value("${aliyun.oss.bucketName}")
private String bucketName;

@Value("${aliyun.oss.region}")
private String region;
  1. 创建实体类
1
2
3
4
5
6
7
8
@Data
@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {
    private String endpoint;
    private String bucketName;
    private String region;
}

使用实体类的参数

1
2
3
4
5
6
String endpoint;
String bucketName;
String region;
endpoint = aliOSSProperties.getEndpoint();
bucketName = aliOSSProperties.getBucketName();
region = aliOSSProperties.getRegion();

JWT令牌

1
2
3
4
5
6
<!--jjwt令牌生成和解析-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

令牌工具类

public class JwtUtils {

    private static String signKey = "SVRIRUlNQQ==";
    private static Long expire = 43200000L;

    /**
     * 生成JWT令牌
     * @return
     */
    public static String generateJwt(Map<String,Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }

    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分负载 payload 中存储的内容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }
}

过滤器

在启动类添加@ServletComponentScan

@ServletComponentScan 是Spring Boot注解,用于自动扫描和注册Servlet、Filter、Listener等Web组件。它会扫描指定包路径下的Web组件,并将其自动注册到Servlet容器中,简化了传统web.xml配置方式。

在过滤器类添加@WebFilter("/*")注解,拦截所有地址,重写doFilter方法

@Slf4j
@WebFilter("/*")
public class LoginFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //获取请求路径
        String url = request.getRequestURL().toString();
        log.info("filter过滤请求路径{}",url);
        if(url.contains("/login")){
            log.info("filter过滤登录请求,直接放行");
            filterChain.doFilter(request,response);
            return;
        }
        String token = request.getHeader("token");

        if(token==null){
            log.info("filter过滤请求,没有令牌,直接封装未授权的响应信息");
            response.setStatus(401);
            return;
        }
        try {
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            log.info("filter过滤请求,令牌无效,直接封装未授权的响应结果");
            response.setStatus(401);
            return;
        }
        log.info("filter过滤请求,令牌有效,直接放行");
        filterChain.doFilter(request,response);

    }

}

拦截器

WebConfig.class 配置文件

/**
 * springmvc配置类:
 *     配置拦截器、异常处理、视图解析器、消息转换器
 */
@Configuration
public class WebConfig  implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;
    //注册拦截器到springmvc框架中
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //使用方法提供的拦截器注册器进行注册
        registry.addInterceptor(loginInterceptor)
                //配置拦截器:拦截的路径
                .addPathPatterns("/**")//拦截所有请求
                .excludePathPatterns("/login");
    }
}

登录拦截流程

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("token");

        if(token==null){
            log.info("LoginInterceptor拦截请求,没有令牌,直接封装未授权的响应信息");
            response.setStatus(401);
            return false;
        }
        try {
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            log.info("LoginInterceptor拦截请求,令牌无效,直接封装未授权的响应结果");
            response.setStatus(401);
            return false;
        }
        log.info("LoginInterceptor拦截请求,令牌有效,直接放行");
        return true;

    }
}

image

image

image