Java研学-SpringBoot(五)

七 统一异常处理

1 框架自带方式

  Spring Boot 默认会把所有错误都交给 BasicErrorController 类完成处理,错误的视图导向到 classpath:/static/error/ 和 classpath:/templates/error/路径上,HTTP 状态码就是默认视图的名称。如:

// 出现 404 错误 ->
classpath:/static/error/404.html 
// 出现 5xx 错误 
classpath:/static/error/5xx.html

  于 resources/static 目录下创建error目录,导入404.html文件后,当出现404错误时,就会展示该页面

<!DOCTYPE html>  
<html lang="zh">  
<head>  
    <meta charset="UTF-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title>404 - 页面未找到</title>  
    <style>  
        body {  
            font-family: Arial, sans-serif;  
            background-color: #f0f0f0;  
            display: flex;  
            justify-content: center;  
            align-items: center;  
            height: 100vh;  
            margin: 0;  
        }  
  
        .container {  
            text-align: center;  
            background-color: #fff;  
            padding: 30px;  
            border-radius: 10px;  
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);  
        }  
  
        h1 {  
            color: #333;  
            font-size: 24px;  
        }  
  
        p {  
            color: #666;  
            font-size: 16px;  
            margin-top: 10px;  
        }  
  
        a {  
            color: #007bff;  
            text-decoration: none;  
            font-weight: bold;  
        }  
    </style>  
</head>  
<body>  
    <div class="container">  
        <h1>404 - 页面未找到</h1>  
        <p>很抱歉,您正在寻找的页面不存在或已被移除。</p>  
        <p>请检查您输入的网址是否正确,或者返回<a href="/">首页</a>继续浏览。</p>  
    </div>  
</body>  
</html>

2 控制器增强器

  针对不同的错误类型,给用户的提示也要随之变化,请求的不同,返回的也应该不同(404没找到的话是返回一个固定的页面,500对于Ajax请求,返回的应该是一个json字符串,对于form表单的请求,返回的就应该是一个页面)
  于 src/main/java/cn/tj/play_boot/web/advice 目录下创建 ExceptionControllerAdvice 统一异常处理类(需要贴上异常处理类注解 @ControllerAdvice),不同的异常返回的异常信息也不同,可创建多个异常处理方法进行捕获,哪一个方法的异常类型更详细,就由那个方法进行捕获(运行时异常,算术异常)

@ControllerAdvice
public class ExceptionControllerAdvice {
    //Controller 中写的是处理器方法 ControllerAdvice 中写的是异常处理方法
	//他与Controller 相同点
		//返回值
		//void 会定义形参 HttpServletResponse 类型 自定义响应内容 
		//String 处理方法可以定义个Model 形参,响应HTML 格式
		//自定义类型 响应 JSON 格式数据,方法上要贴@ResponseBody
		//ModelAndView 响应 HTML
	//不同点
		//这个处理异常的方法不贴@RequestMapping,贴的是@ExceptionHandler 注解,指定针对什么类型的异常
		// 形参中可以指定异常类
		// 指定异常是因为这样就可以根据不同的异常类型来响应不同的内容。
		// 在请求访问经过控制器,业务层,Mapper 对象,整个调用的过程中若出现了异常且没有被处理(try catch)。这些异常都统一交给这个方法来处理
    @ExceptionHandler(RuntimeException.class)
    public String handlerException(Model model, RuntimeException e) {
        e.printStackTrace();
        // 将异常信息显示到页面上
        model.addAttribute("errorMsg", e.getMessage());
        // 对应的templates中应该有一个error页面
        return "error";
    }
}
<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>500异常页面</title>
</head>
<body>
   <p th:text="${errorMsg}"></p>
</body>
</html>

八 拦截器

1 介绍

  在传统的 XML 方式中,需要在 <mvc:interceptors> 标签中去注册自定义的拦截器。
  在 Spring Boot 中,提供了 WebMvcConfigurer 配置接口,是使用 JavaConfig 配置 Spring MVC 的标准,如果对 Spring MVC 做配置,则需要自定义配置类实现该接口,若是需要注册拦截器,则实现接口中的 addInterceptors 方法即可

2 编辑拦截器

  于 src/main/java/cn/tj/play_boot/web/interceptor 创建 HelloInterceptor 拦截器

@Component
public class HelloInterceptor implements HandlerInterceptor {
/*请求进入controller之前拦截 true为放行*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器来喽");
        return true;
    }
}

3 注册

  原来编辑拦截器后需要在xml中进行注册,但在 JavaConfig 中需要自定义配置类(贴 @Configuration 注解),继承WebMvcConfigurer 接口,重写对应的方法(大改),于src/main/java/cn/tj/play_boot/config/ 目录创建 MvcJavaConfig ,重写添加拦截器方法(addInterceptors)

@Configuration
public class MvcJavaConfig implements WebMvcConfigurer {
    @Autowired
    private HelloInterceptor helloInterceptor;
    // 拦截器可以设置多个 其执行顺序就是我们的书写顺序
    // 设置拦截器的拦截规则
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    // 所有需要注册的拦截器都封装到了 InterceptorRegistry 中
        registry.addInterceptor(helloInterceptor)//注册自定义的拦截器对象
                .addPathPatterns("/**")//设置需要拦截的路径(全部路径)
                .excludePathPatterns("/static/*","/user");//设置不需要拦截的路径(可设置多个路径)
                
	// 可编辑多个拦截器
		/*registry.addInterceptor(helloInterceptor2)//注册自定义的拦截器对象
                .addPathPatterns("/**")//设置需要拦截的路径(全部路径)
                .excludePathPatterns("/static/*","/user");//设置不需要拦截的路径(可设置多个路径)*/
    }
}

九 日志

1 作用

  日志框架可以把日志的输出和代码分离,能够很方便的定义日志的输出环境,控制台,文件,数据库以及日志的输出格式和输出级别。配置文件设置logging.level.cn.tj.mapper=trace会导致服务器日志磁盘占用越来越多

2 Spring Boot 中的日志

  Spring Boot 默认开启日志,其默认的日志格式为:时间 日志级别 线程ID 线程名称 日志类 日志说明。
  Spring Boot 的日志分为:系统日志和应用日志。日志级别,级别越高,输出的内容越少,如果设置的级别为 info,则 debug 以及 trace 级别的都无法显示,日志级别由低到高 trace < debug < info < warn < error。
  Spring Boot 默认选择 Logback 作为日志框架

3 输出日志 – 两种方式

  在定义静态Logger对象时,你需要传入当前类的.class属性作为参数给LoggerFactory.getLogger()方法。但是,不能直接写当前类.class,因为当前类并不是一个有效的Java语法。需要使用this.getClass()或者类名.class来获取当前类的Class对象。

// 类中定义一个静态 Logger 对象,传入当前类后可查看该类的日志
private static final Logger log = LoggerFactory.getLogger(当前类.class);

  @Slf4j 注解会自动为 PermissionServiceImpl 类生成一个静态的 final Logger 对象,名为 log,这个对象是通过 SLF4J 的 LoggerFactory 初始化的。这样就不必手动编写和初始化 Logger 对象了。

// 使用 Lombok 提供的 @Slf4j 注解简化代码,和方式一的作用相同
@Slf4j
@Service
public class DepartmentServiceImpl implements DepartmentService {}

  日志的输出方法,springboot默认的日志级别为info,所以低级别的 trace 和 debug 直接调用log.trace(…)和log.debug(…)是看不到的,需要在application.properties文件中进行小改(logging.level.root=trace)后才能看到所有日志信息

// 在需要输出日志的地方使用日志的输出方法,
log.info(...);
log.error(...);
...
// 输出日志中变量可以使用 {} 作为占位符,id中的数据会替换{}
log.info("删除id为{}的数据", id);

4 Logback 配置文件

  resources 目录下创建 logback-spring.xml 文件,Logback 框架默认会自动加载 classpath:logback.xml,在 Spring Boot 中使用时,会额外的支持自动加载classpath:logback-spring.xml(模板文件直接复制即可),其中由 appender 标签决定将日志输出到哪里,通过 < appender-ref ref=“STDOUT”/> 决定选用那个 appender 标签

<?xml version="1.0" encoding="UTF-8"?>
<!--scan:开启日志框架的热部署,默认值 true 表示开启
    scanPeriod:热部署的频率,默认值 60 second
    debug:设置输出框架内部的日志,默认值 false-->
    
<configuration scan="true" scanPeriod="60 second" debug="false">
    <property name="appName" value="springboot demo"/>
    <contextName>${appName}</contextName>
    <!-- appender:日志输出对象,配置不同的类拥有不同的功能
        ch.qos.logback.core.ConsoleAppender:日志输出到控制台        
    -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd-HH:mm:ss} %level [%thread]-%logger{35} >> %msg %n</pattern>
                 
        </encoder>  
    </appender>
    <!--ch.qos.logback.core.FileAppender:日志输出到文件中-->
    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
   		<!--日志格式-->
        <encoder>
            <pattern>%-4relative [%thread] %level %logger{35} - %msg %n</pattern>
       </encoder>
       <!--是否追加,指同一个文件不断续写重启不刷新,设置为false后重启程序日志文件会刷新,一般设为true-->
        <append>true</append>
        <!--要输出的文件名,默认会生成到当前工程目录下-->
        <file>mylog.log</file>
   </appender>
    <!--
        root 是项目通用的 logger,一般情况下都是使用 root 配置的日志输出
        level:按照级别输出日志,日志级别,级别越高,输出的内容越少
        可以同时支持两种日志输出方式:控制台和文件
    -->
    <root level="info">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="fileAppender"/>
    </root>
    <!-- 自定义的 logger,用于专门输出特定包中打印的日志
    <logger name="cn.tj.crm.mapper" level="trace">
    </logger>
	-->
</configuration>

十 banner

1 修改 banner

  在 resources 目录中放入 banner.txt 文件,即可替换默认的 banner。
  可以通过在线banner制作自定义的 banner

2 关闭 banner – application.properties 文件

# 关闭 banner
spring.main.banner-mode=off 

十一 热部署

1 导入依赖

  Spring Boot 重启是 reload 重启,通过监控 classpath 的变化,如果 classpath 中的文件发生变化,即触发重启。Spring Boot 通过两个 classpath 来完成 reload,一个 basic classloader 中加载不变的类(jar 包中的类),一个 restart classloader 中加载 classpath 中的类(自己写的类),重启的时候,restart classloader 中的类丢弃并重新加载。
  JRebel 可以实现热部署,Spring Boot 也可以通过提供的 spring-boot-devtools 包来完成 Springboot 应用热部署。

<!-- Spring Boot 热部署插件 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

2 使用

  导入依赖后,编辑代码时可通过单击锤子完成重新加载(此时不是所有文件都重新加载,只重新加载更改后的那个文件),使用锤子的前提是没有改变类的结构(可以编辑方法体中的内容,但是不能新增方法),通常锤子会比重启快一些

  • 39
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

泰勒疯狂展开

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

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

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

打赏作者

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

抵扣说明:

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

余额充值