当前位置: 首页 > news >正文

SSM基础知识-SpringMVC-视图解析(ModelAndView)、方法请求参数接收、方法返回值处理、RESTful 风格、拦截器、全局异常

一、环境准备:项目结构与依赖

1. 项目目录结构

2. 核心依赖(pom.xml)

    <dependencies><!--springmvc依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.5.RELEASE</version></dependency><!-- Jackson JSON处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version><scope>provided</scope></dependency></dependencies>

3. spring-mvc.xml 配置

包含组件扫描、视图解析器、注解驱动、静态资源处理、拦截器:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--这个xml由DispatcherServlet读取--><context:component-scan base-package="com.example"/><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--前缀:视图文件的路径--><property name="prefix" value="/WEB-INF/jsp/" /><!--后缀:视图文件的扩展名--><property name="suffix" value=".jsp" /></bean><!--注解驱动,用于返回json数据或解决其他问题--><mvc:annotation-driven /><!--DispatcherServlet映射是/时,和tomcat内置的DefaultServlet映射/一样(处理静态资源的)导致静态资源无法访问第一种解决方法:由DefaultServlet来处理静态资源<mvc:default-servlet-handler/>第二种解决方案:不依赖tomcat的DefaultServlet<mvc:resources mapping="/static/**" location="/static/" /><mvc:annotation-driven />解决resources和@RequestMapping冲突导致动态资源servlet访问不到--><mvc:resources mapping="/static/**" location="/static/" /><!--拦截器想要触发拦截器,需要满足两个条件1 被DispatcherServlet接收2 满足拦截器设置的url特殊说明:webapp下的jsp页面不会被Spring拦截,spring建议jsp文件放在web-inf下--><!-- 配置拦截器 --><mvc:interceptors><mvc:interceptor><!-- 拦截所有请求(/**:所有层级的请求;/*:仅一级请求) --><mvc:mapping path="/**"/><!-- 排除拦截的请求(可选,如静态资源、登录页) --><!-- <mvc:exclude-mapping path="/static/**"/> --><!-- 自定义拦截器的全路径 --><bean class="com.example.interceptor.OneInterceptor"/></mvc:interceptor></mvc:interceptors></beans>

4. web.xml 配置

配置 Spring MVC 的核心前端控制器 DispatcherServlet,接收所有请求:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0">
<!--DispatcherServlet是一个中央Servlet。负责接收所有请求并分发给不同controller。初始化会执行init(){//创建容器,读取配置文件WebApplicationContext ctx = new ClassPathXmlApplicationContext("spring-mvc.xml");//把容器对象放入到ServletContext中getServletContext().setAttribute(key, ctx);}
--><servlet><servlet-name>myWeb</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>myWeb</servlet-name><url-pattern>/</url-pattern><!--接收所有请求并分发给不同controller--></servlet-mapping>
</web-app>

二、知识点 1:视图解析与 ModelAndView

Spring MVC 中,ModelAndView 是连接 “业务数据” 和 “视图” 的核心类,配合视图解析器可简化页面跳转。

1. 核心代码(OneController.java)

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//知识点1:ModelAndView和视图解析器用法@RequestMapping("/test1")public ModelAndView test1(){ModelAndView mv = new ModelAndView();//相当于request.setAttribute()mv.addObject("msg","test1");//请求转发,用到了视图解析器mv.setViewName("test");/*显示的使用请求转发(视图解析器不起作用)mv.setViewName("forward:/WEB-INF/jsp/test.jsp");显示的使用重定向(视图解析器不起作用),这里不能访问/WEB-INF下的内容,只能请求转发访问mv.setViewName("redirect:/WEB-INF/jsp/test.jsp");框架会把addObject里面的数据存入uri:http://localhost:8080/D03_SpringMVC/WEB-INF/jsp/test.jsp?msg=test1*/return mv;}//方法可以给参数当作原生Servlet用@RequestMapping(value = "/test2")public void test2(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws ServletException, IOException {request.setAttribute("msg","test2");request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request,response);}
}

2. 视图解析器配置(spring-mvc.xml)

在 spring-mvc.xml 中配置 InternalResourceViewResolver,自动拼接视图路径:

<!-- 视图解析器:处理JSP视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 前缀:视图文件所在路径 --><property name="prefix" value="/WEB-INF/jsp/" /><!-- 后缀:视图文件扩展名 --><property name="suffix" value=".jsp" />
</bean>

3. 测试视图(test.jsp)

在 WEB-INF/jsp 下创建 test.jsp,用于渲染 ModelAndView 中的数据:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Spring MVC 测试</title>
</head>
<body><!-- EL表达式获取请求域中的msg数据 --><h3>${msg}</h3>
</body>
</html>

4. 访问测试

  • 访问 http://localhost:8080/项目名/one/test1,页面会显示 test1 - ModelAndView基础用法
  • 核心逻辑:ModelAndView 存数据 → 视图解析器拼接路径 → JSP 渲染数据。

三、知识点 2:原生 Servlet API 与请求参数接收

Spring MVC 支持直接在控制器方法中注入原生 Servlet 对象(HttpServletRequest/HttpServletResponse/HttpSession),同时提供多种参数接收方式,满足不同场景。

1. 原生 Servlet API 注入

直接在方法参数中声明 Servlet 对象,Spring 会自动注入:

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//方法可以给参数当作原生Servlet用@RequestMapping(value = "/test2")public void test2(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws ServletException, IOException {request.setAttribute("msg","test2");request.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(request,response);}
}

2. 多种参数接收方式

(1)参数名与请求参数名一致

直接声明参数,Spring 自动完成类型转换(建议用包装类,避免空指针):

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//http://localhost:8080/D03_SpringMVC/one/test3?num=1//方法行参名和前端传来的name参数名保持一致,数据类型由框架帮你强转,建议使用Integer,匹配不上给null@RequestMapping("/test3")public ModelAndView test3(Integer num){ModelAndView mv = new ModelAndView();mv.addObject("msg",num);mv.setViewName("test");return mv;}
}
(2)参数名与请求参数名不一致(@RequestParam)

用 @RequestParam 指定请求参数名,可控制参数是否必传:

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//http://localhost:8080/D03_SpringMVC/one/test4?num2=1//方法行参名和前端传来的name参数名不一致时,使用value指定name参数名//require=false:未匹配赋null;require=true:未匹配报异常@RequestMapping("/test4")public ModelAndView test4(@RequestParam(value = "num2",required = false) Integer num){ModelAndView mv = new ModelAndView();mv.addObject("msg",num);mv.setViewName("test");return mv;}
}
(3)实体类接收多参数(推荐)

若请求参数较多(如表单提交),可直接用实体类接收,Spring 自动调用 setter 方法赋值:

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//http://localhost:8080/D03_SpringMVC/one/test5?id=1&name=zhangsan//框架根据传来的参数,调用构造函数创建对象和set方法进行赋值@RequestMapping("/test5")public ModelAndView test5(Emp emp){ModelAndView mv = new ModelAndView();mv.addObject("msg",emp);mv.setViewName("test");return mv;}
}

对应的 Emp 实体类:

package com.example.entity;public class Emp {int id;String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Emp() {}public Emp(int id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {return "Emp{" +"id=" + id +", name='" + name + '\'' +'}';}
}

四、知识点 3:控制器方法返回值类型

Spring MVC 支持多种返回值类型,对应不同场景(视图跳转、JSON 响应等),核心是区分 “是否走视图解析器”。

1. 返回值为 String:指定视图名

返回字符串表示逻辑视图名(配合视图解析器),可通过 Model 传递数据:

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//返回值为String(或Object)。表示视图名称(配置了视图解析器就是逻辑名称)@RequestMapping("/test6")public String test6(Model model){//相当于request.setAttribute()model.addAttribute("msg","test6");return "test";}
}

2. 返回值为 void:手动处理响应(适合 AJAX)

返回 void 时,Spring 不处理视图,需手动通过 HttpServletResponse 输出数据(如 JSON):

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//返回值为void。来实现ajax请求@RequestMapping("/test7")public void test7(HttpServletResponse response, Integer id, String name) throws IOException {System.out.println(id+" "+name);ArrayList<Emp> students = new ArrayList<>();students.add(new Emp(1,"zhangsan"));students.add(new Emp(2,"lisi"));ObjectMapper om = new ObjectMapper();String json  = om.writeValueAsString(students);response.setContentType("application/json;charset=utf-8");response.getWriter().println(json);}
}

3. 返回值为 Object + @ResponseBody:自动返回 JSON(推荐)

用 @ResponseBody 注解标记方法,Spring 会自动将返回的 Object 转为 JSON(无需手动处理),且默认设置 Content-Type: application/json

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//返回值为object并配合@ResponseBody注解。表示返回json数据(简化test7)。//自动设置响应头Content-Type为application/json;charset=UTF-8//需在配置文件加注解驱动<mvc:annotation-driven />以及jackson依赖@RequestMapping(value = "/test8")@ResponseBody//表示不走视图解析器,最后调response.getWriter().write()public Object test8(){ArrayList<Emp> students = new ArrayList<>();students.add(new Emp(1,"zhangsan"));students.add(new Emp(2,"lisi"));return students;}
}

 关键配置:需在 spring-mvc.xml 中添加 <mvc:annotation-driven />,启用注解驱动,否则 @ResponseBody 无法自动转换 JSON,以及加入jackson依赖:

<!-- 注解驱动:启用@ResponseBody、@RequestParam等注解,加载消息转换器 -->
<mvc:annotation-driven />

4. 返回值为 String + @ResponseBody:返回纯文本

@ResponseBody 配合 String 返回值,直接返回纯文本,需注意编码(用 produces 指定):

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//返回值为String并配合@ResponseBody注解。表示返回文本数据//Content-Type默认为text/plain;charset=ISO-8859-1。可通过produces指定编码@RequestMapping(value = "test9",produces = "text/plain;charset=utf-8")@ResponseBodypublic String test9() {return "张三";}
}

五、知识点 4:RESTful 风格传参

RESTful 是一种 URL 设计规范,通过 /{参数名} 传递参数,配合 HTTP 方法(GET/POST/PUT/DELETE)表示操作类型,更简洁规范以及达到URL复用。

1. 核心代码

用 @PathVariable 注解获取 URL 路径中的参数,用 @GetMapping 限定 HTTP 方法(替代 @RequestMapping(method = RequestMethod.GET)):

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//restful风格传参(用/分割前端传来变量的值)//不写method标识无论什么请求方式都可以接收//@GetMapping等价@RequestMapping+限定了请求方式为Get。此外还有//@PostMapping(增);@PutMapping(改);@DeleteMapping(删);@GetMapping(查)//http://localhost:8080/D03_SpringMVC/one/test11/zhangsan@RequestMapping(value = "test11/{msg}",method = RequestMethod.GET)@ResponseBodypublic String test11(@PathVariable String msg){return msg;}
}

2. 常用 HTTP 方法注解

注解对应 HTTP 方法作用
@GetMappingGET查询数据(幂等)
@PostMappingPOST新增数据(非幂等)
@PutMappingPUT修改数据(幂等)
@DeleteMappingDELETE删除数据(幂等)

六、知识点 5:拦截器(Interceptor)

拦截器是 Spring MVC 的核心扩展点,用于在请求处理的前、中、后插入自定义逻辑(如登录校验、日志记录),只拦截经过 DispatcherServlet 的请求。

1. 自定义拦截器(OneInterceptor.java)

实现 HandlerInterceptor 接口,重写 3 个核心方法:

package com.example.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class OneInterceptor implements HandlerInterceptor {/*** 1. 预处理:请求到达Controller前执行(核心)* 返回true:放行,继续执行后续流程* 返回false:拦截,后续流程(Controller、postHandle、afterCompletion)不执行*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("-----------------preHandle:请求前拦截-----------------");// 示例:登录校验(未登录则重定向到登录页)/*String username = (String) request.getSession().getAttribute("username");if (username == null) {response.sendRedirect("/login.jsp");return false;}*/return true; // 放行}/*** 2. 后处理:Controller方法执行完、视图渲染前执行* 可修改ModelAndView中的数据和视图*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("-----------------postHandle:视图渲染前-----------------");// 示例:统一给视图添加数据if (modelAndView != null) {modelAndView.addObject("commonMsg", "全局公共信息");}}/*** 3. 完成处理:视图渲染后执行(无论是否异常都会执行)* 常用于释放资源(如关闭流)*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("-----------------afterCompletion:视图渲染后-----------------");}
}

2. 配置拦截器(spring-mvc.xml)

在 spring-mvc.xml 中注册拦截器,指定拦截规则:

<!-- 配置拦截器 -->
<mvc:interceptors><mvc:interceptor><!-- 拦截所有请求(/**:所有层级的请求;/*:仅一级请求) --><mvc:mapping path="/**"/><!-- 排除拦截的请求(可选,如静态资源、登录页) --><!-- <mvc:exclude-mapping path="/static/**"/> --><!-- 自定义拦截器的全路径 --><bean class="com.example.interceptor.OneInterceptor"/></mvc:interceptor>
</mvc:interceptors>

3. 拦截器生效条件

  1. 请求必须经过 DispatcherServlet(即 web.xml 中 DispatcherServlet 的 url-pattern 匹配请求);
  2. 请求路径满足拦截器的 mapping 规则(排除 exclude-mapping 的路径);
  3. 注意:webapp 根目录下的 JSP 直接访问(如 http://localhost:8080/test.jsp)不会被拦截,因为这类请求由 Tomcat 默认 Servlet 处理,未经过 DispatcherServlet,建议将 JSP 放在 WEB-INF 下。

七、知识点 6:全局异常处理(@RestControllerAdvice)

在实际开发中,控制器方法可能抛出异常(如空指针、除零异常),用 @RestControllerAdvice 可统一捕获异常,返回格式化响应(避免给前端暴露错误栈)。

1. 通用响应封装(Result.java)

package com.example.util;/*** 通用响应结果封装(精简版)* 仅保留核心字段和基础方法,便于快速使用* @param <T> 响应数据类型*/
public class Result<T> {// 状态private int code;// 响应消息private String msg;// 响应数据private T data;// 私有构造,通过静态方法创建private Result(int code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}// ================= 成功响应 =================/** 成功(无数据) */public static <T> Result<T> success() {return new Result<>(200, "操作成功", null);}/*** 成功响应(仅自定义消息)*/public static <T> Result<T> success(String message) {return new Result<>(200, message, null);}/** 成功(带数据) */public static <T> Result<T> success(T data) {return new Result<>(200, "操作成功", data);}/** 成功(自定义消息+数据) */public static <T> Result<T> success(String msg, T data) {return new Result<>(200, msg, data);}// ================= 错误响应 =================/** 错误(默认消息) */public static <T> Result<T> fail() {return new Result<>(500, "失败", null);}/** 错误(自定义消息) */public static <T> Result<T> fail(String msg) {return new Result<>(500, msg, null);}/** 错误(自定义状态码+消息) */public static <T> Result<T> fail(int code, String msg) {return new Result<>(code, msg, null);}// getter(无setter,确保不可变)public int getCode() { return code; }public String getMsg() { return msg; }public T getData() { return data; }
}

2. 全局异常处理器(GlobalExceptionHandler.java)

用 @RestControllerAdvice 标记全局异常类,@ExceptionHandler 标记处理特定异常的方法:

package com.example.exception;import com.example.util.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局异常处理器* 作用:捕获 Controller 中抛出的异常,统一格式返回给前端*/
@RestControllerAdvice
public class GlobalExceptionHandler {// 处理未知异常@ExceptionHandler(Exception.class)public Result handleException(Exception e) {e.printStackTrace();return Result.fail(500,"系统异常");}
}

3. 测试异常处理

在控制器中写一个会抛出异常的方法:

package com.example.controller;import com.example.entity.Emp;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
//@RestController注解相当于这个类中的所有方法默认被@ResponseBody修饰
@Controller
@RequestMapping("/one")
public class OneController {//全局异常处理@RequestMapping("test10")@ResponseBodypublic String test10() {int a = 10 / 0;return "";}
}

访问 http://localhost:8080/项目名/one/test10,会返回统一的 JSON 响应:

{"code": 500,"msg": "系统异常","data": null
}

八、总结

本文基于完整的代码案例,覆盖了 Spring MVC 开发中的 6 大核心知识点:

  1. 视图解析ModelAndView 配合视图解析器,简化页面跳转;
  2. 请求参数接收:支持原生 Servlet API、单个参数、实体类接收,满足不同场景;
  3. 返回值处理:区分视图跳转(String/ModelAndView)和数据响应(@ResponseBody);
  4. RESTful 风格:用 @PathVariable 路径传参,更简洁规范;
  5. 拦截器:在请求前、视图渲染前后插入自定义逻辑(如登录校验);
  6. 全局异常@RestControllerAdvice 统一捕获异常,返回格式化响应。
http://www.dtcms.com/a/349684.html

相关文章:

  • UniApp文件上传大小限制问题解决方案
  • Mysql 5.7 与 SqlSugar 5.X 整合开发实战
  • 对线性代数伴随矩阵的深刻理解
  • ComfyUI AI一键换装工作流无私分享
  • 【ansible】6.主机模式以及包含和导入文件
  • Ansible自动化运维介绍与安装
  • 国内代理 IP 的类型:住宅 IP、机房 IP、移动 4G/5G IP 区别
  • 愿景娱乐:践行“流量向善”以公益行动赋能“她”未来
  • RAG(知识库ChatPDF)
  • 开源大模型天花板?DeepSeek-V3 6710亿参数MoE架构深度拆解
  • 无障碍辅助模块|Highcharts引领可访问数据可视化的交流
  • 部分CSS笔试题讲解
  • Python JSON 全方位解析:序列化、反序列化与实战技巧
  • pytest+requests+Python3.7+yaml+Allure+Jenkins+docker实现接口自动化测试
  • k8sday17安全机制
  • flask Celery入门:轻松实现异步任务处理
  • 前端通过node本地转译rtsp流,配合hls实现浏览
  • 【SQL】深入理解MySQL存储过程:从入门到实战
  • CUDA 工具包 13.0 正式发布:开启新一代 GPU 计算的基石!
  • 使用EasyExcel根据模板导出文件
  • QtExcel/QXlsx
  • 深入浅出 Java 多态:从原理到实践的全面解析
  • 【RAGFlow代码详解-5】配置系统
  • 基于深度学习的翻拍照片去摩尔纹在线系统设计与实现
  • UE5 HoudiniPivotPainter1.0使用
  • NFC 滤波网络设计考虑
  • 车载通信架构---通过CANoe做 SOME/IP 模拟的配置例如
  • 库存指标怎么算?一文讲清3大库存分析指标
  • 大数据治理域——离线数据开发
  • 小白成长之路-k8s部署项目(二)