springboot_2(thymeleaf、异常、log4j、mybatis、redis)

thymeleaf模板引擎

简介
  • 作用:做同步开发使用,前端代码与后端代码在一个项目中。类似于jsp,用来获取后端java代码的数据(request,session,servletContext),在html中使用模板引擎技术来获取数据。
  • 同步:用户发起请求url(http://ip:port/后端接口url)–>进入我们控制层代码–>调用服务层代码–>得到数据–>把数据放在request对象–>返回html视图–>在视图中使用jsp或thymeleaf等类似的引擎技术来获取request对象中的数据–>动态生成纯静态的html代码(遍历或显示数据)–>生成的html代码返回客户端。
  • 异步:用户请求(请求页面html)–>页面加载函数中发起异步请求(ajax或axios)–>调用服务层代码–>得到数据–>把数据返回客户端–>异步请求回调函数中解析数据渲染视图.
  • jsp:编写.jsp–>当用户第一次请求XXX.jsp–>jsp引擎对XXX.jsp进行翻译,翻译成XXX.java–>虚拟机把XXX.java编译成XXX.class–>执行XXX.class中的service方法–>service方法中在生成静态html
  • thymeleaf:编译.html–>当用户第一次请求XXX.html–>thymeleaf引擎把.html加载到内存进行引擎语法解析–>基于内存把视图模板存储–>生成静态的html
  • 总结:解析动态数据,生成静态html.与jsp功能一样。
  • springBoot官方不支持jsp,推荐同步开发使用thymeleaf。
  • 相对于jsp来说,执行效率更加优秀。对于前端ui与程序员更加友好。
使用thymeleaf
  • 加thymeleaf启动器依赖
  • 开发时,都要把thymleaf基于内存存储模板禁用掉。
模板语法
  • 表达式:
  1. 属性表达式:${} 用来获取request,session,servletContext域中的数据。
    <span th:text="${request1}">测试数据测试数据</span>
    <hr>
    [[${request1}]]
    <hr>
    <span th:text="${session.session1}">测试数据测试数据</span>
    <hr>
    [[${session.session1}]]
    <hr>
    <span th:text="${#servletContext.getAttribute('context1')}">测试数据</span>
    <hr>
    [[${#servletContext.getAttribute('context1')}]]
    <hr>
    <input type="text" value="aaaa" th:value="${request1}">
  1. ​链接表达式:@{} 用来给链接生成当前项目的绝对路径。表达式内部/开头
<script src="/js/jquery-3.2.1.js" th:src="@{/js/jquery-3.2.1.js}"></script>
  1. 文档表达式:~{} 用来做页面的嵌套.写子页面的视图名
<div th:fragment="topFragment">
    公共的top页面
</div>

<div th:fragment="bottomFragment">
    公共的bottom页面
</div>
<div th:insert="~{common :: topFragment}"></div>
<div th:replace="~{common :: bottomFragment}"></div>
common是要引入模块的文件名。
  • 属性:

    • th:text="${}" 给双标签中间的内容赋值。
    • ​ th:value="${}" 给单标签的value赋值。
    • ​ th:insert="~{}" 用来做页面的嵌套.如果完整页面嵌套的话,th:isnert=“视图名”
    • ​ th:replace="~{}" 用来做页面的嵌套.
    • ​ th:fragment=“片断命名” 给局部div命名,通过文档表达式引入片断
    • ​ th:each="" 结合着属性表达式获取java代码的集合数据进行遍历输出。
    • ​ th:if=“条件表达式”
<table>
   <tr>
        <th>seq</th>
        <th>id</th>
        <th>name</th>
        <th>phone</th>
        <th>操作</th>
    </tr>
    <tr th:each="user,i:${ul}" th:if="${i.count%2!=0}">
        <td>[[${i.count}]]</td>
        <td>[[${user.uid}]]</td>
        <td th:text="${user.uname}"></td>
        <td>[[${user.uphone}]]</td>
        <td>
            <a th:href="@{/user/del(uid=${user.uid},uname=${user.uname})}">删除</a>
        </td>
    </tr>
</table>
链接传参
  • a标签的href传参
<a th:href="@{/user/del(uid=${user.uid},uname=${user.uname})}">删除</a>
  • ajax发起get请求,传参
var uid=12;
var url = "[[@{/user/del}]]?uid="+uid;

springboot异常处理

  • 针对于同步开发使用。不能达到返回的前端不同的错误信息(比如token过期,密码有误等等自定义的错误信息).

  • 使用浏览器测试请求:返回的是错误页面。

  • 使用postman测试:返回的是json数据。

  • 异常处理机制:

ErrorMvcAutoConfiguration配置类中有三个核心的异常处理的bean:
1.BasicErrorController:映射路径/error,出现异常tomcat会把请求转到/error的处理器中。
errorHtml:浏览器请求的处理器方法,查找错误视图,如果查找不到,则使用viewName为error的错误视图。
error:异步请求的处理器方法,直接返回json数据。
2.DefaultErrorAttributes:该对象中getErrorAttributes方法,生成了一个Map,该集合中包含了固定的错误信息。
3.StaticView默认错误视图,该视图的名字叫:error
4.在四个静态资源路径下定义error/错误码.html|error/4xx.html,5xx.html
5.怎么扩展错误信息,从DefaultErrorAttributes派生子类,注入容器,替换掉默认的bean对象。

  • 日常开发中,仍然使用全局统一异常处理:

    • @ControllerAdivce,@ExceptionHandler,自定义异常,状态枚举,响应体对象。

日志集成

  • 加入log4j2启动器
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
  • 加入log4j2.xml到resources目录
  • 排除掉可能重复导入的jar包。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-logging</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>

mybatis集成

  • 加入mybatis启动器,mysql连接包,pom文件resources配置。springboot默认使用HikariCP连接池。
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.13</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

<resources>
	<resource>
	    <directory>src/main/java</directory>
	    <includes>
	        <include>**/*.xml</include>
	    </includes>
	</resource>
	<resource>
	    <directory>src/main/resources</directory>
	    <includes>
	        <include>**/*</include>
	    </includes>
	</resource>
</resources>
  • application.java启动类配置mapper接口扫描注解,事务注解
@MapperScan("com.javasm.mapper")
@EnableTransactionManagement
  • application.yml 配置数据库连接信息,xml文件扫描,连接池信息,驼峰映射、别名等
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.14.241:3306/crm?characterEncoding=UTF8&useSSL=true&serverTimezone=Asia/Shanghai
    username: root
    password: root
    
mybatis:
  type-aliases-package: com.javasm
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath:com/javasm/mapper/*.xml

redis集成

  • 引入redis启动器
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
RedisTemplate
  • application.java启动类配置redis注解识别(使用注解玩redis生效),修改redis的默认序列化方式,默认是jdk(RedisTemplate内部采用的JDK默认的对象序列化机制,要求key和value存储的对象 必须implements Serializable,存进reids的数据无法辨识),改为jackson。
    • 修改后的配置对注解不生效,注解默认还是使用jdk的方式,且注解存的值只能通过注解取,手动get取为null
@SpringBootApplication
@MapperScan("com.javasm.mapper")
@EnableTransactionManagement
@EnableCaching // redis的注解识别
public class Application {

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

    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

}
  • application.yml 配置redis连接ip、端口、密码等
  redis:
    password: root
  • RedisTemplate的使用方法与原生reids稍有区别
@SpringBootTest
class ApplicationTests {

    @Resource
    private RedisTemplate<String, Object> rt;

    @Test
    public void testRedis(){
        ValueOperations<String, Object> value = rt.opsForValue();
        value.set("12",new ApplySimple(1,"啦啦啦",1001));
        HashOperations<String, Object, Object> opsForHash = rt.opsForHash();
        opsForHash.put("hashTest","123",new ApplySimple(12,"测试",123));
    }

    @Test
    // 手动取注解存进的值,取不出来,为null
    public void testRedisGet(){
        rt.setKeySerializer(new JdkSerializationRedisSerializer());
        rt.setValueSerializer(new JdkSerializationRedisSerializer());
        ValueOperations<String, Object> value = rt.opsForValue();
        Object o = value.get("apply::10");
        HashOperations<String, Object, Object> opsForHash = rt.opsForHash();

        Object hashTest = opsForHash.get("hashTest", "123");
        System.out.println(o);
        System.out.println(hashTest);
    }
}
StringRedisTemplate
  • StringRedisTemplate要求key和value必须都是String.需要手工把对象转json字符串,不常用
基于注解的使用
  • 在启动类上开启redis注解@EnableCaching
  • 重点有两个注解:
    • @Cacheable:注解到查询方法上,表示先查询缓存中指定key,找到直接返回,找不到则执行方法,把方法返回值放缓存。
    • @CacheEvict:注解到insert,delte,update方法上,当数据发生改变时,把缓存中对应的数据删掉。
//unless:对返回结果做判断,unless的条件为false时,加缓存,为true时不加
//condition:对查询条件做判断,条件为true时,查缓存,为false不查缓存
@Cacheable(cacheNames = "blogs",key = "#bid",unless = "#result==null",condition = "#bid>0")
@Override
public Blog selectById(Integer bid) {
    Blog blog = bm.selectByPrimaryKey(bid);
    return blog;
}

@CacheEvict(cacheNames = "blogs",key = "#b.bid")
@Override
public boolean updateBlogById(Blog b) {
    return bm.updateByPrimaryKeySelective(b)==1?true:false;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值