问题
在原来的示例中,我们在控制器方法的返回值中直接返回了视图文件所在的路径和名称,这样就使得代码出现了耦合,如果后续视图文件移动位置,那么控制器代码还需要进行修改。
package world.xuewei.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 第一个控制器 * * @author 薛伟 * @since 2023/10/30 16:18 */ @Controller public class IndexController { @RequestMapping("/index") public String index() { System.out.println("Hello World"); return "/index.jsp"; } }
视图解析器
在 Spring MVC 框架中,InternalResourceViewResolver 是一种视图解析器,用于将控制器中返回的逻辑视图名称与实际的物理视图路径匹配。它会将逻辑视图名称映射到 JSP 文件或其他模板引擎支持的模板文件,并返回给客户端以呈现最终的用户界面。
该类主要通过以下两种方式实现视图的解析:
- 使用前缀和后缀来确定物理视图的文件路径。
- 例如,将前缀设置为
/WEB-INF/views/
并将后缀设置为.jsp
,则逻辑视图名称home
将被解析为文件路径/WEB-INF/views/home.jsp
。 - 这种方式可以通过调用 setPrefix() 和 setSuffix() 方法进行配置。
- 将视图名称直接映射到物理视图的文件路径。
- 例如,将逻辑视图名称
home
映射到文件路径/WEB-INF/views/home.jsp
,则直接使用此路径作为视图的物理路径。 - 这种方式可以通过调用
setViewClass()
方法并指定具体的视图类来实现。
在视图解析过程中,InternalResourceViewResolver 还支持以下功能:
- 支持多个视图解析器。
- 如果一个视图解析器无法解析视图,则会依次尝试使用其他视图解析器。
- 要指定多个视图解析器,可以通过调用
setViewResolvers()
方法并传递一个ViewResolver
数组来实现。
- 支持视图缓存。
- 可以将解析后的视图缓存起来,以提高性能和效率。
- 要启用视图缓存,可以通过调用
setCache()
方法并将其设置为 true 来实现。默认情况下,视图缓存是禁用的。
配置视图解析器
配置文件方式
<!-- 引入视图解析器 --> <bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 视图所在路径 --> <property name="prefix" value="/"/> <!-- 文件类型 --> <property name="suffix" value=".jsp"/> </bean>
配置类方式
package world.xuewei.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; /** * Mvc 配置类 * * @author 薛伟 * @since 2023/10/31 10:32 */ @Configuration public class MvcConfig { @Bean public ViewResolver internalResourceViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); // 视图所在路径 viewResolver.setPrefix("/"); // 文件类型 viewResolver.setSuffix(".jsp"); return viewResolver; } }
最终效果
配置完视图解析器,在控制器方法的返回值,我们只需要返回视图的名称即可,可以将上述代码修改为:
package world.xuewei.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * 第一个控制器 * * @author 薛伟 * @since 2023/10/30 16:18 */ @Controller public class IndexController { @RequestMapping("/index") public String index() { System.out.println("Hello World"); return "index"; } }