SpringBoot2异常处理与web原生组件注入的方法

发布时间:2022-03-22 13:35:12 作者:iii
来源:亿速云 阅读:99

SpringBoot2异常处理与Web原生组件注入的方法

引言

在Spring Boot 2.x中,异常处理和Web原生组件的注入是开发Web应用程序时经常遇到的两个重要主题。Spring Boot提供了多种机制来处理异常,并且允许开发者轻松地将Servlet、Filter、Listener等Web原生组件注入到Spring容器中。本文将详细介绍如何在Spring Boot 2.x中进行异常处理以及如何注入Web原生组件。

一、Spring Boot 2.x中的异常处理

1.1 默认异常处理机制

Spring Boot默认提供了一个BasicErrorController来处理应用程序中的异常。当应用程序抛出未捕获的异常时,Spring Boot会自动将请求重定向到/error路径,并返回一个包含错误信息的JSON响应或HTML页面。

1.1.1 自定义错误页面

要自定义错误页面,可以在src/main/resources/templates目录下创建一个error.html文件。Spring Boot会自动使用这个文件来渲染错误页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Error</title>
</head>
<body>
    <h1>Error Page</h1>
    <p>Status: [[${status}]]</p>
    <p>Error: [[${error}]]</p>
    <p>Message: [[${message}]]</p>
</body>
</html>

1.1.2 自定义错误JSON响应

要自定义错误JSON响应,可以通过实现ErrorAttributes接口或继承DefaultErrorAttributes类来定制错误信息的格式。

import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;

import java.util.Map;

@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
        errorAttributes.put("customAttribute", "This is a custom error attribute");
        return errorAttributes;
    }
}

1.2 使用@ControllerAdvice进行全局异常处理

@ControllerAdvice注解允许我们定义一个全局的异常处理类,用于处理应用程序中所有控制器抛出的异常。

1.2.1 定义全局异常处理类

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleException(Exception ex) {
        return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
        return new ResponseEntity<>("Invalid argument: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}

1.2.2 处理特定控制器的异常

@ControllerAdvice还可以与@ExceptionHandler结合使用,处理特定控制器抛出的异常。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice(assignableTypes = {MyController.class})
public class MyControllerExceptionHandler {

    @ExceptionHandler(MyCustomException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleMyCustomException(MyCustomException ex) {
        return new ResponseEntity<>("Custom exception: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}

1.3 使用@ExceptionHandler进行局部异常处理

@ExceptionHandler注解可以用于控制器内部,处理该控制器抛出的特定异常。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
        return new ResponseEntity<>("Invalid argument: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @GetMapping("/test")
    public String test() {
        throw new IllegalArgumentException("Test exception");
    }
}

1.4 使用@ResponseStatus自定义HTTP状态码

@ResponseStatus注解可以用于自定义异常类,指定当该异常抛出时返回的HTTP状态码。

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource not found")
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

1.5 使用ErrorController自定义错误处理

通过实现ErrorController接口,可以完全自定义错误处理逻辑。

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class MyErrorController implements ErrorController {

    @RequestMapping("/error")
    public String handleError(HttpServletRequest request) {
        // 自定义错误处理逻辑
        return "error";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}

二、Web原生组件的注入

Spring Boot允许开发者将Servlet、Filter、Listener等Web原生组件注入到Spring容器中,从而在Spring Boot应用程序中使用这些组件。

2.1 注入Servlet

2.1.1 使用@WebServlet注解

可以通过@WebServlet注解将Servlet注册到Spring Boot应用程序中。

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "myServlet", urlPatterns = "/myServlet")
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().write("Hello from MyServlet");
    }
}

2.1.2 使用ServletRegistrationBean

可以通过ServletRegistrationBean将Servlet注册到Spring Boot应用程序中。

import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ServletConfig {

    @Bean
    public ServletRegistrationBean<MyServlet> myServletRegistrationBean() {
        return new ServletRegistrationBean<>(new MyServlet(), "/myServlet");
    }
}

2.2 注入Filter

2.2.1 使用@WebFilter注解

可以通过@WebFilter注解将Filter注册到Spring Boot应用程序中。

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化逻辑
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 过滤逻辑
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 销毁逻辑
    }
}

2.2.2 使用FilterRegistrationBean

可以通过FilterRegistrationBean将Filter注册到Spring Boot应用程序中。

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistrationBean() {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new MyFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

2.3 注入Listener

2.3.1 使用@WebListener注解

可以通过@WebListener注解将Listener注册到Spring Boot应用程序中。

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class MyListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 上下文初始化逻辑
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 上下文销毁逻辑
    }
}

2.3.2 使用ServletListenerRegistrationBean

可以通过ServletListenerRegistrationBean将Listener注册到Spring Boot应用程序中。

import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ListenerConfig {

    @Bean
    public ServletListenerRegistrationBean<MyListener> myListenerRegistrationBean() {
        return new ServletListenerRegistrationBean<>(new MyListener());
    }
}

2.4 注入ServletContextInitializer

ServletContextInitializer接口允许开发者在Servlet上下文初始化时执行自定义逻辑。

import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.stereotype.Component;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

@Component
public class MyServletContextInitializer implements ServletContextInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // 自定义初始化逻辑
    }
}

2.5 注入ServletContextListener

ServletContextListener接口允许开发者在Servlet上下文初始化和销毁时执行自定义逻辑。

import org.springframework.stereotype.Component;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

@Component
public class MyServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 上下文初始化逻辑
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 上下文销毁逻辑
    }
}

三、总结

Spring Boot 2.x提供了多种机制来处理异常,并且允许开发者轻松地将Servlet、Filter、Listener等Web原生组件注入到Spring容器中。通过合理地使用这些机制,开发者可以构建出更加健壮和灵活的Web应用程序。

在异常处理方面,Spring Boot提供了默认的异常处理机制,开发者可以通过自定义错误页面、错误JSON响应、全局异常处理、局部异常处理等方式来满足不同的需求。

在Web原生组件的注入方面,Spring Boot支持通过注解和编程式配置两种方式来注册Servlet、Filter、Listener等组件。开发者可以根据具体需求选择合适的方式来注入这些组件。

通过本文的介绍,相信读者已经对Spring Boot 2.x中的异常处理和Web原生组件注入有了更深入的了解。希望这些知识能够帮助开发者在实际项目中更好地应用Spring Boot,构建出高质量的Web应用程序。

推荐阅读:
  1. Zookeeper整合SpringBoot2 Curator组件方法
  2. Do带你解析:原生APP与web APP的区别

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot2 web

上一篇:Java中的静态字段和静态方法怎么用

下一篇:MybatisPlus EntityWrapper怎么自定义SQL

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》