preface

Since its launch in 2014, Spring Boot’s search index has skyrocketed. It’s true that Spring Boot is catching on, and as a Java programmer on the front lines, you’ve probably felt it in many ways.


Now there are more and more articles about Spring Boot in various technical communities, more and more pictures and videos related to Spring Boot, and more and more Internet companies are using Spring Boot. Java programmers are now out interviewing, and Spring Boot has become a must-ask.

Spring Boot is proving to be a must-have skill for Java programmers. And it is foreseeable that the development of Spring Boot will be even better in the future. Learn Spring Boot, no delay!

Spring Boot2 tutorial

XML configuration does not normally exist in Spring Boot projects. This is because XML is not recommended in Spring Boot. Note that it is not not supported. A lot of the automated configuration is done through Java configuration, which we can do ourselves, that is, we can use pure Java to build an SSM environment, that is, there is no XML configuration in the project, including web.xml.

Environmental requirements:

To set up the SSM environment using pure Java, the Tomcat version must be later than 7.

1. Create the project

Create a normal Maven project (note that you don’t need to create a Web project here) and add SpringMVC dependencies. Also, we need to introduce Servlet dependencies (never use a lower version of the Servlet). The final POM.xml file looks like this:

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> < version > 5.1.6. RELEASE < / version > < / dependency > < the dependency > < groupId > javax.mail. Servlet < / groupId > < artifactId > javax.mail. The servlet API - < / artifactId > < version > 4.0.1 < / version > < scope > provided < / scope > < / dependency >Copy the code

2. Add Spring configuration

After the project is successfully created, first add the Spring configuration file as follows:

@Configuration
@ComponentScan(basePackages = "org.javaboy", useDefaultFilters = true,
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes =
Controller.class)})
public class SpringConfig {
}Copy the code
About this configuration, I say the following:

The @Configuration annotation indicates that this is a Configuration class, and in our case, this Configuration acts like applicationContext.xml

UseDefaultFilters use the default filters, and then remove the Controller annotation. That is, all beans except Controller are scanned in the Spring container.

Add the SpringMVC configuration

Next, create the SpringMVC configuration file:

@Configuration
@ComponentScan(basePackages = "org.javaboy",useDefaultFilters =
false,includeFilters = {@ComponentScan.Filter(type =
FilterType.ANNOTATION,classes = Controller.class)})
public class SpringMVCConfig {
}Copy the code
Note that if you don’t need to add any additional configuration in SpringMVC, this is fine. View parser, JSON parsing, file upload…… Wait, if none of them need to be configured, this is fine.

4. Configure web.xml

At this point, we’re not web. The XML file, then we can use Java code to replace web. XML files, here will use WebApplicationInitializer, concrete are defined as follows:

public class WebInit implements WebApplicationInitializer { public void onStartup(ServletContext servletContext) throws ServletException {/ / first to load the configuration file for SpringMVC AnnotationConfigWebApplicationContext CTX = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMVCConfig.class); / / add the DispatcherServlet ServletRegistration. Dynamic for springmvc = servletContext. AddServlet ("springmvc", new DispatcherServlet(ctx)); // Add path mapping to DispatcherServlet springmvc.addMapping("/"); / / add DispatcherServlet start timing for springmvc setLoadOnStartup (1); }}Copy the code
WebInit role similar to the web. The XML, this class needs to implement WebApplicationInitializer interfaces, and interface to realize the method, when the project starts, onStartup method will be executed automatically, we can do it in this way some project initialization, For example, load the SpringMVC container, add filters, add listeners, add servlets, etc.

Note:

Since we only add the SpringMVC configuration in WebInit, the project will only load the SpringMVC container at startup, not the Spring container. If we have to load the Spring container, we need to modify the SpringMVC configuration. The @Configuration annotation is also scanned in the package scan of the SpringMVC Configuration to load the Spring container. Another solution to this problem is to directly discard the Spring Configuration in the project and put all the Configuration directly into the SpringMVC Configuration. There is no problem in SSM integration. In actual development, the second scheme is often adopted. The configuration of SpringMVC is as follows:

@Configuration
@ComponentScan(basePackages = "org.javaboy")
public class SpringMVCConfig {
}Copy the code
In this scenario, all annotations are scanned in SpringMVC and Spring configuration files can be deleted.

5, test,

Finally, add a HelloController and start the project to test:

@RestController
public class HelloController {
  @GetMapping("/hello")
  public String hello() {
    return "hello"; }}Copy the code
Start the project and access the interface as follows:

Spring Boot Global exception handling

In the Spring Boot project, exceptions are handled uniformly. You can use @ControllerAdvice in Spring to handle exceptions uniformly, or you can define your own exception handling scheme. Spring Boot has some default policies for exception handling, which we’ll look at separately.

By default, the exception page in Spring Boot looks like this:

We can also see from this exception that the user is seeing this page because the developer did not explicitly provide a /error path. If the developer had provided a /error path, the page would not be displayed. Providing the /error path is actually the last resort, and Spring Boot itself will only look for the /error path when all conditions are not met when handling exceptions. So let’s take a look at how to customize error pages in Spring Boot. Generally speaking, there are two types, one is static page, the other is dynamic page.

Static exception page

Custom static exception page is divided into two types. The first type is to use HTTP response code to name the page, such as 404.html, 405.html, 500.html…. , the other is to directly define a 4xx. HTML, indicating that 400-499 states will display the exception page, 5xx. HTML, indicating that 500-599 states will display the exception page.

The default is to define the relevant page in the classpath:/static/error/ path:

At this point, the project is launched, and if the project throws a 500 request error, the 500.html page will be displayed automatically, and if 404 occurs, the 404.html page will be displayed. If the exception display page contains both 5xx. HTML and 500. HTML, the 500. HTML page is displayed first when a 500 exception occurs.

Dynamic exception page

Dynamic exception pages are defined in much the same way as static ones, with page templates such as JSP, Freemarker, and Thymeleaf.

Dynamic exception pages can also support 404.html or 4xx.html, but in general, because dynamic exception pages can display exception details directly, there is no need to enumerate errors one by one. Just define 4xx.html (using the Thymeleaf template here) or 5xx.html.

Note that the dynamic page template does not require the developer to define the controller, but directly define the abnormal page. Spring Boot’s own exception processor will automatically find the abnormal page.

The page definition is as follows:

The page reads as follows:

<! DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<h1>5xx</h1>
<table border="1">
  <tr>
    <td>path</td>
    <td th:text="${path}"></td>
  </tr>
  <tr>
    <td>error</td>
    <td th:text="${error}"></td>
  </tr>
  <tr>
    <td>message</td>
    <td th:text="${message}"></td>
  </tr>
  <tr>
    <td>timestamp</td>
    <td th:text="${timestamp}"></td>
  </tr>
  <tr>
    <td>status</td>
    <td th:text="${status}"></td>
  </tr>
</table>
</body>
</html>Copy the code
By default, the complete exception information is displayed as follows:

If dynamic pages and static page defines the exception handling page at the same time, such as the classpath: / static/error / 404 HTML and classpath: / templates/error / 404 HTML exist at the same time, using dynamic pages by default. A complete error page lookup would look like this:

A 500 error occurred –> Find dynamic 500.html page –> find static 500.html –> Find dynamic 5xx.html–> find static 5xx.html.

Custom exception data

By default, all exception data in Spring Boot is actually the five pieces of data shown above, This article 5 data definition in org. Springframework. Boot. Web. Reactive. Error. DefaultErrorAttributes class, specific definition in getErrorAttributes approach:

@Override
public Map<String, Object> getErrorAttributes(ServerRequest request,
        boolean includeStackTrace) {
    Map<String, Object> errorAttributes = new LinkedHashMap<>();
    errorAttributes.put("timestamp", new Date());
    errorAttributes.put("path", request.path());
    Throwable error = getError(request);
    HttpStatus errorStatus = determineHttpStatus(error);
    errorAttributes.put("status", errorStatus.value());
    errorAttributes.put("error", errorStatus.getReasonPhrase());
    errorAttributes.put("message", determineMessage(error));
    handleException(errorAttributes, determineException(error),
includeStackTrace);
    return errorAttributes;
}Copy the code
The TerrorAttributes class itself is in

Org. Springframework. Boot. Autoconfigure. Web. Servlet. Error. Abnormal ErrorMvcAutoConfiguration automatic configuration class defined in the, Spring Boot will automatically provide an instance of ErrorAttributes, which is TerrorAttributes, if the developer does not provide an instance of ErrorAttributes themselves.

Based on this, developers can customize ErrorAttributes in two ways:

1. Directly implement the ErrorAttributes interface

Inherit TerrorAttributes (recommended) because the handling of exception data in TerrorAttributes is done and developers can use it directly.

Specific definitions are as follows:

@Component
public class MyErrorAttributes  extends DefaultErrorAttributes {
  @Override
  public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean
includeStackTrace) {
    Map<String, Object> map = super.getErrorAttributes(webRequest,
includeStackTrace);
    if ((Integer)map.get("status") == 500) {
      map.put("message"."Server internal error!);
   }
    returnmap; }}Copy the code
ErrorAttributes must be registered as a Bean so that Spring Boot does not use the default TerrorAttributes, which looks like this:

Custom exception view

The default exception view is the static or dynamic page described above. This can also be customized. First of all, Abnormal loading logic view by default in org. Springframework. Boot. Autoconfigure. Web. Servlet. Error. BasicErrorController errorHtml method of class, This method is used to return the exception page + data, and there is another error method, which is used to return the exception data (which is triggered if it is an Ajax request).

@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
public ModelAndView errorHtml(HttpServletRequest request,
        HttpServletResponse response) {
    HttpStatus status = getStatus(request);
    Map<String, Object> model =
Collections.unmodifiableMap(getErrorAttributes(
            request, isIncludeStackTrace(request,
MediaType.TEXT_HTML)));
    response.setStatus(status.value());
    ModelAndView modelAndView = resolveErrorView(request, response, status,
model);
    return(modelAndView ! = null) ? modelAndView : new ModelAndView("error",
model);
}Copy the code
In this method, we first get the exception data through the getErrorAttributes method (which actually calls the getErrorAttributes method of the ErrorAttributes instance), Then call resolveErrorView to create a ModelAndView. If this fails, the user will be presented with a default error page.

Normally, the resolveErrorView method would come to the resolveErrorView method of the DefaultErrorViewResolver class:

@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status,
        Map<String, Object> model) {
    ModelAndView modelAndView = resolve(String.valueOf(status.value()),
model);
    if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
        modelAndView = resolve(SERIES_VIEWS.get(status.series()),
model);
   }
    return modelAndView;
}Copy the code
In this case, the exception response code is used as the view name to search for dynamic and static pages respectively. If none is found, 4xx or 5xx is used as the view name to search for dynamic or static pages respectively.

To custom exception view resolution, is also very easy, because DefaultErrorViewResolver is ErrorMvcAutoConfiguration class provides the instance, the developer does not provide relevant instances, The DefaultErrorViewResolver is used. The default configuration fails when developers provide their own ErrorViewResolver instance, so customising an exception view simply requires providing an instance of ErrorViewResolver:

@Component
public class MyErrorViewResolver extends DefaultErrorViewResolver {
  public MyErrorViewResolver(ApplicationContext applicationContext,
ResourceProperties resourceProperties) {
    super(applicationContext, resourceProperties);
 }
  @Override
  public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus
status, Map<String, Object> model) {
    return new ModelAndView("/aaa/123", model); }}Copy the code
In fact, the developer can also define the exception data here (directly in the resolveErrorView method to redefine a model, copy the model data in the parameter and modify it, note that the model type in the parameter is UnmodifiableMap, That is, it cannot be modified directly) without customizing MyErrorAttributes. After the definition is complete, provide a view named 123 as shown below:

After that, the false attempt is defined as successful.

conclusion

We could actually customize the exception controller, BasicErrorController, but we thought it would be too much of a hassle, and the previous methods would suffice for most of our development needs. If it’s a back-end separation architecture, exception handling and some other options, I’ll talk about that in the future.

The Spring Boot tutorial is a PDF document with more than 200 pages.

Concern public number: programmer chase wind, reply 005 to get this Spring Boot actual combat tutorial.

The last

Welcome everyone to exchange, like the article remember to pay attention to me like yo, thank you for your support!