Springboot整合之Listener、静态资源、异常处理、热部署
目录:1、Springboot整合Listener 2、Springboot访问静态资源 3、异常处理 4、热部署
一、SpringBoot整合Listener
两种方式完成组件的注册
1、通过注解扫描完成组件的注册
FirstListener
package com.lee.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
/**
* 注解的方式注册listener组件
* <listener>
* <listener-class>com.lee.listener.FirstListener</listener-class>
* </listener>
*/
@WebListener
public class FirstListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("first listener init.....");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("first listener destroy.....");
}
}
启动类
package com.lee;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
//该注解会扫描当前包和其子包下的 @WebServlet,@WebFilter,@WebListener
//并在启动类启动的时候将其实例化
@ServletComponentScan
@SpringBootApplication
public class SpringbootApplicationListener1 {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplicationListener1.class,args);
}
}
结果:
first listener init.....
second filter init
first filter init
2、通过方法完成组件的注册
SecondListener
package com.lee.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SecondListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("second listener init....");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("second listener destroy....");
}
}
启动类
package com.lee;
import com.lee.listener.SecondListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SpringbootApplicationListener2 {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplicationListener2.class,args);
}
@Bean
public ServletListenerRegistrationBean<SecondListener> secondListener(){
ServletListenerRegistrationBean<SecondListener> bean = new ServletListenerRegistrationBean<>();
bean.setListener(new SecondListener());
return bean;
}
}
结果:
second listener init....
first listener init.....
second filter init
first filter init
二、SpringBoot访问静态资源
两种查找静态资源的方式,当然还有其他的方式,后续补充介绍
1、classpath下的static的目录下
Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则:
/static
/public
/resources
/META-INF/resources
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-caQpPYf0-1573701100253)(C:\Users\james\Desktop\笔记\SpringBoot\images\1.png)]
访问:
http://localhost:8080/images/dear.jpg
http://localhost:8080/index.html
2、ServletContext根目录下
在main下创建webapp 讲images和html移入即可,不推荐
三、异常处理
异常处理方式
springboot中对于异常处理提供了五中处理方式:
1、自定义错误页面
2、@ExceptionHandler注解处理异常
3、@ControllerAdvice + @ExceptionHandler注解处理异常
4、配置SimpleMappingExceptionResolver类完成异常处理
5、自定义HandlerExceptionResolver类处理异常
1、自定义错误页面
springboot默认的处理异常的机制:springboot默认的已经提供了一套处理异常的机制,一旦程序中出现了异常,springboot会向、error的URL发送请求。在springboot中提供了一个叫BasicExcetionController来处理error请求。然后跳转到默认显示异常的页面来展示异常信息。
Controller
package com.lee.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class DemoController {
@RequestMapping("/show")
public String show(){
String s = null;
s.length();
return "index";
}
@RequestMapping("/show2")
public String show2(){
int i = 100/0;
return "index";
}
}
自定义错误页面/resources/template/error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>异常处理页面</title>
</head>
<body>
页面出现异常,请您联系管理员.....<br/>
<span th:text="#{exception}"> </span>
</body>
</html>
2、@ExceptionHandler注解处理异常
Controller
package com.lee.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class DemoController {
@RequestMapping("/show")
public String show(){
String s = null;
s.length();
return "index";
}
@RequestMapping("/show2")
public String show2(){
int i = 100/0;
return "index";
}
@ExceptionHandler(value = {NullPointerException.class})
public ModelAndView nullException(Exception e){
ModelAndView mav = new ModelAndView("error1");
mav.addObject("error",e.toString());
return mav;
}
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView arithmeticException(Exception e){
ModelAndView mav = new ModelAndView("error2");
mav.addObject("error",e.toString());
return mav;
}
}
自定义错误页面/resources/template/error1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>异常处理页面NullPointerException</title>
</head>
<body>
页面出现异常,请您联系管理员.....<br/>
<span th:text="${error}"> </span>
</body>
</html>
自定义错误页面/resources/template/error2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>异常处理页面ArithmeticException</title>
</head>
<body>
页面出现异常,请您联系管理员.....<br/>
<span th:text="${error}"> </span>
</body>
</html>
注意:代码冗余
3、@ControllerAdvice + @ExceptionHandler注解处理异常
Controller
package com.lee.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UsersController {
@RequestMapping("/showUsers")
public String showUsers(){
String s = null;
s.length();
return "index";
}
@RequestMapping("/showUsers2")
public String showUsers2(){
int i = 100/0;
return "index";
}
}
GlobalException
package com.lee.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class GlobalException {
@ExceptionHandler(value = {NullPointerException.class})
public ModelAndView nullException(Exception e){
ModelAndView mav = new ModelAndView("error1");
mav.addObject("error",e.toString());
return mav;
}
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView arithmeticException(Exception e){
ModelAndView mav = new ModelAndView("error2");
mav.addObject("error",e.toString());
return mav;
}
}
注意:提高了代码的复用性
4、配置SimpleMappingExceptionResolver类完成异常处理
GlobalException2
在这之前要先把上一节的ControllerAdvice去掉,以免影响测试结果
package com.lee.exception;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.Properties;
/**
* 配置SimpleMappingExceptionResolver类完成异常处理
*/
@Configuration
public class GlobalException2 {
//缺点是只能返回异常映射的视图,不能返回异常映射的内容
@Bean
public SimpleMappingExceptionResolver method1(){
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
/**
* 参数一:异常的类型,注意必须是异常的全名
* 参数二:异常返回的视图
*/
mappings.setProperty("java.lang.NullPointerException","error1");
mappings.setProperty("java.lang.ArithmeticException","error2");
//设置异常与视图的映射信息的
resolver.setExceptionMappings(mappings);
return resolver;
}
}
注意:这个方法其实是对ControlerAdvice的一个精简,用一个方法来解决上述异常问题的
5、自定义HandlerExceptionResolver类处理异常
GlobalException3
在这之前要先把上一节的ControllerAdvice和GlobalException2去掉,以免影响测试结果
package com.lee.exception;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Configuration
public class GlobalException3 implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView mav = new ModelAndView();
if(e instanceof NullPointerException){
mav.setViewName("error1");
}else if(e instanceof ArithmeticException){
mav.setViewName("error2");
}
mav.addObject("error",e.toString());
return mav;
}
}
注意:该方式旨在解决第四种方式不能返回异常内容的问题
还有其他处理异常的方式…待续…
四、热部署
springboot的热部署方式分为两种:
1、SpringLoader插件---【不推荐使用,不再介绍】--热部署的方式
2、DevTools工具---重新部署的方式
1、DevTools工具
<!-- Spring boot 热部署 : 此热部署会遇到 java.lang.ClassCastException 异常 -->
<!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖该项目的项目如果想要使用devtools,需要重新引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>