1. 什么是视图解析器?一个生动的比喻 🏷️
想象一下你要寄信:
- 你只写"张三收"(就像控制器返回
"index_1") - 邮局帮你补充完整地址:北京市/海淀区/中关村大街1号/张三收
- 这样邮递员就能准确找到目的地了
视图解析器就是这个"邮局",它把简单的视图名补充成完整的文件路径。
2. 视图解析器的工作原理 🔍
看看你提供的代码:
@Controller
public class SixController {
@RequestMapping("/test1.do")
public String tet1(){
return "index_1"; // 这只是个"简短地址"
}
}
配合XML配置:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/html/"/> <!-- 补充"省份" -->
<property name="suffix" value=".html"/> <!-- 补充"城市" -->
</bean>
最终效果:
- 控制器返回:
"index_1" - 视图解析器加工:
/html/+index_1+.html=/html/index_1.html - SpringMVC会自动转发到这个完整的HTML文件
3. 为什么要用视图解析器? 🤔
没有视图解析器时:
@Controller
public class OldController {
@RequestMapping("/old.do")
public String oldMethod(){
return "/WEB-INF/views/user/profile.jsp"; // 要写完整路径
}
}
问题:
- 代码冗长
- 修改文件位置时要改很多代码
- 容易出错
使用视图解析器后:
@Controller
public class NewController {
@RequestMapping("/new.do")
public String newMethod(){
return "user/profile"; // 只需写简洁的视图名
}
}
优点:
- ✅ 代码简洁
- ✅ 修改方便(只需改配置)
- ✅ 不易出错
4. 如何配置视图解析器? 🛠️
方式1:XML配置(经典方式)
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 设置前缀:视图文件所在的目录 -->
<property name="prefix" value="/WEB-INF/views/"/>
<!-- 设置后缀:视图文件的扩展名 -->
<property name="suffix" value=".jsp"/>
<!-- 可选:设置视图类(用于JSTL等) -->
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
</bean>
方式2:Java配置(现代方式)
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
5. 实际应用示例 🎯
示例1:JSP页面
配置:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
控制器:
@Controller
public class UserController {
@RequestMapping("/user/info")
public String userInfo() {
return "user/info"; // → /WEB-INF/jsp/user/info.jsp
}
@RequestMapping("/product/list")
public String productList() {
return "product/list"; // → /WEB-INF/jsp/product/list.jsp
}
}
示例2:HTML页面(如你的配置)
配置:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/html/"/>
<property name="suffix" value=".html"/>
</bean>
控制器:
@Controller
public class PageController {
@RequestMapping("/home")
public String home() {
return "index"; // → /html/index.html
}
@RequestMapping("/about")
public String about() {
return "company/about"; // → /html/company/about.html
}
}
6. 注意事项 ⚠️
1. 文件位置要正确
如果配置了prefix = "/WEB-INF/views/",那么你的JSP文件必须放在:
项目目录/
└── WEB-INF/
└── views/
├── index.jsp
└── user/
└── profile.jsp
2. 与重定向/转发的区别
@Controller
public class ExampleController {
// 使用视图解析器(默认转发)
@RequestMapping("/normal")
public String normal() {
return "page"; // → 转发到 /WEB-INF/views/page.jsp
}
// 重定向(不使用视图解析器)
@RequestMapping("/redirect")
public String redirect() {
return "redirect:/new/page"; // → 重定向,不经过视图解析器
}
// 显式转发(不使用视图解析器)
@RequestMapping("/forward")
public String forward() {
return "forward:/other/page"; // → 转发,不经过视图解析器
}
}
3. 多个视图解析器
如果需要多个视图解析器,可以设置order属性:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
<property name="order" value="2"/> <!-- 数字越大优先级越低 -->
</bean>
7. 常见问题及解决方案 ❓
问题1:404错误(页面找不到)
原因: 文件路径不正确
解决: 检查prefix配置和实际文件位置是否匹配
问题2:视图解析器不生效
原因: 配置有误或冲突
解决: 检查配置文件和组件扫描设置
问题3:中文乱码
解决: 确保JSP页面设置了正确的编码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
8. 总结 🎯
| 概念 | 说明 | 比喻 |
|---|---|---|
| 视图解析器 | 将简短视图名转换为完整路径 | 邮局补充地址 |
| prefix | 视图文件的前置路径 | 省份+城市 |
| suffix | 视图文件的扩展名 | 街道+门牌号 |
| 返回值 | 控制器返回视图名 | 只写"收件人姓名" |
| 最终路径 | prefix + 视图名 + suffix | 完整地址 |
视图解析器的核心价值: 让控制器不需要关心视图的具体位置,实现控制器和视图的分离。
浙公网安备 33010602011771号