Spring MVC核心技术:从请求映射到异常处理

目录

一、@RequestMapping注解深度解析

[1.1 注解的层级映射机制](#1.1 注解的层级映射机制)

[1.2 请求参数绑定技巧](#1.2 请求参数绑定技巧)

二、结果跳转的三重境界

[2.1 ModelAndView方式](#2.1 ModelAndView方式)

[2.2 Servlet API直接操作](#2.2 Servlet API直接操作)

[2.3 SpringMVC语义化跳转](#2.3 SpringMVC语义化跳转)

三、文件上传实战指南

[3.1 配置上传解析器](#3.1 配置上传解析器)

[3.2 文件处理核心代码](#3.2 文件处理核心代码)

[3.3 文件下载实现](#3.3 文件下载实现)

四、异常处理最佳实践

[4.1 局部异常处理](#4.1 局部异常处理)

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

五、性能优化关键点

六、常见问题排查手册

七、最佳实践总结

一、@RequestMapping注解深度解析

RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

RequestMapping注解可以作用在方法和类上

  1. 作用在类上:第一级的访问目录

  2. 作用在方法上:第二级的访问目录

  3. 细节:路径可以不编写 / 表示应用的根目录开始

1.1 注解的层级映射机制

多级路径配置示例

java 复制代码
@Controller
@RequestMapping("/user")  // 一级路径
public class UserController {
    
    @GetMapping("/profile") // 二级路径 -> /user/profile
    public String showProfile() {
        return "user-profile";
    }
}

核心属性详解

属性 说明 使用场景
value/path 定义请求路径 基础路径映射
method 限制HTTP方法类型 RESTful接口设计
params 要求必须包含指定参数 条件性路由处理
headers 校验请求头信息 接口版本控制

1.2 请求参数绑定技巧

(1). 绑定机制

  1. 表单提交的数据都是k=v格式的 username=haha&password=123

  2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的

  3. 要求:提交表单的name和参数的名称是相同的

(2). 支持的数据类型

  1. 基本数据类型和字符串类型

  2. 实体类型(JavaBean)

  3. 集合数据类型(List、map集合等)

基本数据类型和字符串类型

  1. 提交表单的name和参数的名称是相同的

  2. 区分大小写

实体类型(JavaBean)

  1. 提交表单的name和JavaBean中的属性名称需要一致

  2. 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:address.name

给集合属性数据封装

  1. JSP页面编写方式:list[0].属性

基础类型绑定

java 复制代码
@PostMapping("/register")
public String register(
    @RequestParam("uname") String username,
    @RequestParam(value = "age", defaultValue = "18") int userAge) {
    // 业务逻辑
}

复杂对象绑定

html 复制代码
<!-- 表单结构 -->
<input name="address.province">
<input name="address.city">

集合类型处理

java 复制代码
public class OrderForm {
    private List<OrderItem> items;
}

// 前端传参格式
items[0].productId=1001&items[0].quantity=2

二、结果跳转的三重境界

2.1 ModelAndView方式

java 复制代码
@RequestMapping("/detail")
public ModelAndView productDetail() {
    ModelAndView mv = new ModelAndView();
    mv.addObject("product", productService.getById(1001));
    mv.setViewName("product-detail");
    return mv;
}

2.2 Servlet API直接操作

java 复制代码
@RequestMapping("/redirect")
public void directRedirect(HttpServletResponse response) throws IOException {
    response.sendRedirect("/home");
}

@RequestMapping("/forward")
public void directForward(HttpServletRequest request, 
                         HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/views/error.jsp").forward(request, response);
}

2.3 SpringMVC语义化跳转

java 复制代码
// 内部转发
@RequestMapping("/internal")
public String internalForward() {
    return "forward:/api/data";
}

// 外部重定向
@RequestMapping("/external")
public String externalRedirect() {
    return "redirect:https://www.example.com";
}

三、文件上传实战指南

3.1 配置上传解析器

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

3.2 文件处理核心代码

java 复制代码
@PostMapping("/upload")
public String handleFileUpload(
    @RequestParam("file") MultipartFile file,
    HttpServletRequest request) throws IOException {

    String uploadPath = request.getServletContext().getRealPath("/uploads");
    File dest = new File(uploadPath + File.separator + file.getOriginalFilename());
    file.transferTo(dest);
    return "upload-success";
}

3.3 文件下载实现

java 复制代码
@GetMapping("/download")
public void downloadFile(
    @RequestParam String filename,
    HttpServletResponse response) throws IOException {

    File file = new File("/storage/" + filename);
    response.setContentType("application/octet-stream");
    response.setHeader("Content-Disposition", 
                      "attachment; filename=\"" + filename + "\"");
    Files.copy(file.toPath(), response.getOutputStream());
}

四、异常处理最佳实践

4.1 局部异常处理

java 复制代码
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(SQLException.class)
    public ModelAndView handleDatabaseError(SQLException ex) {
        ModelAndView mav = new ModelAndView("error-db");
        mav.addObject("errorMsg", "数据库操作异常:" + ex.getMessage());
        return mav;
    }
}

4.2 全局异常处理器

java 复制代码
@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler,
            Exception ex) {
        
        ModelAndView mav = new ModelAndView("system-error");
        if(ex instanceof BusinessException) {
            mav.addObject("errorCode", ((BusinessException) ex).getErrorCode());
        }
        return mav;
    }
}

五、性能优化关键点

  1. 静态资源配置
XML 复制代码
<mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>

2.异步请求处理

java 复制代码
@Async
@GetMapping("/async-data")
public CompletableFuture<Data> fetchAsyncData() {
    return CompletableFuture.supplyAsync(() -> dataService.getComplexData());
}

3.缓存策略应用

java 复制代码
@Cacheable(value = "products", key = "#id")
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable Long id) {
    return productRepository.findById(id);
}

六、常见问题排查手册

问题1:参数绑定失败

✅ 解决方案:

  • 检查POJO字段命名一致性

  • 使用@DateTimeFormat处理日期格式

  • 验证复杂类型的默认构造函数

问题2:文件上传大小限制

✅ 检查项:

  • 确认multipartResolver配置

  • 检查服务器容器配置(如Tomcat的maxSwallowSize)

问题3:中文乱码问题

✅ 处理方案:

XML 复制代码
<!-- web.xml配置 -->
<filter>
    <filter-name>encodingFilter</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>
</filter>

七、最佳实践总结

  1. 接口设计原则

    • 遵循RESTful风格

    • 使用合适的HTTP状态码

    • 保持URL语义清晰

  2. 安全建议

    • 文件上传时验证文件类型

    • 对下载文件进行权限校验

    • 使用HTTPS传输敏感数据

  3. 性能优化

    • 启用Gzip压缩

    • 使用CDN分发静态资源

    • 合理设置缓存策略

相关推荐
多多*1 分钟前
JavaEE企业级开发 延迟双删+版本号机制(乐观锁) 事务保证redis和mysql的数据一致性 示例
java·运维·数据库·redis·mysql·java-ee·wpf
计算机-秋大田4 分钟前
基于Spring Boot的个性化商铺系统的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
士别三日&&当刮目相看16 分钟前
JAVA学习*String类
java·开发语言·学习
烂蜻蜓24 分钟前
深度解读 C 语言运算符:编程运算的核心工具
java·c语言·前端
王嘉俊92531 分钟前
ReentranLock手写
java·开发语言·javase
my_realmy39 分钟前
JAVA 单调栈习题解析
java·开发语言
高飞的Leo1 小时前
工厂方法模式
java·开发语言·工厂方法模式
5967851541 小时前
C#重写treeView控件
java·c#
小杨4042 小时前
架构系列二十三(全面理解IO)
java·后端·架构
程序员鱼皮2 小时前
2025 年最全Java面试题 ,热门高频200 题+答案汇总!
java·后端·面试