• SpringBoot


    项目搭建方式1

    springboot内置了tomcat

     <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
      </parent>
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <version>2.4.5</version>
        </dependency>
      </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    项目搭建方式2

     <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.4.5</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
    
      </dependencyManagement>
    
    
      <dependencies>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
          <version>2.4.5</version>
        </dependency>
      </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    SpringBoot文件配置

    application.properties

    server.servlet.context-path=/springboot03
    server.port=8090
    
    
    • 1
    • 2
    • 3

    application.yml

    server:
      port: 8080
      servlet:
        context-path: /springboot03
    
    • 1
    • 2
    • 3
    • 4

    上下两行隔开两个空格是一个层级。

    两者都配置的话.properties的优先级更高。

    SpringBoot整合Mybatis

    导入依赖:

     <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
    <!--        mybatis的启动器-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.4</version>
            </dependency>
    <!--        mysql驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.21</version>
            </dependency>
    <!--        lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    application.yml:

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
        username: root
        password: 
        driver-class-name: com.mysql.cj.jdbc.Driver
    server:
      servlet:
        context-path: /springboot03
    
    mybatis:
      type-aliases-package: com.msb.pojo
      mapper-locations: classpath:mybatis/*.xml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    其他的地方就和springmvc的一样了。

    SpringBoot整合logback

    logback作用: 打印日志
    在resourse目录下增加logback.xml文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
        <property name="LOG_HOME" value="${catalina.base}/logs/"/>
        <!-- 控制台输出 -->
        <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
            <!-- 日志输出格式 -->
            <layout class="ch.qos.logback.classic.PatternLayout">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
                </pattern>
            </layout>
        </appender>
        <!-- 按照每天生成日志文件 -->
        <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--日志文件输出的文件名-->
                <FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <layout class="ch.qos.logback.classic.PatternLayout">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
                </pattern>
            </layout>
            <!--日志文件最大的大小-->
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>10MB</MaxFileSize>
            </triggeringPolicy>
        </appender>
    
        <!-- 日志输出级别 -->
        <root level="info">
            <appender-ref ref="Stdout"/>
            <appender-ref ref="RollingFile"/>
        </root>
    
        <logger name="com.msb.mapper" level="DEBUG"></logger>
    
    
    <!--    &lt;!&ndash;日志异步到数据库 又开启一个线程来打印日志&ndash;&gt;-->
    <!--    <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
    <!--&lt;!&ndash;        日志异步到数据库&ndash;&gt;-->
    <!--        <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
    <!--&lt;!&ndash;            连接池&ndash;&gt;-->
    <!--            <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
    <!--                <driverClass>com.mysql.cj.jdbc.Driver</driverClass>-->
    <!--                <url>jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true-->
    <!--                <user>root</user>-->
    <!--                <password>cl091900</password>-->
    <!--            </dataSource>-->
    <!--        </connectionSource>-->
    <!--    </appender>-->
    
    </configuration>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    SpringBoot整合pageHelper

    导入依赖:

    <!--        pageHelper的启动器-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.3.0</version>
            </dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Controller层:

     @RequestMapping("findByPage/{pageNum}/{pageSize}")
        @ResponseBody
        public List<Emp> findByPage(@PathVariable("pageNum") Integer pageNum,@PathVariable("pageSize") Integer pageSize ){
            return empService.findByPage(pageNum,pageSize);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Service层:

      @Override
        public List<Emp> findByPage(Integer pageNum, Integer pageSize) {
            Page<Object> objects = PageHelper.startPage(pageNum, pageSize);
            List<Emp> list=empMapper.findAll();
            System.out.println(objects.toString());
            // 页码  页大小  当前页数据  总页数  总记录数
            //这些对象都在startPage的返回值里
            //数据封装方式2pageInfo ->pageBean
            PageInfo<Emp> pi=new PageInfo<>(list);
    
            return list;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    SpringBoot整合Druid

    很方便的帮助我们实现对sql执行的监控
    导入依赖:

      <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    application.yml配置文件:

    spring:
      datasource:
        #使用阿里的Druid连接池
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        # 填写你数据库的url、登录名、密码和数据库名
        url: jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
        username: root
        password: 
      druid:
        #连接池配置信息
        #初始化大小,最小,最大
        initial-size: 5
        min-idle: 5
        maxActive: 20
        #配置获取连接等待超时的时间
        maxWait: 60000
        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        timeBetweenEvictionRunsMillis: 60000
        # 配置一个连接在池中最小生存的时间,单位是毫秒
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        # 打开PSCache,并且指定每个连接上PSCache的大小
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20
        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
        filters: stat,wall,slf4j
        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
        connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
        # 配置DruidStatFilter
        web-stat-filter:
          enabled: true
          url-pattern: "/*"
          exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
        # 配置DruidStatViewServlet
        stat-view-servlet:
          url-pattern: "/druid/*"
          # IP白名单(没有配置或者为空,则允许所有访问)
          allow: 127.0.0.1,192.168.8.109
          # IP黑名单 (存在共同时,deny优先于allow)
          deny: 192.168.1.188
          #  禁用HTML页面上的“Reset All”功能
          reset-enable: false
          # 登录名
          login-username: admin
          # 登录密码
          login-password: 123456
      main:
        allow-circular-references: true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    SpringBoot整合FreeMarker

    导入依赖:

    <!--        freeMaker启动器-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Controller:

    @Controller
    public class FreemarkerController {
        @RequestMapping("/show")
        public String freemarger(Map<String,Object> map){
            map.put("name","漩涡刘能");
    
            return "show";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    show.ftlh:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <br/>
    ${name}
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    FreeMarker常用指令(遍历List集合)

    这里使用.ftlh渲染出来的界面,属性如果为空值,则显示不出来。
    需要在ftlh中引入这个指令。

            <#setting classic_compatible=true>
    
    • 1

    Controller:

     //查询全部员工信息,展示
        @RequestMapping("/showEmp")
        public ModelAndView testList(){
            ModelAndView mv=new ModelAndView();
            List<Emp> list=empService.findAll();
            System.out.println(list.toString());
            mv.addObject("empList",list);
            mv.setViewName("showEmp");
            return mv;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    showEmp.ftlh:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
            #empTable {
                width: 80%;
                border: 1px solid blue;
                margin: 0px auto;
            }
    
            #empTable th, td {
                border: 1px solid green;
                text-align: center;
            }
    
        </style>
    
    </head>
    <body>
    <table id="empTable" cellpadding="0px" cellspacing="0px">
        <tr>
            <th>索引</th>
            <th>工号</th>
            <th>姓名</th>
            <th>岗位</th>
            <th>薪资</th>
            <th>部门号</th>
        </tr>
        <#list empList as emp>
            <#setting classic_compatible=true>
        <tr>
    <#--        //通过_index可以得到循环的下标-->
            <td>${emp_index}</td>
            <td></td>
            <td>${emp.ename}</td>
            <td>${emp.job}</td>
            <td>${emp.sal}</td>
            <td>${emp.deptno}</td>
        </tr>
        </#list>
    </table>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    FreeMarker遍历Map集合

    Controller:

    //查询全部员工信息,展示
        @RequestMapping("/showEmpMap")
        public ModelAndView testMap(){
            ModelAndView mv=new ModelAndView();
            List<Emp> list=empService.findAll();
            Map<String,Emp> empMap=new HashMap<>();
            for (Emp emp : list) {
                empMap.put(emp.getEmpno().toString(),emp);
            }
            mv.addObject("empMap",empMap);
            mv.setViewName("showEmpMap");
            return mv;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    showEmpMap.ftlh:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
            #empTable {
                width: 80%;
                border: 1px solid blue;
                margin: 0px auto;
            }
    
            #empTable th, td {
                border: 1px solid green;
                text-align: center;
            }
    
        </style>
    
    </head>
    <body>
    <#setting classic_compatible=true>
    <#--查看Map集合中单独一个元素-->
    <table id="empTable" cellpadding="0px" cellspacing="0px">
        <tr>
            <th>索引</th>
            <th>工号</th>
            <th>姓名</th>
            <th>岗位</th>
            <th>薪资</th>
            <th>部门号</th>
        </tr>
        <#list empMap?keys as k>
            <tr>
                <td>${k_index}</td>
                <td>${k}</td>
                <td>${empMap[k].ename}</td>
                <td>${empMap[k].job}</td>
                <td>${empMap[k].sal}</td>
                <td>${empMap[k].deptno}</td>
            </tr>
        </#list>
    
    
    </table>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    FreeMarker在遍历map集合是,key必须是String

    FreeMaker内置函数:

    内建函数语法格式: 变量+?+函数名称 
    
    • 1
    显示年月日:         ${today?date} 
    显示时分秒:      ${today?time} 
    显示日期+时间:${today?datetime} 
    自定义格式化:   ${today?string("yyyy年MM月")} 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    SpringBoot整合Thymeleaf

    导入依赖:

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.3</version>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.21</version>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
    
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
    
    
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.12</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
                <version>2.4.5</version>
            </dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    showEmp.html:

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" >
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
            #empTable {
                width: 80%;
                border: 1px solid blue;
                margin: 0px auto;
            }
    
            #empTable th, td {
                border: 1px solid green;
                text-align: center;
            }
        </style>
    </head>
    <body>
    展示单个员工信息
    工号:<span th:text="${emp.empno}"></span><br>
    姓名:<span th:text="${emp.ename}"></span><br>
    职务:<span th:text="${emp.job}"></span><br>
    上级:<span th:text="${emp.mgr}"></span><br>
    入职日期:<span th:text="${emp.hiredate}"></span><br>
    
    <hr/>
    
    <table id="empTable" cellpadding="0px" cellspacing="0px" >
        <tr>
            <th>工号</th>
            <th>姓名</th>
            <th>职务</th>
            <th>上级</th>
            <th>入职日期</th>
            <th>工资</th>
            <th>补助</th>
            <th>部门</th>
            <th>操作</th>
        </tr>
        <tr th:each="emp:${empList}">
            <td th:text="${emp.empno}"></td>
            <td th:text="${emp.ename}"></td>
            <td th:text="${emp.job}"></td>
            <td th:text="${emp.mgr}"></td>
            <td th:text="${emp.hiredate}"></td>
            <td th:text="${emp.sal}"></td>
            <td th:text="${emp.comm}"></td>
            <td th:text="${emp.deptno}"></td>
            <td>
    
                <a th:href="@{removeEmp(empno=${emp.empno},ename=${emp.ename})}" >删除</a>
                <a href="javascript:void(0)" th:onclick="removeEmp([[${emp.empno}]],[[${emp.ename}]])">删除</a>
                <a href="javascript:void(0)" th:onclick="removeEmp([[${emp.empno}]],[[${emp.ename}]])">删除</a>
            </td>
        </tr>
    </table>
    <script>
        function removeEmp(empno,ename){
           var resulet= confirm("确定要删除编号为“+empno+”的"+ename);
            if(resulet){
    
                window.location.href="removeEmp?empno="+empno+"&ename="+ename;
            }
        }
    </script>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    Thymeleaf内置对象

    Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。
    使用内置对象的语法
    1引用内置对象需要使用#
    2大部分内置对象的名称都以s结尾。如:strings、numbers、dates
    3常见内置对象如下

    #arrays:数组操作的工具;
    #aggregates:操作数组或集合的工具;
    #bools:判断boolean类型的工具;
    #calendars:类似于#dates,但是是java.util.Calendar类的方法;
    #ctx:上下文对象,可以从中获取所有的thymeleaf内置对象;
    #dates:日期格式化内置对象,具体方法可以参照java.util.Date;
    #numbers: 数字格式化;#strings:字符串格式化,具体方法可以参照String,如startsWith、contains等;
    #objects:参照java.lang.Object;
    #lists:列表操作的工具,参照java.util.List;
    #sets:Set操作工具,参照java.util.Set;#maps:Map操作工具,参照java.util.Map;
    #messages:操作消息的工具。

    <span th:text="${#httpServletRequest.getAttribute('msg')}"></span><br/>
    <span th:text="${#request.getAttribute('msg')}"></span><br/>
    <span th:text="${msg}"></span><br/>
    
    session:<br/>
    <span th:text="${#httpSession.getAttribute('msg')}"></span><br/>
    <span th:text="${#session.getAttribute('msg')}"></span><br/>
    <span th:text="${session.msg}"></span><br/>
    
    application:<br/>
    <span th:text="${#servletContext.getAttribute('msg')}"></span><br/>
    <span th:text="${application.msg}"></span><br/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    SpringBoot热部署

    热部署之后则不需要重启项目,当监听到内容改变后tomcat则自动的进行重启。
    步骤:

    添加依赖:

    <!--        开发者工具-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <version>2.4.5</version>
                <optional>true</optional>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    修改idea自动编译配置:
    在这里插入图片描述

    idea2022版本:
    在这里插入图片描述
    这里要打勾。

    注意在2022以前的版本需要修改Reigstry
    Ctrl+Shift+Alt+/ 点击弹出框中Registry…
    在这里插入图片描述
    在这里插入图片描述

    SpringBoot打包部署

    将项目打成jar包

    导入依赖:

    <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <fork>true</fork>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用maven package代码打包就可以

    在这里插入图片描述

    项目打成war包

    排除项目中自带的所有的Tomcat插件和jsp servlet 依赖,因为这里要将项目放到一个Tomcat上运行

    	<!--配置SpringBoot的web启动器-->
    	<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    	    <!--排除web启动中自动依赖的tomcat插件-->
    	    <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
    	            <artifactId>spring-boot-starter-tomcat</artifactId>
    	        </exclusion>
    	    </exclusions>
    </dependency>
    	<!--
        手动依赖tomcat插件,但是表明项目打包时该依赖不会被打进去,目的主要是保证开发阶段本地SpringBoot
    	    项目可以正常运行
    	-->
    	<dependency>
    	    <groupId>org.springframework.boot</groupId>
    	    <artifactId>spring-boot-starter-tomcat</artifactId>
        <!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
            相当于compile,但是打包阶段做了exclude操作-->
       <scope>provided</scope>
    	</dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    SpringBoot的启动类继承SpringBootServletInitializer,并重写configure

    @SpringBootApplication
    public class Springboot04Application extends SpringBootServletInitializer {
        //重写配置方法
    
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(Springboot04Application.class);
        }
    
        public static void main(String[] args) {
            SpringApplication.run(Springboot04Application.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用install命令打包项目,并将war包放到tomcat下的webapps下,启动tomcat即可。

    SpringBoot拦截器配置

    自定义拦截器类:

    @Component
    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return HandlerInterceptor.super.preHandle(request, response, handler);
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    拦截器配置:

    @Configuration
    public class MyInterceptorConfig implements WebMvcConfigurer {
        @Autowired
        MyInterceptor myInterceptor;
        //设置拦截器路径
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            InterceptorRegistration interceptorRegistration = registry.addInterceptor(myInterceptor);
            interceptorRegistration.addPathPatterns("/**").excludePathPatterns("/login");
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    SpringBoot其他注解

    @Configuration

    用来编写配置类,里面有一些bean实例,spring容器从配置类中来获取这些实例。
    配置类:

    @Configuration
    public class MyConfig {
        @Bean // 向容器中添加一个Bean,以方法名作为Bean的id,返回值类型作为组件的类型
        public User user1(){
            return new User("张三","123");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    启动类:

    @SpringBootApplication
    public class Springboot04Application {
       
    
        public static void main(String[] args) {
    
            ConfigurableApplicationContext Context = SpringApplication.run(Springboot04Application.class, args);
            User user1=Context.getBean("user1",User.class);
            System.out.println(user1);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    @Import

    @Import(User.class)
    @Configuration
    public class MyConfig {
        @Bean // 向容器中添加一个Bean,以方法名作为Bean的id,返回值类型作为组件的类型
        public User user1(){
            return new User("张三","123");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    根据类型来获取bean实例,默认使用无参构造方法来创建实例对象。

    @ImportResource

    原生配置文件引入,允许我们自己定义xml配置文件,在文件中配置bean

    @ImportResource("classpath:beans.xml")
    @Configuration
    public class MyConfig {
        @Bean // 向容器中添加一个Bean,以方法名作为Bean的id,返回值类型作为组件的类型
        public User user1(){
            return new User("张三","123");
        }
    
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    @ConfigurationProperties

    读取application.properties配置文件中的内容,读取进入bean

    JUnit5

    JUnit5常见注解

    class Springboot04ApplicationTests {
        @DisplayName("测试方法1:")//是对类的描述
        @Test  //方法可以独立的运行,不需要再测试了
        public void test1(){
    
        }
        @BeforeAll
        public void beforeAll(){
            System.out.println("在所有的测试方法执行之前先执行一次");
        }
        @BeforeEach
        public void beforeEach(){
            System.out.println("在每一个测试方法之前执行该方法");
        }
    
        @AfterEach
        public void afterEach(){
           System.out.println("在每一个测试方法之后执行该方法");
        }
        @AfterAll
        public void afterAll(){
            System.out.println("在所有方法执行之后执行该方法");
        }
        @RepeatedTest(3)
        public void repeatTest(){
            System.out.println("重复测试3次");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    JUnit5断言

    @DisplayName("JUnit5断言")
    @SpringBootTest(classes = Springboot04ApplicationTests2.class)//在测试的时候可以导入spring中的一些组件
    class Springboot04ApplicationTests2 {
    
        @DisplayName("简单断言1")
        @Test
      public void testAssertions1(){
          int x=add(1,2);
          Assertions.assertEquals(2,x,"add运算结果错误");
    
      }
    
      public int add(int a,int b){
            return a+b;
      }
      @DisplayName("组合断言")
      @Test
      public void testAssertAll(){
            Assertions.assertAll("AssertAll",
                    ()->Assertions.assertTrue(1>0),
                    ()->Assertions.assertTrue(2>3));
      }
    
        @DisplayName("异常断言")
        @Test//断言它会出现指定的异常,如果没出现,则表示测试失败
        public void testAssertExcepion(){
           Assertions.assertThrows(ArithmeticException.class,()->{int i=1/0;},"竟然没有出现异常");
        }
    
        @DisplayName("超时异常")
        @Test
        public void testAssertTimeOut(){
            Assertions.assertTimeout(Duration.ofMillis(1000),()->Thread.sleep(900));
        }
        
        @DisplayName("快速失败")
        @Test //如果测试时出现了某些情况,直接生成测试失败的报告,后续也不再测试了
        public void testFail(){
            Assertions.fail("测试失败");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    JUnit5前置条件

    @DisplayName("JUnit5前置条件")
    @SpringBootTest(classes = Springboot04ApplicationTests3.class)//在测试的时候可以导入spring中的一些组件
    class Springboot04ApplicationTests3 {
        @DisplayName("测试前置条件")
        @Test
      public void testAssumptions(){
          //假设的条件为true的时候才会执行测试,否则取消测试
          Assumptions.assumeTrue(true);
          System.out.println("测试了");
      }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    JUnit5嵌套测试

    @DisplayName("JUnit5嵌套测试")
    @SpringBootTest(classes = Springboot04ApplicationTests4.class)//在测试的时候可以导入spring中的一些组件
    class Springboot04ApplicationTests4 {
       @BeforeEach
        public void outerBeforEach(){
           System.out.println("outerBeforeEach");
        }
    
       @Test
        public void outerTest1(){
           System.out.println("outerTest");
       }
       @Nested
       @DisplayName("内部嵌套测试")
       class InnerClass{
           @BeforeEach
           public void outerBeforEach(){
               System.out.println("innerBeforeEach");
           }
    
           @Test
           public void outerTest1(){
               System.out.println("innerTest");
           }
       }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    JUnit5参数化测试

    @DisplayName("JUnit5嵌套测试")
    @SpringBootTest(classes = Springboot04ApplicationTests5.class)//在测试的时候可以导入spring中的一些组件
    class Springboot04ApplicationTests5 {
    
    
        @ParameterizedTest
        @ValueSource(ints={1,2,3,4,5,6})
      public void testParam1(int a){
          Assertions.assertTrue(a>0&&a<4);
    
      }
    
        @ParameterizedTest
        @MethodSource("stringProvider")
        public void testParam2(String str){
            Assertions.assertNotNull(str,"str为null了,测试失败");
    
        }
    
        public static Stream<String> stringProvider(){
            List<String>  strs=new ArrayList<>();
            strs.add("a");
            strs.add("b");
            strs.add("c");
            strs.add(null);
            Stream<String> stream = strs.stream();
            return stream;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    Promise, async, await 学习
    电脑开机速度慢怎么解决?
    2.算法-Python模拟退火算法实例
    df -h 显示/根目录占100%
    【IDEA 使用easyAPI、easyYapi、Apifox helper等插件时,导出接口文档缺少代码字段注释的相关内容、校验规则的解决方法】
    公司知识共享计划
    全新升级的AOP框架Dora.Interception[6]: 框架设计和实现原理
    C++ 之 constexpr详解
    友善Nona Pi开发板ubuntu22.04系统用Python3.8.17的pip安装PyQt5.15.2时报错“Q_PID”这个宏未定义的一种解决办法
    maven离线模式及设置
  • 原文地址:https://blog.csdn.net/qq_44867340/article/details/127578139