互联网大厂必问的Spring boot已成为常态,现在学还来得及!

本文主要是介绍互联网大厂必问的Spring boot已成为常态,现在学还来得及!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

自 2014 年发布至今,Spring Boot 的搜索指数 一路飙升。没错 Spring Boot 越来越火了,作为一名行走一线的 Java 程序员,你可能在各个方面感受到了 Spring Boot 的火。

现在各大技术社区 Spring Boot 的文章越来越多,Spring Boot 相关的图文、视频教程越来越多,使用 Spring Boot 的互联网公司也越来越多; Java 程序员现在出去面试, Spring Boot 已经成了必问的内容。

一切都在证明,Spring Boot 已经成为了 Java 程序员必备的技能。并且可以预见的是未来 Spring Boot 的发展还会更好。学 Spring Boot,事不宜迟!

 

Spring Boot2教程

在Spring Boot项目中,正常来说是不存在XML配置,这是因为Spring Boot不推荐使用 XML ,注意,并非不支持,Spring Boot 推荐开发者使用 Java 配置来搭建框架,Spring Boot 中,大量的自动化配置都是通过 Java 配置来实现的,这一套实现方案,我们也可以自己做,即自己也可以使用纯 Java 来搭建一个 SSM 环境,即在项目中,不存在任何 XML 配置,包括 web.xml 。

环境要求:

使用纯 Java 来搭建 SSM 环境,要求 Tomcat 的版本必须在 7 以上。

1、创建工程

创建一个普通的 Maven工程(注意,这里可以不必创建Web工程),并添加SpringMVC的依赖,同时,这里环境的搭建需要用到 Servlet ,所以我们还需要引入 Servlet 的依赖(一定不能使用低版本的Servlet),最终的 pom.xml 文件如下:

 
  1. <dependency>

  2. <groupId>org.springframework</groupId>

  3. <artifactId>spring-webmvc</artifactId>

  4. <version>5.1.6.RELEASE</version>

  5. </dependency>

  6. <dependency>

  7. <groupId>javax.servlet</groupId>

  8. <artifactId>javax.servlet-api</artifactId>

  9. <version>4.0.1</version>

  10. <scope>provided</scope>

  11. </dependency>

2 、添加 Spring 配置

工程创建成功之后,首先添加 Spring 的配置文件,如下:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy", useDefaultFilters = true,

  3. excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes =

  4. Controller.class)})

  5. public class SpringConfig {

  6. }

关于这个配置,我说如下几点:

@Configuration 注解表示这是一个配置类,在我们这里,这个配置的作用类似于applicationContext.xml

@ComponentScan 注解表示配置包扫描,里边的属性和 xml 配置中的属性都是一一对应的,useDefaultFilters 表示使用默认的过滤器,然后又除去 Controller 注解,即在 Spring 容器中扫描除了 Controller 之外的其他所有 Bean 。

3、 添加 SpringMVC 配置

接下来再来创建 springmvc 的配置文件:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy",useDefaultFilters =

  3. false,includeFilters = {@ComponentScan.Filter(type =

  4. FilterType.ANNOTATION,classes = Controller.class)})

  5. public class SpringMVCConfig {

  6. }

注意,如果不需要在SpringMVC中添加其他的额外配置,这样就可以了。即视图解析器、JSON解析、文件上传......等等,如果都不需要配置的话,这样就可以了。

4、配置 web.xml

此时,我们并没 web.xml 文件,这时,我们可以使用Java代码去代替 web.xml 文件,这里会用到WebApplicationInitializer ,具体定义如下:

 
  1. public class WebInit implements WebApplicationInitializer {

  2. public void onStartup(ServletContext servletContext) throws ServletException

  3. {

  4. //首先来加载 SpringMVC 的配置文件

  5. AnnotationConfigWebApplicationContext ctx = new

  6. AnnotationConfigWebApplicationContext();

  7. ctx.register(SpringMVCConfig.class);

  8. // 添加 DispatcherServlet

  9. ServletRegistration.Dynamic springmvc =

  10. servletContext.addServlet("springmvc", new DispatcherServlet(ctx));

  11. // 给 DispatcherServlet 添加路径映射

  12. springmvc.addMapping("/");

  13. // 给 DispatcherServlet 添加启动时机

  14. springmvc.setLoadOnStartup(1);

  15. }

  16. }

WebInit 的作用类似于 web.xml,这个类需要实现 WebApplicationInitializer 接口,并实现接口中的方法,当项目启动时,onStartup 方法会被自动执行,我们可以在这个方法中做一些项目初始化操作,例如加载 SpringMVC 容器,添加过滤器,添加 Listener、添加 Servlet 等。

注意:

由于我们在WebInit中只是添加了SpringMVC的配置,这样项目在启动时只会去加载SpringMVC容器,而不会去加载 Spring 容器,如果一定要加载 Spring 容器,需要我们修改 SpringMVC 的配置,在SpringMVC 配置的包扫描中也去扫描 @Configuration 注解,进而加载 Spring 容器,还有一种方案可以解决这个问题,就是直接在项目中舍弃 Spring 配置,直接将所有配置放到 SpringMVC 的配置中来完成,这个在 SSM 整合时是没有问题的,在实际开发中,较多采用第二种方案,第二种方案,SpringMVC 的配置如下:

 
  1. @Configuration

  2. @ComponentScan(basePackages = "org.javaboy")

  3. public class SpringMVCConfig {

  4. }

这种方案中,所有的注解都在 SpringMVC 中扫描,采用这种方案的话,则 Spring 的配置文件就可以删除了。

5、测试

最后,添加一个 HelloController ,然后启动项目进行测试:

 
  1. @RestController

  2. public class HelloController {

  3. @GetMapping("/hello")

  4. public String hello() {

  5. return "hello";

  6. }

  7. }

启动项目,访问接口,结果如下:

Spring Boot全局异常处理

在Spring Boot项目中 ,异常统一处理,可以使用Spring中@ControllerAdvice来统一处理,也可以自己来定义异常处理方案。Spring Boot 中,对异常的处理有一些默认的策略,我们分别来看。

默认情况下,Spring Boot 中的异常页面 是这样的:

我们从这个异常提示中,也能看出来,之所以用户看到这个页面,是因为开发者没有明确提供一个/error 路径,如果开发者提供了 /error 路径 ,这个页面就不会展示出来,不过在 Spring Boot 中,提供/error 路径实际上是下下策,Spring Boot本身在处理异常时,也是当所有条件都不满足时,才会去找 /error 路径。那么我们就先来看看,在 Spring Boot 中,如何自定义 error 页面,整体上来说,可以分为两种,一种是静态页面,另一种是动态页面。

静态异常页面

自定义静态异常页面,又分为两种,第一种 是使用HTTP响应码来命名页面,例如404.html、405.html、500.html ....,另一种就是直接定义一个 4xx.html,表示400-499 的状态都显示这个异常页面,5xx.html 表示 500-599 的状态显示这个异常页面。

默认是在 classpath:/static/error/ 路径下定义相关页面:

此时,启动项目,如果项目抛出 500 请求错误,就会自动展示 500.html 这个页面,发生 404 就会展示404.html 页面。如果异常展示页面既存在 5xx.html,也存在 500.html ,此时,发生500异常时,优先展示 500.html 页面。

动态异常页面

动态的异常页面定义方式和静态的基本 一致,可以采用的页面模板有 jsp、freemarker、thymeleaf。

动态异常页面,也支持 404.html 或者 4xx.html ,但是一般来说,由于动态异常页面可以直接展示异常详细信息,所以就没有必要挨个枚举错误了 ,直接定义 4xx.html(这里使用thymeleaf模板)或者5xx.html 即可。

注意,动态页面模板,不需要开发者自己去定义控制器,直接定义异常页面即可 ,Spring Boot 中自带的异常处理器会自动查找到异常页面。

页面定义如下:

页面内容如下:

 
  1. <!DOCTYPE html>

  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">

  3. <head>

  4. <meta charset="UTF-8">

  5. <title>Title</title>

  6. </head>

  7. <body>

  8. <h1>5xx</h1>

  9. <table border="1">

  10. <tr>

  11. <td>path</td>

  12. <td th:text="${path}"></td>

  13. </tr>

  14. <tr>

  15. <td>error</td>

  16. <td th:text="${error}"></td>

  17. </tr>

  18. <tr>

  19. <td>message</td>

  20. <td th:text="${message}"></td>

  21. </tr>

  22. <tr>

  23. <td>timestamp</td>

  24. <td th:text="${timestamp}"></td>

  25. </tr>

  26. <tr>

  27. <td>status</td>

  28. <td th:text="${status}"></td>

  29. </tr>

  30. </table>

  31. </body>

  32. </html>

默认情况下,完整的异常信息就是这5条,展示 效果如下 :

如果动态页面和静态页面同时定义了异常处理页面,例如 classpath:/static/error/404.html 和classpath:/templates/error/404.html 同时存在时,默认使用动态页面。即完整的错误页面查找方式应该是这样:

发生了 500 错误-->查找动态 500.html 页面-->查找静态 500.html --> 查找动态 5xx.html-->查找静态5xx.html。

自定义异常数据

默认情况下,在 Spring Boot 中,所有的异常数据其实就是上文所展示出来的 5 条数据,这 5 条数据定义在 org.springframework.boot.web.reactive.error.DefaultErrorAttributes 类中,具体定义在 getErrorAttributes 方法中 :

 
  1. @Override

  2. public Map<String, Object> getErrorAttributes(ServerRequest request,

  3. boolean includeStackTrace) {

  4. Map<String, Object> errorAttributes = new LinkedHashMap<>();

  5. errorAttributes.put("timestamp", new Date());

  6. errorAttributes.put("path", request.path());

  7. Throwable error = getError(request);

  8. HttpStatus errorStatus = determineHttpStatus(error);

  9. errorAttributes.put("status", errorStatus.value());

  10. errorAttributes.put("error", errorStatus.getReasonPhrase());

  11. errorAttributes.put("message", determineMessage(error));

  12. handleException(errorAttributes, determineException(error),

  13. includeStackTrace);

  14. return errorAttributes;

  15. }

DefaultErrorAttributes 类本身则是在

org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration 异常自动配置类中定义的,如果开发者没有自己提供一个 ErrorAttributes 的实例的话,那么 Spring Boot 将自动提供一个 ErrorAttributes 的实例,也就是 DefaultErrorAttributes 。

基于此 ,开发者自定义 ErrorAttributes 有两种方式 :

1. 直接实现 ErrorAttributes 接口

2. 继承 DefaultErrorAttributes(推荐),因为 DefaultErrorAttributes 中对异常数据的处理已经完成,开发者可以直接使用。

具体定义如下:

 
  1. @Component

  2. public class MyErrorAttributes extends DefaultErrorAttributes {

  3. @Override

  4. public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean

  5. includeStackTrace) {

  6. Map<String, Object> map = super.getErrorAttributes(webRequest,

  7. includeStackTrace);

  8. if ((Integer)map.get("status") == 500) {

  9. map.put("message", "服务器内部错误!");

  10. }

  11. return map;

  12. }

  13. }

定义好的 ErrorAttributes 一定要注册成一个 Bean ,这样,Spring Boot 就不会使用默认的DefaultErrorAttributes 了,运行效果如下图:

自定义异常视图

异常视图默认就是前面所说的静态或者动态页面,这个也是可以自定义的,首先 ,默认的异常视图加载逻辑在org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController 类的errorHtml 方法中,这个方法用来返回异常页面+数据,还有另外一个 error 方法,这个方法用来返回异常数据(如果是 ajax 请求,则该方法会被触发)。

 
  1. @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)

  2. public ModelAndView errorHtml(HttpServletRequest request,

  3. HttpServletResponse response) {

  4. HttpStatus status = getStatus(request);

  5. Map<String, Object> model =

  6. Collections.unmodifiableMap(getErrorAttributes(

  7. request, isIncludeStackTrace(request,

  8. MediaType.TEXT_HTML)));

  9. response.setStatus(status.value());

  10. ModelAndView modelAndView = resolveErrorView(request, response, status,

  11. model);

  12. return (modelAndView != null) ? modelAndView : new ModelAndView("error",

  13. model);

  14. }

在该方法中 ,首先会通过 getErrorAttributes 方法去获取异常数据(实际上会调用到 ErrorAttributes的实例 的 getErrorAttributes 方法),然后调用 resolveErrorView 去创建一个 ModelAndView ,如果这里创建失败,那么用户将会看到默认的错误提示页面。

正常情况下, resolveErrorView 方法会来到 DefaultErrorViewResolver 类的 resolveErrorView 方法中:

 
  1. @Override

  2. public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus

  3. status,

  4. Map<String, Object> model) {

  5. ModelAndView modelAndView = resolve(String.valueOf(status.value()),

  6. model);

  7. if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {

  8. modelAndView = resolve(SERIES_VIEWS.get(status.series()),

  9. model);

  10. }

  11. return modelAndView;

  12. }

在这里,首先以异常响应码作为视图名分别去查找动态页面和静态页面,如果没有查找到,则再以 4xx或者 5xx 作为视图名再去分别查找动态或者静态页面。

要自定义异常视图解析,也很容易 ,由于 DefaultErrorViewResolver 是在ErrorMvcAutoConfiguration 类中提供的实例,即开发者没有提供相关实例时,会使用默认的DefaultErrorViewResolver ,开发者提供了自己的 ErrorViewResolver 实例后,默认的配置就会失效,因此,自定义异常视图,只需要提供 一个 ErrorViewResolver 的实例即可:

 
  1. @Component

  2. public class MyErrorViewResolver extends DefaultErrorViewResolver {

  3. public MyErrorViewResolver(ApplicationContext applicationContext,

  4. ResourceProperties resourceProperties) {

  5. super(applicationContext, resourceProperties);

  6. }

  7. @Override

  8. public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus

  9. status, Map<String, Object> model) {

  10. return new ModelAndView("/aaa/123", model);

  11. }

  12. }

实际上,开发者也可以在这里定义异常数据(直接在 resolveErrorView 方法重新定义一个 model ,将参数中的model 数据拷贝过去并修改,注意参数中的 model 类型为 UnmodifiableMap,即不可以直接修改),而不需要自定义 MyErrorAttributes。定义完成后,提供一个名为 123 的视图,如下图:

如此之后,错误试图就算定义成功了。

总结

实际上也可以自定义异常控制器 BasicErrorController ,不过觉得这样太大动干戈了,没必要,前面几种方式已经可以满足我们的大部分开发需求了。如果是前后端分离架构,异常处理还有其他一些处理方案,这个以后和大家聊。

篇幅有限,其他内容就不在这里一一展示了,这份Spring Boot实战教程已整理成一份PDF文档,共有200多页。

关注公众号:麒麟改bug。

最后

欢迎大家一起交流,喜欢文章记得关注我点赞哟,感谢支持!

这篇关于互联网大厂必问的Spring boot已成为常态,现在学还来得及!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/653174

相关文章

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B