• 《springboot那些事》


    注:static目录、主要用于存放非模板引擎渲染的资源。

    ​ template目录,存放渲染引擎页面的资源。

    • 一句话:用模板引擎的话,就放template目录、否则static目录。

    一、使用thymeleaf

    • 引入thymealeaf坐标

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-thymeleafartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • yml配置
    spring:
      thymeleaf:
        prefix: classpath:/templates/
        suffix: .html
    
    • 1
    • 2
    • 3
    • 4
    • controller
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import java.util.Map;
    
    /**
     * @ClassName HelloWorldController
     * @Author Lucky-Six
     * @Date 2022/11/15 11:52
     * @Version 1.0.0
     */
    @Controller
    public class HelloWorldController {
    
        @RequestMapping("/")
        public String testThymeleaf(Map<String, Object> map) {
            map.put("msg", "testThymeleaf");
            return "index";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • index页面(template目录下)
    DOCTYPE html>
    
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    head>
    <body>
    
    <span th:text="${msg}">demospan>
    
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二、404、500页面

    • 默认识别:
    • /static/error/404.html
    • /static/error/500.html
    • /template/error/404.html
    • /template/error/500.html

    ​ 需要使用404/500页面时,仅需在static/template目录下,创建error文件夹、然后添加404-500页面即可。

    	当异常出现,会自动响应响应页面
    
    • 1

    在这里插入图片描述


    三、使用过滤器

    • ​ 继承filter
    import lombok.extern.slf4j.Slf4j;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;
    
    /**
     * @ClassName MyFilter
     * @Author Lucky-Six
     * @Date 2022/11/14 21:32
     * @Version 1.0.0
     */
    @Slf4j
    @WebFilter(urlPatterns = {"/*"})
    public class MyFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            Filter.super.init(filterConfig);
            log.info("init---Filter");
        }
    
        @Override
        public void destroy() {
            Filter.super.destroy();
            log.info("destroy---Filter");
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
            log.info("doFilter,拦截路径:{}", httpServletRequest.getServletPath());
            filterChain.doFilter(servletRequest, servletResponse);
        }
    
        
    }
    
    • 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
    • 启动类上,加上扫描注解、扫描过滤器所在包。
    @ServletComponentScan(basePackages = "shop.xiaochen.prorediscache.filter")
    
    • 1

    在这里插入图片描述

    四、拦截器使用

    ​ 注:拦截器,必须注册之后才生效、否则无效。拦截效果,在拦截器中自定义。

    • 自定义拦截器
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @ClassName CustomInterceptor
     * @Author Lucky-Six
     * @Date 2022/11/15 12:04
     * @Version 1.0.0
     */
    @Slf4j
    @Component
    public class CustomInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("preHandle");
            return HandlerInterceptor.super.preHandle(request, response, handler);
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            log.info("postHandle");
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            log.info("afterCompletion");
            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
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 拦截器注册
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * @ClassName MyInterceptor
     * @Author Lucky-Six
     * @Date 2022/11/15 12:07
     * @Version 1.0.0
     */
    @Component
    public class MyInterceptor implements WebMvcConfigurer {
    
        @Autowired
        private CustomInterceptor customInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            //  拦截所有请求
            registry.addInterceptor(customInterceptor).addPathPatterns("/*");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    五、异常处理机制

    • 自定义异常类
    /**
     * @ClassName CustomException
     * @Author Lucky-Six
     * @Date 2022/11/15 12:51
     * @Version 1.0.0
     */
    public class CustomException extends RuntimeException {
        /**
         * Constructs a new runtime exception with the specified detail message.
         * The cause is not initialized, and may subsequently be initialized by a
         * call to {@link #initCause}.
         *
         * @param message the detail message. The detail message is saved for
         *                later retrieval by the {@link #getMessage()} method.
         */
        public CustomException(String message) {
            super(message);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 全局异常捕获器
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.ResponseBody;
    import shop.xiaochen.prorediscache.utils.ApiResult;
    
    /**
     * @ClassName CustomException
     * @Author Lucky-Six
     * @Date 2022/11/14 21:27
     * @Version 1.0.0
     */
    @ControllerAdvice
    @ResponseBody
    public class GlobalException {
        // 算数异常
        @ExceptionHandler({ArithmeticException.class})
        public ApiResult<String> handlerAdvice(ArithmeticException e) {
            return new ApiResult(500, "fail", e.getMessage());
        }
    
        // 自定义异常类
        @ExceptionHandler({CustomException.class})
        public ApiResult handlerAdviceCustom() {
            return new ApiResult(500, "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
    • 使用方法

    在这里插入图片描述

    六、定时器使用

    /**
     * @ClassName RedisScheduling
     * @Author Lucky-Six
     * @Date 2022/11/14 20:44
     * @Version 1.0.0
     */
    @Slf4j
    @Component
    @EnableScheduling
    public class Scheduling {
    
        // 20s执行一次
        @Scheduled(fixedRate = 20000)
        public void test() {
            // 执行内容写这里
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    七、MP分页拦截器配置类

    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyMPConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(
                    new PaginationInnerInterceptor(DbType.MARIADB));
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    八、Redis序列化器配置类

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    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 RedisConfiguration {
    
        @Bean
        @SuppressWarnings("all")
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
            template.setConnectionFactory(factory);
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
            template.setKeySerializer(stringRedisSerializer);
            template.setHashKeySerializer(stringRedisSerializer);
            template.setValueSerializer(jackson2JsonRedisSerializer);
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
            template.afterPropertiesSet();
            return template;
        }
    }
    
    • 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

    九、各种简称

    第 1 个:DAO

    DAO(Data Access Object)数据访问对象,它是一个面向对象的数据库接口,负责持久层的操作,为业务层提供接口,主要用来封装对数据库的访问,常见操作无外乎 CURD。我们也可以认为一个 DAO 对应一个 POJO 的对象,它位于业务逻辑与数据库资源中间,可以结合 PO 对数据库进行相关的操作。

    第 2 个:PO

    PO(Persistent Object)持久层对象,它是由一组属性和属性的get和set方法组成,最简单的 PO 就是对应数据库中某个表中的一条记录(也就是说,我们可以将数据库表中的一条记录理解为一个持久层对象),多个记录可以用 PO 的集合,PO 中应该不包含任何对数据库的操作。PO 的属性是跟数据库表的字段一一对应的,此外 PO 对象需要实现序列化接口。

    第 3 个:BO

    BO(Business Object)业务层对象,是简单的真实世界的软件抽象,通常位于中间层。BO 的主要作用是把业务逻辑封装为一个对象,这个对象可以包括一个或多个其它的对象。举一个求职简历的例子,每份简历都包括教育经历、项目经历等,我们可以让教育经历和项目经历分别对应一个 PO,这样在我们建立对应求职简历的 BO 对象处理简历的时候,让每个 BO 都包含这些 PO 即可。

    第 4 个:VO

    VO(Value Object)值对象,通常用于业务层之间的数据传递,和 PO 一样也是仅仅包含数据而已,但 VO 应该是抽象出的业务对象,可以和表对应,也可以不对应,这根据业务的需要。 如果锅碗瓢盆分别为对应的业务对象的话,那么整个碗柜就是一个值对象。此外,VO 也可以称为页面对象,如果称为页面对象的话,那么它所代表的将是整个页面展示层的对象,也可以由需要的业务对象进行组装而来。

    第 5 个:DTO

    DTO(Data Transfer Object)数据传输对象,主要用于远程调用等需要大量传输对象的地方,比如我们有一个交易订单表,含有 25 个字段,那么其对应的 PO 就有 25 个属性,但我们的页面上只需要显示 5 个字段,因此没有必要把整个 PO 对象传递给客户端,这时我们只需把仅有 5 个属性的 DTO 把结果传递给客户端即可,而且如果用这个对象来对应界面的显示对象,那此时它的身份就转为 VO。使用 DTO 的好处有两个,一是能避免传递过多的无用数据,提高数据的传输速度;二是能隐藏后端的表结构。常见的用法是:将请求的数据或属性组装成一个 RequestDTO,再将响应的数据或属性组装成一个 ResponseDTO.

    第 6 个:POJO

    POJO(Plain Ordinary Java Object)简单的 Java 对象,实际就是普通的 JavaBeans,是为了避免和 EJB(Enterprise JavaBean)混淆所创造的简称。POJO 实质上可以理解为简单的实体类,其中有一些属性及其getter和setter方法的类,没有业务逻辑,也不允许有业务方法,也不能携带有connection之类的方法。POJO 是 JavaEE 世界里面最灵活的对象,在简单系统中,如果从数据库到页面展示都是 POJO 的话,它可以是 DTO;如果从数据库中到业务处理中都是 POJO 的话,它可以是 BO;如果从数据库到整个页面的展示的话,它也可以是 VO.


  • 相关阅读:
    ssm基于微信小程序的学习资料销售平台+ssm+uinapp+Mysql+计算机毕业设计
    笔试强训错题总结(一)
    设计模式深度解析:适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼
    [架构之路-246]:目标系统 - 设计方法 - 软件工程 - 需求工程- 需求开发:获取、分析、定义、验证
    【JavaEE】锁策略、CAS和synchronized的优化
    《动手学深度学习 Pytorch版》 7.4 含并行连接的网络(GoogLeNet)
    406. 根据身高重建队列
    纯Python实现遗传算法
    MinIO 图片转文件的分界线RELEASE.2022-05-26T05-48-41Z
    JDBC-day07(Apache-DBUtils实现CRUD操作)
  • 原文地址:https://blog.csdn.net/weixin_52236586/article/details/127863934