Different templates exist at the same time (Jsp, FreeMarker, Thymeleaf)

Template priority

  • FreeMarker view parser priority:
  • Thymeleaf view parser priority:
  • Jsp has the lowest priority

Test code

Create.01 html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>01.html--thymeleaf</h1>
</body>
</html>

Create 02 ftlh:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>02.ftlh--freemarker</h1>
</body>
</html>

Create 03 jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>03.jsp</h1>
</body>
</html>

Put Thymeleaf and FreeMarker templates in the templates directory and jsp files in the webapp directory respectively
Then we write the Controller:

@Controller
public class HelloController {
    @GetMapping("/{path}")
    public String gethello(@PathVariable String path){
        return path;
    }
}

Write configuration class:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/",".jsp");
        //registry.order(1);
    }
}

We put a breakpoint in the ContentNegotiatingViewResolver class:

Thymeleaf and FreeMarker exist at the same time

  • When requested http://localhost:8080/01

  • When requested http://localhost:8080/02

  • When requested http://localhost:8080/03

    FreeMarker and thymeleaf have the same priority. FreeMarker is located a little ahead, so the first step is to traverse the FreeMarker view parser. Due to the checksource method, FreeMarker will check whether the view is available. If it is available, it will be added to the candidate view. When 01 is requested, FreeMarker's checksource method finds that the view is not available, Therefore, it is not added to the candidate view, and then the thymeleaf view parser is traversed. Because thymeleaf does not check whether the view exists, it will be added to the candidate view regardless of whether there is a problem with the view. When 02 is requested, it is found that there is also a thymeleaf view in the candidate view (but this view is problematic and cannot be used), Finally, enter the getBestView method to find the most appropriate view according to the priority of MediaType and template

Jsp and FreeMarker exist at the same time

We change the priority of Jsp to 1, which will be higher than that of FreeMarker

  • When requested http://localhost:8080/01

  • When requested http://localhost:8080/02

  • When requested http://localhost:8080/03


When we request 01, because we remove the thymeleaf dependency, there is no page display; When we request 02, because the priority of Jsp is higher than that of FreeMarker, and because the checksource method of thymeleaf of Jsp always returns TRUE, it will be added to the candidate view regardless of whether there is a problem with the view. Finally, when we enter the getBestView method, Jsp is matched first according to the priority, but the view is not available, so we can't find the page

Thymeleaf and Jsp exist simultaneously

  • When requested http://localhost:8080/01
  • When requested http://localhost:8080/02
  • When requested http://localhost:8080/03

    Because the priority of jsp is lower than that of thymeleaf, which does not check whether the view exists, it will be added to the candidate view regardless of whether there is a problem with the view. Each request has only thymeleaf template, but there is a problem with the view at the time of 03 request, so it cannot be found, so an error is reported

resolvent:
Create HandelInternalResourceViewExist class:

public class HandelInternalResourceViewExist extends InternalResourceView {
    @Override
    public boolean checkResource(Locale locale) throws Exception {
        File file = new File(getServletContext().getRealPath("/") + getUrl());
        return file.exists();
    }
}

Modify Jsp priority:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/",".jsp").viewClass(HandelInternalResourceViewExist.class);
        registry.order(1);
    }
}

Successfully accessed 03:

Thymeleaf, Jsp and FreeMarker exist at the same time

Three templates exist at the same time. You only need to make both templates have detection ability. Similarly, you can coexist by writing the following code
resolvent:
Create HandelInternalResourceViewExist class:

public class HandelInternalResourceViewExist extends InternalResourceView {
    @Override
    public boolean checkResource(Locale locale) throws Exception {
        File file = new File(getServletContext().getRealPath("/") + getUrl());
        return file.exists();
    }
}

Modify Jsp priority:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp("/",".jsp").viewClass(HandelInternalResourceViewExist.class);
        registry.order(1);
    }
}

Keywords: Java FreeMarker JSP Spring Boot Spring MVC

Added by Diego17 on Sun, 20 Feb 2022 05:52:07 +0200