014-Spring Boot web【三】攔截器HandlerInterceptor、異常處理頁面,全局異常處理ControllerAdvice


一、攔截器HandlerInterceptor

1.1、HandlerInterceptor接口說明

  preHandle,congtroller執行前,如果返回false請求終端

  postHandle,controller執行之后,頁面渲染前

  afterCompletion,整個請求結束后,頁面也渲染完畢,一般是資源清理操作

  同時提供異步攔截器AsyncHandlerInterceptor

1.2、攔截器使用步驟

  1》寫一個攔截器,實現HandlerInterceptor 接口

  2》寫一個類,繼承WebMvcConfigurerAdapter抽象類,然后重寫addInterceptors方法,把上一步的攔截器加入registry.addInterceptor(new LogHandlerInterceptor());

1.3、示例

  啟動類

package com.lhx.spring.springboot_web;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
View Code

  建立UserController

package com.lhx.spring.springboot_web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class UserController {

    @GetMapping(value = "/user/home")
    public String home() {
        System.out.println("--------user home--------");
        return "user home";
    }    
}
View Code

  增加攔截器LogHandlerInterceptor 

package com.lhx.spring.springboot_web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class LogHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("----------preHandle----------"+handler.getClass());
        
        
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("----------postHandle----------");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("----------afterCompletion----------");

    }

}
View Code

  增加配置類WebConfiguration 

package com.lhx.spring.springboot_web;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SpringBootConfiguration
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogHandlerInterceptor());
    }

}
View Code

二、異常處理

2.1、編碼拋出異常代碼

    @GetMapping(value = "/user/help")
    @ResponseBody
    public String help() {
        throw new IllegalArgumentException("args is empty");
    }    
View Code

2.2、分析代碼

  查看:org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,發現默認已經被springboot定制。

  去除springboot默認異常顯示,只需在啟動類添加:@SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class)即可。則返回錯誤就會變成Tomcat提供的

2.3、添加自定義錯誤頁

  1》去除springboot默認的:@SpringBootApplication(exclude=ErrorMvcAutoConfiguration.class)

  2》在src/main/resources下增加public,在pulic中增加404.html,500.html

  3》增加CommonErrorPageRegistry實現ErrorPageRegistrar增加@Component注解,可以針對錯誤碼處理或者具體異常處理

package com.lhx.spring.springboot_web;

import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.boot.web.servlet.ErrorPageRegistrar;
import org.springframework.boot.web.servlet.ErrorPageRegistry;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
public class CommonErrorPageRegistry implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
        ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
        ErrorPage args = new ErrorPage(IllegalArgumentException.class, "/args.html");
        registry.addErrorPages(e404);
        registry.addErrorPages(e500);
        registry.addErrorPages(args);
    }

}
View Code

    以上將404,500邏輯添加

 三、全局異常處理

3.1、局部異常處理

  當前Controller使用,可以在當前Controller中使用ExceptionHandler注解

如下代碼

package com.lhx.spring.springboot_web;

import java.io.FileNotFoundException;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class BookController {
    
    @ExceptionHandler(value = Exception.class)
    public String error(Exception e) {
        return "fount exception:"+e.getMessage();
    }
    
    @GetMapping("book/error1")
    public String error1() throws FileNotFoundException {
        throw new FileNotFoundException("book not found");
    }
    @GetMapping("book/error2")
    public String error2() throws ClassNotFoundException {
        throw new ClassNotFoundException("class not found");
    }
}
View Code

  其中:@ExceptionHandler(value = Exception.class) 代表所有;也可指代具體異常,如文件沒有發現@ExceptionHandler(value = FileNotException.class)

3.2、全局異常處理

  1》寫一個GlobalExceptionHandler異常處理類,並且使用@ControllerAdvice注解

  2》寫一個方法,需要添加@ExceptionHandler(value = Exception.class)注解,在方法中編寫具體代碼邏輯

package com.lhx.spring.springboot_web;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public String errorHandler(Exception e) {
        return "global error:" + e.getClass().getName();
    }
}
View Code

  可以有多個不同的異常處理。

3.3、就近原則

  局部異常優先級高於全局異常處理

一個比較通用的寫法

@ControllerAdvice
@ResponseBody
public class ResponseExceptionHandler {
    Logger logger=LoggerFactory.getLogger(ResponseExceptionHandler.class);

    @ExceptionHandler(ResponseException.class)
    public ResponseEntity<ResponseResult> handleException(Exception e) {
        logger.error("請求異常信息",e);
        ResponseException cex = (ResponseException) e;
        return new ResponseEntity(ResponseResult.error(cex.getResponseCode()), HttpStatus.OK);
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM