spring Resolving views

本文介绍了Spring MVC框架中的视图解析器ViewResolver,重点讨论了ContentNegotiatingViewResolver的工作原理及其配置方法。该视图解析器能够根据请求的文件扩展名或Accept头部来选择合适的视图技术。

All MVC frameworks for web applications provide a way to address vies. Spring provides view resolvers, which enable you to render models in a browser without tying you t a specific view technology.Out of the box, Spring enables you to use JSPs,Velocity templates and XSLT views,for example.See Chapter 22,View technologies for a discusstion of how to integrate and use a number of disparate view technologies.
The two interfaces that are important to the way Spring handles views are ViewResolver and View.
The ViewResolver provides a mapping between view names and actual view.The view interface addresses the preparation of the request and hand the request over to one of the view technolgies.

Resolving views with the ViewResolver interface

As discussed in Section 21.3,”Implementing Controllers”,all handler methods in the Spring Web MVC controllers must resolve to a logical view name, either explicity(e.g., by returning a String,View,or ModelAndView)or implicityly(i.e.,based on convetions).Views in Spring are addressed by a logical view name and are resolved by a view resolver.Spring comes with quite a few view resolvers.This table lists most of them; a couple of examples follows.

ViewResolverDescription
AbstractCachingViewResolverAbstract view resolver that caches views.Often views need preparation before they can be used; extending this view resolver provides caching
XmlViewResolverImplementation of ViewResolver that accepts a configuration file written in XML with the same DTD as Spring’s XML bean factories.The default configuration file is /WEB-INF/views.xml
ResourceBundleViewResolverImplementation of ViewResolver that uses bean definitions in a ResourceBundle,specified by the bundle base name.Typically you dfine the bundle in a properties file,located in the classpath.The default file name is views.properties.
ContentNegotiatingViewResolverImplementation of the ViewResolver interface that resolves a view based on the request file name or Accept header.See the section called “ContentNegotiatingViewResolver”.

As an example, with JSP as a view technology,you can use the UrlBasedViewResolver.This view resolver translates a view name to a URL and hands the request over to the RequestDispatcher to render the view.

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

When return test as a logical view name,this view resolver forwards the request to the RequestDispatcher that will send the request to /WEB-INF/jsp/test.jsp.
When you combine different view technologies in a web application, you can use the ResourceBundleViewResolver:

<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="defaultParentView" value="parentView"/>

The ResourceBundleViewResolver inspects the ResourceBundle identified by the basename,and for each view it is supposed to resolve, it uses the value of the property [viewname].url as the view class and the value of the property[viewname].url as the view url.Examples can identify a parent view, from which all views in the properties file “extend”.This way you can specify a default view class, for example.

Note

Subclasses of AbstractCachingViewResolver cache view instances that they resolve.Caching improves performance of certain view technologies.It’s possible to turn off the cache by setting the cache property to false.Furthemore,if you must fefresh a certain view at runtime.

Chaining ViewResolvers

Spring supports multiple view resolvers.Thus you can chain resolvers and, for example,override specific views in certain circumstances.You chain view resolvers by adding more than one resolver to your application context and, if necessary,by setting the order property to specify ordering.Remember,the higher the order property,the later the view resolver is positioned in the chain.
In the following example,the chain of view resolvers consists of two resolvers, an InteranlResourceViewResolver, which is always automatically positioned as the last resolver in the chain, and an XmlViewResolver for specifying Excel views.Excel views are not supported by the InternalResourceViewResolver.

If a specific view resolver does not result in a view,Spring examines the context for other view resolvers.If additional view resolvers exist,Spring continues to inspect them until a view is resolved.If no view resolver returns a view,Spring throws a ServletException.

The contact of a view resolver specifies that a view resolver can return null to indicate the view could not be found.Not all view resolvers do this,however,because in some cases, the resolver simply cannot detect whether or not the view exists.For example,

这是上面关于ViewResolver的介绍,其中我们比较常用到的就是ContentNegotiatingViewResolver。
它处理视图是根据请求的文件名,或者请求当中的Accept header里映射视图的。

ContentNegotiatingViewResolver

The ContentNegotiatingViewResolver does not resolve views itself but rather delegates to other view resolvers,selecting the view that resembles the representation requested by the client.Two strategies exist for a client to request a representation from the server:
- Use a distinct URI for each resource,typically by using a different file extension in the URI. For example,the URI http://www.example.com/users/fred.pdf request a PDF representation of the user fred,and http://www.example.com/users/fred.xml requests an XML representation.
- Use the same URI for the client to locate the resource,but set the Accept HTTP request header to list the media types that it understands.For example, an HTTP request for http://www.example./users/fred with an Accept header set to application/pdf requests a PDF representation of the user fred,while http://www.example.com/users/fred with an Accept header set to text/xml requests an XML representation. This strategy is known as contentnegotiation.
ContentNegotiatingViewResolver并不处理任何视图,而是将处理工作委托给其他视图处理器,或者通过客户端的Accept请求头来决定视图。一般情况下有以下两种请求视图的方式。
通过唯一URI,uri中包含具体的文件类型。
另一种是使用相同的uri,但是通过Accept请求头来判断具体的请求类型。

Note

One issue with the Accept header is that it is impossible to set it in a web browser within HTML.
For example, in Firefox, it is fixed to:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

For this reason it is common to see the use of a distinct URI for each representation when developing browser based web applications.
但是有些浏览器请求html的时候,Accept请求头会加上一系列匹配类型,基于上述原因,在开发web应用的时候会使用唯一URI。

To support multiple representations of a resource, Spring provides the ContentNegotiatingViewResolver to resolve a view based on the file extension or Accept header of the HTTP request.ContentNegotiatingViewResolver does not perform the view resolution itself but instead delegates to a list of view resolvers that you specify throught the bean property ViewResolvers.
为了支持各种不同类型的文件请求,Spring通过ContentNegotiatingViewResolver来解决基于扩展名或者http请求Accept头部类型的文件。它本身并不处理请求,而是将请求的处理,代理给一系列ViewResolvers.

To support custom resolution of a view based on a file extension, use a ContentNegotiationManager: see the section called “Content Negotiation”.
Here is an example configuration of a ContentNegotiatingViewResolver:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
        <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    </property>
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
        </list>
    </property>
</bean>
<bean id="content" class="com.foo.samples.rest.SampleContentAtomView"/>

The InteranlResourceViewResolver handles the translation of view names and JSP pages,while the BeanNameViewResolver returns a view based on the name of a bean.(See “Resolving views with the ViewResolver interface” for more details on how Spring looks up and instantiates a View.)In this example,the content bean is a class that inherits from AbstractAtomFeedView, which returns an Atom RSS feed.For more information on creating an Atom Feed repressentation,see the section Atom Views.

In the above configuration, if a request is made with an .html extension, the view resolver looks for a view that matches the text/html media type.The InternalResourceViewResolver provides the matching view for text/html.If the refquest is made with the file extension .atom, the view resolver looks for a view that matches the application/atom+xml mediat type.This view is provided by the BeanNameViewResolver that maps to the SampleContentAtomView if the view name returned is content.If the request is made with the file extension .json,the MappingJackson2JsonView instance from the DefaultViews list will be selected regardless of the view name.Alternatively,client requests can be made without a file extension but with the Accept header set to the preferred media-type, and the same resolution of request to views would occur.
通过上面的配置,如果一个请求以.html为扩展名,viewresolver就会寻找寻找关联text/html类型的视图。InternalResourceViewResolver提供匹配text/html类型的视图。如果一个请求一个.atom结尾,viewresolver就会寻找application/atom+xml类型的视图。这种视图由BeanNameViewResolver提供,如果视图名称是content,那么视图就会映射到SampleContentAtomView.

Note

if ContentNegotiatingViewResolver’s list of ViewResolvers is not configured explicitly,it automatically uses any ViewResolvers defined in the application context.

<think>好的,用户遇到了模板解析错误的问题,需要帮助解决。首先,我得明确什么是模板解析错误。通常在软件开发中,模板解析错误可能出现在使用模板引擎的时候,比如Thymeleaf、Jinja2或者前端框架如Angular、React等。错误可能由多种原因引起,比如模板路径配置错误、语法错误、变量未定义或类型不匹配,以及依赖缺失或版本不兼容等。 用户提供的引用中有几个相关的信息。引用[3]提到了环境变量未设置导致无法加载数据文件,这可能和模板引擎找不到资源文件有关。虽然用户当前的问题不是Tesseract,但环境变量或路径配置的问题可能类似。引用[2]提到了编译规则中的缩进问题,这可能提示用户检查构建配置文件中的语法是否正确,比如Makefile是否使用了Tab缩进而不是空格。此外,引用[1]讨论了格式字符串的处理,可能与模板中的变量格式化有关,比如日期或数字的格式不正确导致解析错误。 接下来,我需要逐步引导用户排查问题。首先检查模板路径和配置,确保模板文件放在正确的位置,并且应用程序配置的模板目录正确。例如,Spring Boot中Thymeleaf默认查找`src/main/resources/templates`,如果模板放在其他地方,需要配置`spring.thymeleaf.prefix`。然后检查模板语法,比如是否有未闭合的标签、错误的表达式语法或使用了引擎不支持的函数。例如,Thymeleaf中使用`${...}`或`*{...}`时变量是否存在,或者前端框架中是否缺少必要的闭合括号。 接下来是变量和上下文的问题,确保传递给模板的变量名称和类型正确,没有未定义的变量。比如在渲染时是否遗漏了某个模型属性,或者变量名拼写错误。然后是依赖和版本问题,检查模板引擎的依赖是否正确引入,版本是否兼容其他库。比如升级了Spring Boot版本后,Thymeleaf的版本可能需要同步更新。 日志分析也很重要,查看应用程序日志或IDE的控制台输出,通常会有更详细的错误信息,比如具体的行号和错误原因。例如,Thymeleaf会提示哪一行有语法错误,或者变量无法解析。此外,环境变量和缓存问题也可能导致错误,比如开发服务器缓存了旧的模板文件,需要清理缓存或重启服务。某些模板引擎如Thymeleaf在开发模式下默认开启缓存,可以关闭缓存以便实时加载修改。 最后,如果用户能提供具体的错误信息、使用的框架和部分代码示例,可以更精准地定位问题。比如,错误信息是否提到文件不存在、语法错误位置,或者变量未找到等。结合用户之前的引用,尤其是路径配置和环境变量的问题,需要特别检查模板引擎的配置路径是否正确,是否有权限访问,或者文件编码是否导致解析异常。</think>### 模板解析错误解决方案 模板解析错误(Template Resolution Error)常见于Web开发、文档生成或代码编译场景,可能由路径配置、语法错误、依赖缺失或环境问题导致。以下是逐步排查方法: --- #### 1. **检查模板路径配置** - **问题现象**:`Template not found` 或 `Unable to resolve template "xxx"`[^3] - **解决方法**: - 确认模板文件(如HTML、XML)是否位于项目**约定目录**中(例如Spring Boot默认路径为`src/main/resources/templates`) - 检查框架配置文件(如`application.properties`)中的模板路径参数: ```properties # Spring Boot Thymeleaf配置示例 spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html ``` --- #### 2. **验证模板语法** - **常见错误类型**: - **未闭合标签**:`<div>`缺少闭合标签`</div>` - **表达式错误**:模板引擎语法错误(如Thymeleaf中`${user.name}`变量未定义) - **特殊字符转义**:未正确处理`<`, `>`等符号 - **示例**: ```html <!-- Thymeleaf错误示例:变量未定义 --> <p th:text="${undefined_var}"></p> ``` --- #### 3. **检查变量传递** - **关键点**: - 确保后端向模板传递了**所有声明的变量** - 检查变量命名是否与模板中引用的**完全一致**(区分大小写) - **代码示例**: ```java // Spring MVC控制器中需传递变量 model.addAttribute("userName", "John"); // 模板中应使用${userName} ``` --- #### 4. **依赖与版本兼容性** - **典型问题**:模板引擎版本与框架版本冲突(如旧版Thymeleaf与Spring Boot 3.x不兼容) - **解决方法**: - 检查`pom.xml`或`build.gradle`中的依赖声明 - 使用官方推荐的版本组合(如Spring Boot 3.x建议Thymeleaf 3.1.x) --- #### 5. **查看详细错误日志** - **操作步骤**: 1. 在IDE控制台或日志文件中定位错误堆栈 2. 关注`Caused by:`后的根本原因描述 - **示例日志分析**: ``` org.thymeleaf.exceptions.TemplateInputException: Error resolving template "login" ``` 表明系统在解析名为`login`的模板时失败[^3] --- #### 6. **环境变量与缓存问题** - **特殊场景**: - 容器化部署时未挂载模板目录 - 开发服务器缓存旧版模板文件 - **解决方法**: - 清理缓存(如Spring Boot的`/target`目录) - 添加`spring.thymeleaf.cache=false`禁用模板缓存[^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值