09-SpringMVC视图解析器

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 完整地址

视图解析器的核心价值: 让控制器不需要关心视图的具体位置,实现控制器和视图的分离。

posted on 2025-09-14 21:31  笨忠  阅读(28)  评论(0)    收藏  举报