SpringMVC 响应数据和结果视图:从环境搭建到实战全解析

在 SpringMVC 框架中,响应数据结果视图是连接后端业务逻辑与前端展示的核心环节。无论是页面跳转、数据传递,还是异步 JSON 交互,都需要通过合理的响应方式实现。本文将从开发环境搭建入手,详细讲解 Controller 方法返回值分类、转发与重定向机制,以及 JSON 异步交互的实现,附带完整代码示例与避坑指南,帮助开发者系统掌握 SpringMVC 响应逻辑。

一、开发环境搭建(基础准备)

在实现响应功能前,需先完成 SpringMVC 基础环境配置,包括 Maven 依赖、Web 组件配置和核心配置文件,确保框架能正常运行。

1. Maven 坐标配置(pom.xml)

核心依赖包括 SpringMVC 核心包、Servlet/JSP 支持包,以及后续 JSON 转换所需的 Jackson 依赖。为避免版本冲突,统一锁定 Spring 版本为 5.0.2.RELEASE

XML 复制代码
<properties>
    <!-- 统一 Spring 版本 -->
    <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<dependencies>
    <!-- 1. Spring 核心依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- 2. Servlet/JSP 依赖(scope=provided:服务器已内置,仅编译时用) -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>

    <!-- 3. JSON 转换依赖(后续异步交互用) -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.0</version>
    </dependency>
</dependencies>

2. Web.xml 配置(核心组件)

Web.xml 需配置两个关键组件:中文乱码过滤器 (解决请求 / 响应乱码)和前端控制器 DispatcherServlet(SpringMVC 入口)。

(1)中文乱码过滤器

拦截所有请求,统一设置编码为 UTF-8,避免中文在传递过程中出现乱码。

XML 复制代码
<filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!-- 设置请求编码 -->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <!-- 可选:同时设置响应编码(部分场景需额外配置) -->
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>
(2)前端控制器 DispatcherServlet

作为 SpringMVC 的核心入口,负责接收所有请求并转发到对应的 Controller。需配置 SpringMVC 配置文件路径,并设置服务器启动时初始化(load-on-startup=1)。

XML 复制代码
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 加载 SpringMVC 核心配置文件(classpath 表示类路径下) -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- 服务器启动时初始化(优先级 1,数值越小优先级越高) -->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 拦截所有 .do 结尾的请求(避免拦截静态资源如 CSS/JS) -->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

3. SpringMVC 核心配置(springmvc.xml)

SpringMVC 配置文件需完成注解扫描视图解析器注解驱动静态资源放行四项核心配置,确保 Controller 能被扫描、页面能正确跳转、静态资源不被拦截。

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 1. 注解扫描:仅扫描 Controller 所在包(避免扫描 Service/Dao 层) -->
    <context:component-scan base-package="com.springmvc.controller" />

    <!-- 2. 视图解析器:拼接物理视图路径(逻辑视图名 → 实际页面路径) -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/pages/" /> <!-- 页面所在目录(WebRoot 下) -->
        <property name="suffix" value=".jsp" />    <!-- 页面后缀 -->
        <!-- 示例:逻辑视图名 "suc" → 拼接后:/pages/suc.jsp -->
    </bean>

    <!-- 3. 启用 SpringMVC 注解驱动:让 @RequestMapping、@RequestBody 等注解生效 -->
    <mvc:annotation-driven/>

    <!-- 4. 静态资源放行:避免 CSS/JS/图片被 DispatcherServlet 拦截 -->
    <mvc:resources location="/css/" mapping="/css/**"/>    <!-- 匹配 /css/ 下所有资源 -->
    <mvc:resources location="/images/" mapping="/images/**"/>
    <mvc:resources location="/js/" mapping="/js/**"/>
</beans>

二、Controller 方法返回值分类(核心)

SpringMVC 中,Controller 方法的返回值决定了响应方式,主要分为 String 类型void 类型ModelAndView 类型,不同返回值适用于不同场景。

1. 返回 String 类型(最常用)

核心作用:

返回逻辑视图名 ,通过视图解析器(InternalResourceViewResolver)拼接为物理视图路径(prefix + 逻辑视图名 + suffix),适用于简单的页面跳转场景。

代码示例:
java 复制代码
package com.springmvcy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user") // 类级别的请求路径(统一前缀)
public class UserController {

    // 方法级别的请求路径:完整请求路径为 /user/save1.do
    @RequestMapping("/save1.do")
    public String save1() {
        System.out.println("执行用户保存业务(save1)");
        
        // 返回逻辑视图名 "suc" → 视图解析器拼接为:/pages/suc.jsp
        return "suc";
    }
}
关键注意点:
  • 若返回值以 forward:redirect: 开头(如 return "forward:/pages/suc.jsp"),则不经过视图解析器,直接按指定路径跳转(详见下文 "转发与重定向")。
  • 逻辑视图名需与实际页面目录匹配(如 return "user/list" 对应 /pages/user/list.jsp)。

2. 返回 void 类型

默认行为:

若方法返回 void,SpringMVC 会默认查找 "当前请求路径.jsp" (如请求 /user/save2.do,默认查找 /user/save2.jsp),而该页面通常不存在,会导致 404 错误。因此,返回 void 时需手动通过 HttpServletRequest 或 HttpServletResponse 处理响应

常用场景与代码示例:
java 复制代码
@RequestMapping("/save2.do")
public void save2(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
    System.out.println("执行用户保存业务(save2)");

    // 场景1:请求转发(服务器内部跳转,地址栏不变,可共享 request 数据)
    request.getRequestDispatcher("/pages/suc.jsp").forward(request, response);

    // 场景2:直接响应文本(无需跳转页面,如接口返回简单提示)
    // response.setContentType("text/html;charset=UTF-8"); // 解决响应中文乱码
    // response.getWriter().print("用户保存成功!");

    // 场景3:重定向(客户端跳转,地址栏改变,不可共享 request 数据)
    // response.sendRedirect(request.getContextPath() + "/pages/suc.jsp");
}
关键注意点:
  • 手动处理响应时,需注意中文乱码 :通过 response.setContentType("text/html;charset=UTF-8") 设置响应编码。
  • 重定向时需拼接项目上下文路径(request.getContextPath()),避免路径错误(如 response.sendRedirect(request.getContextPath() + "/pages/suc.jsp"))。

3. 返回 ModelAndView 类型

核心作用:

ModelAndView 是 SpringMVC 提供的 "数据 + 视图" 封装类,可同时存储页面所需数据 (Model)和视图路径(View),适用于 "业务处理后需传递数据到页面" 的场景(如列表查询后传递数据到页面展示)。

代码示例:
java 复制代码
@RequestMapping("/save3.do")
public ModelAndView save3() {
    System.out.println("执行用户保存业务(save3)");

    // 1. 创建 ModelAndView 对象
    ModelAndView mv = new ModelAndView();

    // 2. 存入页面所需数据(相当于 request.setAttribute("msg", "用户名已存在"))
    // 页面可通过 EL 表达式 ${msg} 获取该数据
    mv.addObject("msg", "保存失败:用户名已存在,请更换用户名");
    // 可存入多个数据:mv.addObject("user", new User("张三", 20));

    // 3. 设置逻辑视图名(视图解析器拼接为 /pages/error.jsp)
    mv.setViewName("error");

    // 返回 ModelAndView 对象,SpringMVC 自动处理数据传递与页面跳转
    return mv;
}
关键注意点:
  • mv.addObject() 存入的数据默认存储在 request 域中,生命周期与 request 一致(仅当前请求有效)。
  • 若需长期存储数据(如用户登录信息),需手动将数据存入 session 域(request.getSession().setAttribute("user", user))。

三、SpringMVC 转发与重定向(返回 String 实现)

在实际开发中,页面跳转常需区分 "转发" 和 "重定向",SpringMVC 支持通过返回 String 类型实现这两种跳转方式,无需手动操作 HttpServletRequest/HttpServletResponse。

1. 请求转发(forward:)

核心特点:
  • 服务器内部跳转,地址栏 URL 不变。
  • 可共享 request 域中的数据(如转发前存入的 request.setAttribute("data", xxx) 可在目标页面获取)。
  • 跳转路径可为相对路径或绝对路径,不经过视图解析器
代码示例:
java 复制代码
@RequestMapping("/save4.do")
public String save4() {
    System.out.println("执行用户保存业务(save4)");

    // 方式1:转发到具体页面(绝对路径)
    // return "forward:/pages/suc.jsp";

    // 方式2:转发到其他 Controller 方法(完整请求路径)
    return "forward:/user/findAll.do";
}

2. 重定向(redirect:)

核心特点:
  • 客户端跳转(服务器返回 302 状态码,浏览器重新发起请求),地址栏 URL 改变。
  • 不可共享 request 域数据(因是新请求,原 request 已销毁)。
  • 跳转路径需写绝对路径(通常需拼接项目上下文路径),不经过视图解析器
  • 无法直接访问 WEB-INF 目录下的资源(Tomcat 等服务器禁止客户端直接访问 WEB-INF)。
代码示例:
javascript 复制代码
@RequestMapping("/save5.do")
public String save5() {
    System.out.println("执行用户保存业务(save5)");

    // 方式1:重定向到具体页面(需拼接项目上下文路径,避免路径错误)
    // return "redirect:" + request.getContextPath() + "/pages/suc.jsp";

    // 方式2:重定向到其他 Controller 方法(完整请求路径)
    return "redirect:/user/findAll.do";
}
转发与重定向对比表:
对比维度 请求转发(forward) 重定向(redirect)
跳转方式 服务器内部跳转 客户端跳转(浏览器重新请求)
地址栏 URL 不变 改变
request 数据共享 可共享 不可共享
路径处理 可相对路径,不经过视图解析器 需绝对路径,不经过视图解析器
访问 WEB-INF 可访问(服务器内部跳转) 不可访问(客户端禁止访问 WEB-INF)

四、响应 JSON 数据(异步交互核心)

在前后端分离项目中(如 Vue/React 前端 + SpringMVC 后端),后端通常需返回 JSON 格式数据而非页面。SpringMVC 通过 @RequestBody(接收前端 JSON)和 @ResponseBody(返回 JSON)注解,结合 Jackson 依赖实现 JSON 交互。

1. 核心依赖与注解说明

(1)依赖前提:

需确保已导入 Jackson 相关依赖(见本文 "Maven 坐标配置" 部分),Jackson 负责将 Java 对象转为 JSON 字符串,或反之。

(2)关键注解:
注解 作用 适用位置
@RequestBody 将前端传入的 JSON 字符串转为 Java 对象 Controller 方法参数前
@ResponseBody 将 Java 对象转为 JSON 字符串响应前端 Controller 方法前或类前

2. 实体类准备(User.java)

JSON 转换依赖实体类的 getter 方法(Jackson 通过 getter 读取属性值),需确保实体类实现 Serializable 接口(序列化规范),并提供完整的 getter/setter 方法。

java 复制代码
package com.springmvc.entity;

import java.io.Serializable;

// 实体类:对应前端传递的 JSON 数据结构
public class User implements Serializable {
    private String username; // 用户名
    private Integer age;     // 年龄

    // 无参构造(JSON 反序列化需)
    public User() {}

    // 有参构造(可选)
    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }

    // 必须提供 getter/setter 方法(Jackson 依赖 getter 序列化)
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }

    @Override
    public String toString() {
        return "User{" + "username='" + username + "', age=" + age + "}";
    }
}

3. 前端 AJAX 代码(JSP 页面)

前端通过 AJAX 发送 JSON 数据,并指定 contentType: "application/json;charset=UTF-8",告诉后端 "当前传递的是 JSON 格式数据"。

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>SpringMVC JSON 交互</title>
    <!-- 引入 jQuery(需确保 js 目录已配置静态资源放行) -->
    <script src="/js/jquery.min.js" type="text/javascript"></script>
    <script>
        $(function() {
            $("#btnSubmit").click(function() {
                // 1. 构造 JSON 数据(与后端 User 实体类属性对应)
                let userData = JSON.stringify({
                    "username": "张三",
                    "age": 25
                });

                // 2. 发送 AJAX 请求
                $.ajax({
                    type: "post",                  // 请求方式(JSON 传递需用 post)
                    url: "/user/save6.do",         // 请求路径
                    contentType: "application/json;charset=UTF-8", // 关键:声明请求数据格式为 JSON
                    data: userData,                // 传递的 JSON 数据
                    dataType: "json",              // 期望后端返回 JSON 格式数据
                    success: function(res) {       // 响应成功回调(res 为后端返回的 JSON 对象)
                        alert("用户名:" + res.username + ",年龄:" + res.age);
                    },
                    error: function() {            // 响应失败回调
                        alert("请求失败,请重试!");
                    }
                });
            });
        });
    </script>
</head>
<body>
    <button id="btnSubmit">提交用户数据(AJAX)</button>
</body>
</html>

4. 后端 Controller 代码

通过 @RequestBody 接收前端 JSON 并转为 User 对象,处理业务后,通过 @ResponseBody 将处理后的 User 对象转为 JSON 响应前端。

java 复制代码
@RequestMapping("/save6.do")
// @ResponseBody:将返回的 User 对象转为 JSON 响应前端
@ResponseBody
public User save6(@RequestBody User user) { // @RequestBody:将前端 JSON 转为 User 对象
    System.out.println("接收前端传递的用户数据:" + user); // 打印:User{username='张三', age=25}

    // 模拟业务处理:如修改用户名和年龄
    user.setUsername("张三_已处理");
    user.setAge(user.getAge() + 1);

    // 直接返回 User 对象,@ResponseBody 自动转为 JSON
    return user;
}

5. 关键避坑点:

  • 前端必须指定 contentType: "application/json;charset=UTF-8":否则后端无法识别 JSON 格式,@RequestBody 会解析失败。

  • 实体类必须有 无参构造:Jackson 反序列化(JSON → Java 对象)时需调用无参构造创建对象。

  • 静态资源放行:确保 jQuery 等静态资源已通过 mvc:resources 配置放行,避免 404 错误。

  • 中文乱码:若响应 JSON 包含中文乱码,可在 SpringMVC 配置文件中配置消息转换器(如下):

    XML 复制代码
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

五、核心总结与最佳实践

1. 响应方式选型建议

业务场景 推荐返回值类型 关键技术点
简单页面跳转(无数据传递) String 逻辑视图名 + 视图解析器
页面跳转需传递数据 ModelAndView mv.addObject() 存数据
手动处理响应(如直接输出文本) void HttpServletRequest/HttpServletResponse
页面跳转(转发 / 重定向) String(带 forward:/redirect:) 不经过视图解析器,绝对路径跳转
前后端分离异步交互 Java 对象(配合 @ResponseBody) @RequestBody 接收 JSON,Jackson 转换

2. 核心配置与避坑清单

  • 环境配置:确保 DispatcherServlet 加载 SpringMVC 配置文件,mvc:annotation-driven 已启用。
  • 静态资源:通过 mvc:resources 放行 CSS/JS/ 图片,避免被 DispatcherServlet 拦截。
  • 中文乱码:请求乱码用 CharacterEncodingFilter,响应乱码用 response.setContentType()
  • JSON 交互:导入 Jackson 依赖,确保实体类有 getter / 无参构造,前端指定 contentType: application/json

通过本文的讲解,相信开发者已能掌握 SpringMVC 响应数据与结果视图的核心用法。在实际开发中,需根据业务场景选择合适的响应方式,同时注意配置规范与细节,避免常见错误,提升开发效率与系统稳定性。

相关推荐
ganqiuye1 小时前
向ffmpeg官方源码仓库提交patch
大数据·ffmpeg·video-codec
likuolei2 小时前
XQuery 完整语法速查表(2025 最新版,XQuery 3.1)
xml·java·数据库
越努力越幸运5082 小时前
git工具的学习
大数据·elasticsearch·搜索引擎
不会写程序的未来程序员2 小时前
详细的 Git 操作分步指南
大数据·git·elasticsearch
b***46242 小时前
从 SQL 语句到数据库操作
数据库·sql·oracle
Q***f6352 小时前
后端数据库性能优化的8个工具推荐
数据库·性能优化
Kiri霧2 小时前
Scala 循环控制:掌握 while 和 for 循环
大数据·开发语言·scala
一水鉴天2 小时前
整体设计 定稿 之1 devOps 中台的 结论性表述(豆包助手)
服务器·数据库·人工智能
pale_moonlight2 小时前
九、Spark基础环境实战((上)虚拟机安装Scala与windows端安装Scala)
大数据·分布式·spark