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>