Spring MVC 请求与响应

目录

[一、Spring MVC 请求](#一、Spring MVC 请求)

[1.1 请求映射核心注解:@RequestMapping](#1.1 请求映射核心注解:@RequestMapping)

[1.1.1 作用范围](#1.1.1 作用范围)

[1.1.2 属性详解](#1.1.2 属性详解)

[1.2 请求参数绑定机制](#1.2 请求参数绑定机制)

[1.2.1 绑定规则](#1.2.1 绑定规则)

[1.2.2 特殊场景处理](#1.2.2 特殊场景处理)

[二、Spring MVC 响应](#二、Spring MVC 响应)

[2.1 视图返回机制](#2.1 视图返回机制)

[2.1.1 String类型返回](#2.1.1 String类型返回)

[2.1.2 ModelAndView对象](#2.1.2 ModelAndView对象)

[2.2 JSON数据响应](#2.2 JSON数据响应)

[2.2.1 基础配置](#2.2.1 基础配置)

[2.2.2 对象序列化](#2.2.2 对象序列化)

[2.2.3 集合序列化](#2.2.3 集合序列化)

[2.3 重定向与转发](#2.3 重定向与转发)

[2.3.1 Spring MVC实现](#2.3.1 Spring MVC实现)

[2.3.2 Servlet API实现](#2.3.2 Servlet API实现)

[2.4 文件上传与下载](#2.4 文件上传与下载)

[2.4.1 上传配置](#2.4.1 上传配置)

[2.4.2 控制器实现](#2.4.2 控制器实现)

[2.4.3 文件下载](#2.4.3 文件下载)

[2.5 异常处理机制](#2.5 异常处理机制)

[2.5.1 全局异常处理器](#2.5.1 全局异常处理器)

[2.5.2 注解式异常处理](#2.5.2 注解式异常处理)

[2.6 AJAX交互支持](#2.6 AJAX交互支持)

[2.6.1 前端调用](#2.6.1 前端调用)

[2.6.2 后端配置](#2.6.2 后端配置)

关键总结


Spring MVC作为Java企业级开发的主流框架,其核心在于优雅的请求映射与响应处理机制。本文将基于实战角度,系统梳理Spring MVC的请求处理、参数绑定、响应方式及异常处理等核心知识点。

一、Spring MVC 请求

1.1 请求映射核心注解:@RequestMapping

1.1.1 作用范围

  • 级别:定义一级访问目录
  • 方法级别:定义二级访问目录

1.1.2 属性详解

属性 说明 示例
path/value 定义请求路径 @RequestMapping(path="/delete")
method 指定HTTP方法 @RequestMapping(method=RequestMethod.POST)
params 请求参数限制 @RequestMapping(params="type=admin")
java 复制代码
@Controller
@RequestMapping(path = "/role") // 一级请求路径
public class RoleController {
    /**
     * /role/save
     * method="当前方法允许请求方式能访问"
     * params="请求路径上传参数"
     * @return
     */
   @RequestMapping(path = "/save",method = {RequestMethod.GET})
    public String save(){
        System.out.println("保存角色...");
        return "suc";
    }

    @RequestMapping(value = "/delete")
    public String delete(){
        System.out.println("删除角色...");
        return "suc";
    }
}

1.2 请求参数绑定机制

1.2.1 绑定规则

  • 基本类型:参数名与表单name属性一致
html 复制代码
<input type="text" name="username">
java 复制代码
public String save(String username) { ... }
  • 实体对象:自动映射到JavaBean属性
html 复制代码
<input type="text" name="account.balance">
java 复制代码
public class User {
    private Account account; // 包含嵌套对象
    // getter/setter
}
  • 集合类型:使用索引访问
html 复制代码
<input type="text" name="accounts[0].balance">
java 复制代码
public class User {
    private List<Account> accounts;
}

1.2.2 特殊场景处理

java 复制代码
// 使用@RequestParam显式映射
@RequestMapping("/search")
public String search(@RequestParam("keyword") String searchKey) { ... }

// 处理可选参数
@RequestParam(value="page", required=false, defaultValue="1")

二、Spring MVC 响应

2.1 视图返回机制

Spring MVC通过多种方式实现视图渲染,以下是常见响应方式:

2.1.1 String类型返回

  • 特点
    • 简单易用,自动转义HTML特殊字符
    • 支持JSP、Thymeleaf等模板引擎路径
  • 示例
java 复制代码
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/profile")
    public String showProfile() {
        return "user/profile"; // 返回JSP页面
    }

    @RequestMapping("/data")
    public String returnRawHtml() {
        return "<h1>Hello ${username}</h1>"; // 直接返回HTML(需启用mvc:annotation-driven)
    }
}

2.1.2 ModelAndView对象

  • 适用场景
    • 需要显式传递模型数据
    • 混合使用字符串和对象响应
  • 示例
java 复制代码
@RequestMapping("/search")
public ModelAndView searchUsers(String keyword) {
    List<User> users = userService.search(keyword);
    ModelAndView mv = new ModelAndView();
    mv.addObject("users", users);      // 模型数据
    mv.setViewName("user/list");      // 视图路径
    mv.addObject("keyword", keyword); // 附加数据
    return mv;
}

2.2 JSON数据响应

现代Web应用中,JSON是前后端数据交互的主流格式。Spring MVC通过@ResponseBody注解实现自动序列化。

2.2.1 基础配置

pom.xml添加Jackson依赖:

XML 复制代码
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.0</version>
</dependency>

2.2.2 对象序列化

java 复制代码
@RequestMapping("/user/json")
public @ResponseBody User getUser() {
    User user = new User();
    user.setUsername("jack");
    user.setAge(25);
    return user;
}

响应内容:

javascript 复制代码
{"username":"jack","age":25}

2.2.3 集合序列化

java 复制代码
@RequestMapping("/users/json")
public @ResponseBody List<User> getAllUsers() {
    return userService.getAll();
}

响应内容:

javascript 复制代码
[
    {"username":"jack","age":25},
    {"username":"alice","age":30}
]

2.2.4 自定义JSON格式

使用@JsonFormat控制日期、货币等格式:

java 复制代码
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;

2.3 重定向与转发

2.3.1 Spring MVC实现

  • 重定向 :客户端发起新请求

    java 复制代码
    @RequestMapping("/old/path")
    public String redirect() {
        return "redirect:/new/path";
    }
  • 转发 :服务器端内部跳转

    java 复制代码
    @RequestMapping("/A")
    public String forward() {
        return "forward:/B";
    }

2.3.2 Servlet API实现

java 复制代码
@RequestMapping("/download")
public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // 设置下载头
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", "attachment; filename=report.pdf");
    
    // 写入文件内容
    try (InputStream in = new FileInputStream("reports/report.pdf");
         OutputStream out = response.getOutputStream()) {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }
    }
}

2.4 文件上传与下载

2.4.1 上传配置

spring-mvc.xml中配置多部件解析器:

XML 复制代码
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760"/> <!-- 10MB -->
</bean>

2.4.2 控制器实现

java 复制代码
@RequestMapping(value="/upload", method=RequestMethod.POST)
public @ResponseBody Map<String, String> uploadFile(@RequestParam("file") MultipartFile file) {
    String uploadPath = "/uploads/";
    File dir = new File(uploadPath);
    if (!dir.exists()) dir.mkdirs();
    
    try {
        file.transferTo(new File(uploadPath + file.getOriginalFilename()));
        return Collections.singletonMap("status", "success");
    } catch (IOException e) {
        return Collections.singletonMap("error", "上传失败");
    }
}

2.4.3 文件下载

java 复制代码
@RequestMapping("/download/{filename}")
public void downloadFile(@PathVariable String filename, 
                         HttpServletRequest request, 
                         HttpServletResponse response) throws IOException {
    
    String realPath = request.getSession().getServletContext().getRealPath(
        "/uploads/" + filename
    );
    File file = new File(realPath);
    
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
    
    try (FileInputStream fis = new FileInputStream(file);
         BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) > 0) {
            bos.write(buffer, 0, len);
        }
    }
}

2.5 异常处理机制

2.5.1 全局异常处理器

实现HandlerExceptionResolver接口:

java 复制代码
public class GlobalExceptionHandler implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("error", e.getMessage());
        mv.setViewName("error.jsp");
        return mv;
    }
}

配置:

XML 复制代码
<bean id="exceptionResolver" class="com.example.GlobalExceptionHandler"/>

2.5.2 注解式异常处理

使用@ControllerAdvice@ExceptionHandler

java 复制代码
@ControllerAdvice
public class ExceptionAdvice {

    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    }
}

2.6 AJAX交互支持

2.6.1 前端调用

javascript 复制代码
$.ajax({
    url: '/api/user/123',
    type: 'GET',
    dataType: 'json',
    success: function(user) {
        console.log('用户名:', user.username);
        $('#userInfo').html('<p>年龄: ' + user.age + '</p>');
    },
    error: function(xhr) {
        alert('请求失败: ' + xhr.statusText);
    }
});

2.6.2 后端配置

确保控制器方法返回JSON格式数据:

java 复制代码
@RequestMapping("/api/user/{id}")
public @ResponseBody User getUserById(@PathVariable Long id) {
    return userService.findById(id);
}

关键总结

响应类型 适用场景 优点 缺点
视图返回 传统Web页面渲染 支持模板引擎、SEO友好 不适合API接口
JSON响应 前后端分离架构 轻量级、跨平台兼容性好 需处理JSON序列化/反序列化
重定向 页面跳转、旧版URL兼容 客户端发起新请求 SEO不友好
文件操作 文件上传/下载 直接流式处理 需要复杂配置
异常处理 全局错误统一管理 提升系统健壮性 需要额外配置处理器

通过灵活组合这些响应机制,开发者可以构建出高效、可维护的Spring MVC应用。对于现代SPA(单页应用),推荐主要使用JSON响应配合AJAX交互;而对于传统企业级应用,则更适合视图返回+重定向的混合模式。

相关推荐
江沉晚呤时13 分钟前
深入解析外观模式(Facade Pattern)及其应用 C#
java·数据库·windows·后端·microsoft·c#·.netcore
爱吃鱼饼的猫32 分钟前
【Spring篇】Spring的生命周期
java·开发语言
程序猿大波41 分钟前
基于Java,SpringBoot和Vue高考志愿填报辅助系统设计
java·vue.js·spring boot
m0_740154671 小时前
SpringMVC 请求和响应
java·服务器·前端
橘猫云计算机设计1 小时前
基于Java的班级事务管理系统(源码+lw+部署文档+讲解),源码可白嫖!
java·开发语言·数据库·spring boot·微信小程序·小程序·毕业设计
多多*1 小时前
JavaEE企业级开发 延迟双删+版本号机制(乐观锁) 事务保证redis和mysql的数据一致性 示例
java·运维·数据库·redis·mysql·java-ee·wpf
计算机-秋大田1 小时前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
士别三日&&当刮目相看1 小时前
JAVA学习*String类
java·开发语言·学习
烂蜻蜓2 小时前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
王嘉俊9252 小时前
ReentranLock手写
java·开发语言·javase