This has nothing to do with Spring MVC testing.
When you don't declare a ViewResolver
, Spring registers a default InternalResourceViewResolver
which creates instances of JstlView
for rendering the View
.
The JstlView
class extends InternalResourceView
which is
Wrapper for a JSP or other resource within the same web application. Exposes model objects as request attributes and forwards the request to the specified resource URL using a javax.servlet.RequestDispatcher.
A URL for this view is supposed to specify a resource within the web application, suitable for RequestDispatcher's forward or include method.
Emphasis mine. In other words, the view, before rendering, will try to get a RequestDispatcher
to which to forward()
. Before doing this it checks the following
if (path.startsWith("/") ? uri.equals(path) : uri.equals(StringUtils.applyRelativePath(uri, path))) {
throw new ServletException("Circular view path [" + path + "]: would dispatch back " +
"to the current handler URL [" + uri + "] again. Check your ViewResolver setup! " +
"(Hint: This may be the result of an unspecified view, due to default view name generation.)");
}
where path
is the view name, what you returned from the @Controller
. In this example, that is preference
. The variable uri
holds the uri of the request being handled, which is /context/preference
.
The code above realizes that if you were to forward to /context/preference
, the same servlet (since the same handled the previous) would handle the request and you would go into an endless loop.
When you declare a ThymeleafViewResolver
and a ServletContextTemplateResolver
with a specific prefix
and suffix
, it builds the View
differently, giving it a path like
WEB-INF/web-templates/preference.html
ThymeleafView
instances locate the file relative to the ServletContext
path by using a
ServletContextResourceResolver
templateInputStream = resourceResolver.getResourceAsStream(templateProcessingParameters, resourceName);`
which eventually
return servletContext.getResourceAsStream(resourceName);
This gets a resource that is relative to the ServletContext
path. It can then use the TemplateEngine
to generate the HTML. There's no way an endless loop can happen here.