SpringBoot detailed explanation (middle)

8. Thymeleaf template engine

Template engine

The front-end handed over to us is an html page. If it was developed by us before, we need to convert them into jsp pages. The advantage of jsp is that when we find out some data and forward it to the JSP page, we can use jsp to easily display and interact with the data.

Jsp supports very powerful functions, including the ability to write Java code. However, in our current situation, the SpringBoot project is first in the form of jar, not war. Like the second, we still use embedded Tomcat, so Well, he now does not support jsp by default.
It does not support jsp. If we directly use pure static pages, it will bring great trouble to our development. What should we do?

SpringBoot recommends that you can use a template engine:
In fact, we have heard a lot about template engines. In fact, jsp is a template engine, and there are more useful freemarkers, including Thymeleaf recommended by SpringBoot. There are many template engines, but no matter how many template engines, their ideas are all It's the same, what kind of thinking? Let's take a look at this picture.

The role of the template engine is to write a page template. For example, some values ​​are dynamic, and we write some expressions. And where do these values ​​come from, that is, we encapsulate some data in the background. Then hand over this template and this data to our template engine, the template engine will help you parse and fill the expression into the position we specify according to our data, and then finally generate the content we want from this data and write it out to us , this is our template engine, whether it is jsp or other template engines, it is the idea. It's just that between different template engines, they may have a little different syntax. I won't introduce the others. I will mainly introduce the Thymeleaf template engine recommended by SpringBoot. This template engine is a template engine of a high-level language, and its syntax is simpler. And, it's more powerful.

Let's take a look at this template engine, since we need to look at this template engine. First, let's look at how to use SpringBoot.

9, MVC automatic configuration principle

Official website reading

Before writing the project, we also need to know one thing, which is what configuration SpringBoot has done to our SpringMVC, including how to extend and how to customize.
Only when these are clarified, we will be more handy to use in the future. Path 1: Source code analysis, Path 2: Official documentation!

Let's compare it carefully and see how it is implemented. It tells us that SpringBoot has automatically configured SpringMVC for us, and then automatically configured what?

ContentNegotiatingViewResolver Content Negotiating View Resolver
The ViewResolver is automatically configured, which is the view resolver of SpringMVC we learned earlier;

That is, the view object (View) is obtained according to the return value of the method, and then the view object decides how to render (forward, redirect).

Let's take a look at the source code here: we find WebMvcAutoConfiguration , then search for ContentNegotiatingViewResolver. Find the method below!

@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
// ContentNegotiatingViewResolver uses all other view resolvers to locate views, so it should have higher priority
return resolver;

We can click into this category to see! Find the code for the corresponding parsing view;
@Nullable // Annotation description: @Nullable means the parameter can be null
public View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
if (requestedMediaTypes != null) {
// Get the candidate view object
List candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
// choose the most suitable view object and return this object
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) {
return bestView;

Let's continue to click in and see, how did he get the candidate view?

In getCandidateViews, I saw that he took all the view parsers, performed a while loop, and parsed them one by one!

Iterator var5 = this.viewResolvers.iterator();

So the conclusion is: ContentNegotiatingViewResolver This view resolver is used to combine all view resolvers

Let's study his combination logic again, see that there is an attribute viewResolvers, and see where it is assigned!

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00

phone Contact Us