springboot 日志/aop/拦截器(第三章)

springboot 第三章

springboot 日志处理

介绍

​ springboot框架 集成日志 logback 日志

​ Logback是由log4j创始人设计的又一个开源日志组件。目前,logback分为三个模块:logback-core,logback-classic和logback-access。是对log4j日志展示进一步改进!

​ 总结: logback 也是一个开源日志组件 和 log4j作用一致 都是用来生成日志 logback更加轻量

日志级别

在这里插入图片描述

> All < Trace < `DEBUG < INFO < WARN < ERROR` < Fatal < OFF

- OFF   | 关闭:最高级别,不打印日志。 
- FATAL | 致命:指明非常严重的可能会导致应用终止执行错误事件。
- ERROR | 错误:指明错误事件,但应用可能还能继续运行。 
- WARN | 警告:指明可能潜在的危险状况。 
- INFO | 信息:指明描述信息,从粗粒度上描述了应用运行过程。 
- DEBUG | 调试:指明细致的事件信息,对调试应用最有用。
- TRACE | 跟踪:指明程序运行轨迹,比DEBUG级别的粒度更细。 
- ALL | 所有:所有日志级别,包括定制级别。

> 日志级别由低到高:  `日志级别越高输出的日志信息越多`

项目中日志分类

# 日志分类:
- 一种是rootLogger(根全局日志) :     用来监听项目中所有的运行日志 包括引入依赖jar中的日志 

- 一种是logger(指定包级别日志) :     用来监听项目中指定包中的日志信息,自定义某个包下面日志打印的级别

自定义配置日志


logging:
  file:
    name: springbootday3.log    ## 日志名称
    path: ./logs       ## 指定日志输出的文件目录 
  level:
    com.fashion: debug # 子日志,自定义包下日志输出级别
    root: info  #指定根日志级别(一般不推荐修改根日志,输出信息太多,推荐使用子日志)

项目中使用

@RequestMapping("hello")
    public String hello() {
        System.out.println(" ===============  hello ok ");
        logger.trace("TRACE:{}","信息");
        logger.debug("DEBUG:{}","信息");
        logger.info("INFO:{}","信息");
        logger.warn("WARN:{}","信息");
        logger.error("ERROR:{}","信息");
        return "hello ok";
    }

当我们在配置文件配置相应的级别后,对应的日志就可以输出来了


切面编程 aop

springboot是对原有项目中spring框架和springmvc的进一步封装,因此在springboot中同样支持spring框架中AOP切面编程,不过在springboot中为了快速开发仅仅提供了注解方式的切面编程.

1、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、相关注解

# 切面注解
- @Aspect 用来类上,代表这个类是一个切面
- @Before 用在方法上代表这个方法是一个前置通知方法 
- @After 用在方法上代表这个方法是一个后置通知方法 @Around 用在方法上代表这个方法是一个环绕的方法
- @Around 用在方法上代表这个方法是一个环绕的方法
- @Configuration  用来标记是一个spring.xml 文件  

3、 相关表达式

- execution 表达式,后面可以写,具体切到某一个方法,颗粒度很细,但是也代表解析时间越长 
    - * 第一个参数为返回值
    - com.fashion.*.* 具体某个包  .*.*代表是包下面所有子包 
    - (..) 方法参数   ..代表是任意参数 
- with 后面写直接切到某个包下面,颗粒度较粗
- @Annation 标记有注解的才被切点捕捉到

4、前置切面

@Configuration
@Aspect
public class MyAspect {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Before("execution(* com.fashion.controller.*.*(..))")
    public void before(JoinPoint joinpoint) {
        logger.info("我是前置通知=========》");
        logger.debug("执行目标对象:{}",joinpoint.getTarget().getClass().getName());
        logger.debug("方法签名:{}",joinpoint.getSignature());
        logger.debug("请求参数:{}",joinpoint.getArgs());
    }
}

结果
在这里插入图片描述

5、后置切面


    @After("within(com.fashion.controller.*)")
    public void after(JoinPoint joinpoint) {
        logger.info("我是后置通知=========》");
        logger.debug("执行目标对象:{}",joinpoint.getTarget().getClass().getName());
        logger.debug("方法签名:{}",joinpoint.getSignature());
        logger.debug("请求参数:{}",joinpoint.getArgs());
    }

6、环绕切面

 @Around("within(com.fashion.controller.*)")
    public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
        logger.info("我是环绕通知=========》");
        logger.debug("执行目标对象:{}",joinpoint.getTarget().getClass().getName());
        logger.debug("方法签名:{}",joinpoint.getSignature());
        logger.debug("请求参数:{}",joinpoint.getArgs());

        Object result = joinpoint.proceed();// 执行目标方法

        return result;

    }

结果

在这里插入图片描述

注意: 环绕通知存在返回值,参数为ProceedingJoinPoint,如果执行放行,不会执行目标方法,一旦放行必须将目标方法的返回值返回,否则调用者无法接受返回数据

文件上传下载功能

文件上传

用户将自己计算机的文件通过浏览器上传到服务器指定位置,在上传的过程我们称为文件上传;

1、jsp 页面开发

<%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
</head>
<body>

<div style="margin:auto;" >
   <h1>springboot 文件上传</h1>
   <form action="/file/upload" method="post" enctype="multipart/form-data">
       <input type="file" name="file"><br><br>
       <button type="submit" value="提交">提交</button>
   </form>
</div>

</body>
</html>

页面效果

在这里插入图片描述

2、controller 编写

@Controller
@RequestMapping("/file/")
public class FileController {


    public final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${file.dir}")
    private String path;


    @RequestMapping("upload")
    public String upload(MultipartFile file) {
        logger.info("文件原始名称:{}",file.getOriginalFilename());
        logger.info("文件大小kb:{}",file.getSize() / 1024);

        String oriName = file.getOriginalFilename();
        String subFix = oriName.substring(file.getOriginalFilename().lastIndexOf("."));
        logger.info("文件后缀:{}",subFix);

        // 新文件名称
        String newFileName = new Date().getTime() + subFix;

        File uploadFile = new File(path,newFileName);

        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "redirect:/upload.jsp";

    }
}

3、yml 配置

  • 配置文件根目录,指定将文件上传到某个文件的根目录
  • 文件大小限制,指定最大文件大小
server:
  servlet:
    context-path: /
    jsp:
      init-parameters:
        development: true  # 热部署

## 视图解析器配置
spring:
  mvc:
    view:
      suffix: .jsp
      prefix: /
      

#文件过大,会报异常,默认 10M
nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (38443713) exceeds the configured maximum (10485760)      

#修改上传文件大小:
spring:
  http:
    multipart:
       max-request-size: 100M  #用来控制文件上传大小的限制
       max-file-size: 100M #用来指定服务端最大文件大小 

文件下载

将服务器的某个资源下载到本地磁盘用于查看是使用

1、jsp 页面开发

<%@page pageEncoding="UTF-8" contentType="text/html; UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件下载</title>
</head>
<body>

<div style="margin:auto;" >
   <h1>springboot 文件下载</h1>

    <a href="/file/download?fileName=1728045592798.png">1728045592798.png</a>
    <a href="/file/download?fileName=aa.md">aa.md</a>
    <a href="/file/download?fileName=我是文件.txt">我是文件.txt</a>
</div>

</body>
</html>

2、controller编写

 /**
     *  文件下载
     * @param fileName
     * @param response
     * @return
     */
    @RequestMapping("download")
    public void download(String fileName, HttpServletResponse response) throws Exception {
        logger.info("需要下载的文件名称:{}",fileName);

        File downLoadFile = new File(path,fileName);
        logger.info("文件绝对路径:{}",downLoadFile.getAbsolutePath());

        ServletOutputStream os = response.getOutputStream();
        response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));

        IOUtils.copy(new FileInputStream(downLoadFile),os);

        IOUtils.closeQuietly(os);
    }

3、页面效果

在这里插入图片描述


拦截器

拦截器相当于 aop ,底层实际上也是使用的 aop 功能, 拦截器(inteceptor) 和 过滤器(Filter) 的区别是,Filter 过滤器可以拦截所有请求,包含.jsp .js .css 等全部资源;

但是 interceptor 拦截器只能拦截 controller方法,也就是 url 方法

1、编写拦截器

public class MyInterceptor implements HandlerInterceptor {

    public final Logger logger = LoggerFactory.getLogger(this.getClass());



    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("=========== 步骤1 ==========");
        return true; //返回true 放行  返回false阻止
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("=========== 步骤2 ==========");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("=========== 步骤3 ==========");
    }
}

2、将自定义的拦截器加入注册器中

@Configuration
public class WebConfiguration implements WebMvcConfigurer {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**")// 拦截的路径
                .excludePathPatterns("/hello") //放行的路径
                .order(1);// 指定加载的顺序,按照正序排序
    }
}

3、效果

在这里插入图片描述

当我们访问http://localhost:8081/download.jsp的时候,拦截器没有出来,当我们访问下载的url后,日志就出来了;

  • 拦截器的order 用来编排有多个拦截器,需要指定顺序的时候使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空寻流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值