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

news/2024/10/5 1:12:56 标签: spring boot, 后端, java

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  #指定根日志级别(一般不推荐修改根日志,输出信息太多,推荐使用子日志)

项目中使用

java">@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、前置切面

java">@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、后置切面

java">
    @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、环绕切面

java"> @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 编写

java">@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编写

java"> /**
     *  文件下载
     * @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、编写拦截器

java">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、将自定义的拦截器加入注册器中

java">@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 用来编排有多个拦截器,需要指定顺序的时候使用

http://www.niftyadmin.cn/n/5690551.html

相关文章

10.4学习

1.Transactional 注意事项&#xff1a; ①事务函数中不要处理耗时任务&#xff0c;会导致长期占有数据库连接。 ②事务函数中不要处理无关业务&#xff0c;防止产生异常导致事务回滚。 ●事务传播属性 ①REQUIRED&#xff08;默认属性&#xff09; 如果存在一个事务&#…

android 全面屏最底部栏沉浸式

Activity的onCreate方法中添加 this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); Android 系统 Bar 沉浸式完美兼容方案自 Android 5.0 版本&#xff0c;Android 带来了沉浸式系统 ba - 掘金 (juejin.cn)https://juejin.cn/post/7075578…

随笔:标准是金

数据并不一定是资产&#xff0c;信息才是。 随着人工智能和大数据技术的兴起&#xff0c;和数字化转型的趋势。数据资产管理成为热门话题。需要指出的是&#xff0c;只有能够创造价值的数据才能成为资产。 如果数据要参与交易和传播&#xff0c;更需要转变为信息。通俗地讲&…

在java中都是如何实现这些锁的?或者说都有哪些具体的结构实现

在Java中&#xff0c;多种锁机制的实现依赖于不同的类和接口。以下是一些常见的锁机制及其在Java中的具体实现&#xff1a; 1. 互斥锁&#xff08;Mutex&#xff09; 实现方式&#xff1a;Java中的互斥锁可以通过synchronized关键字或ReentrantLock类来实现。synchronized关键…

【python实操】python小程序之函数的方法和赋值的区别

引言 python小程序之函数的方法和赋值 文章目录 引言一、函数的方法和赋值1.1 题目1.2 代码1.2.1 append方法1.2.2 赋值 1.3 代码解释1.3.1 append方法1.3.2 赋值 二、思考2.1 append方法和赋值的区别2.1.1 append方法2.1.2 赋值操作2.1.3 总结 一、函数的方法和赋值 1.1 题目…

论文笔记:Anytime Continual Learning for Open Vocabulary Classification

1. 挑战/问题 在开放词汇表图像分类中&#xff0c;随着时间的推移&#xff0c;模型需要不断学习新的标签&#xff0c;同时保留对旧标签的记忆。这导致几个挑战&#xff1a; 数据增量学习&#xff1a;模型需要在任意时间点有效地吸收新的训练样本。模型持续改进&#xff1a;模…

Jmeter中有关属性的获取的问题

Jmeter中有3个方法用来获取属性值&#xff1a; props.getProperty(propName), ${__property(propName)} ${__P(propName)} 试验了下&#xff0c;在JSR223 Sampler中使用以上3个方法获取属性值的情况 1. 返回结果如下&#xff1a; 这里看到&#xff0c;在jmeter属性列表里…

职业技术学校开设无人机培训技术详解

职业技术学校开设无人机培训技术&#xff0c;是一个涉及多个方面的综合性教学过程。以下是对该培训技术的详细解析&#xff1a; 一、培训目标 无人机培训技术的目标在于培养学员掌握无人机的基本原理、组装调试、飞行操作、安全规范及维修保养等技能&#xff0c;使其成为具备…