ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Spring MVC

2026/8/15 4:06:05 拓冰建站 浏览量
Spring MVC

什么是Spring MVC

官方介绍
  1. Spring MVC是一个Web框架,具有http能力
  2. 构造在Servlet(API)之上的
什么是MVC

MVC是Model View Controller的缩写,他是一种设计模式,将软件系统分为模型,视图和控制器三部分。
image.png
Model:对请求进行处理
Controller:和用户进行交互,对用户请求合理性进行校验
View:返回一个页面给用户

MVC和Spring MVC的关系

MVC是一种设计思想,而Spring MVC是对MVC思想的具体实现。

总结:Spring MVC是一个实现了MVC模式,并继承了Servlet API的Web框架。

学习Spring MVC

学习Spring MVC重点掌握3个功能

  1. 连接功能: 将用户(浏览器)和Java程序连接起来,也就是访问一个地址就能调用我们的Spring程序
  2. 获取参数的功能: 用户访问的时候会带一些参数,在程序中想办法获取到参数
  3. 输出数据的功能: 执行业务逻辑之后,要把程序执行的结果返回给用户
Spring MVC的连接功能

在Spring MVC中使用@RequestMapping来实现URL的路由映射,也就是浏览器连接程序的作用。

@RequestMapping("/test") //一级路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {@RequestMapping("/hi") //二级路由地址public String sayHi() {return "hi Spring MVC";}
}

注意:以前没有前后端分离,所以需要Java程序员也要返回页面(也就是MVC中的视图),随着时代的进步,MVC中的视图被Spring MVC屏蔽了,使用@ResponseBody实现只返回数据的功能。
@RequestMapping既能修饰类也能修饰方法

@RequestMapping 即是get请求也是post请求

image.png
在有些公司对隐私性要求比较高,就会要求不能使用get请求,统一使用post请求,这种情况要怎么处理呢?

@RequestMapping(value = "/hi", method = RequestMethod.POST)

表示当前方法只支持post请求
image.png
除了上面方法还可以通过@PostMapping来实现

获取参数

传递基础类型参数
@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {//表示当前方法只支持post请求@RequestMapping(value = "/hi")public String sayHi(String name, Integer age) {return "hi," + name + " age: " + age;}
}

image.png
参数的位置不用对应,但是参数的名字要对应。

在Spring MVC中传参一定要使用包装类,而非基础类型

因为:当形参是一个基础类型,如果请求中忘记传递这个参数,使用基础类型就会报500错误,而类型包装不会报错,只是值为null
image.png
image.png

后端参数重命名@RequestParam

在某些情况下,前端传递的参数key和后端接收的key可以不一致,比如前端的命名为time,而后端要求要用createtime字段来接收。这样就会出现参数接收不到的情况,为此我们可以使用@RequestParam来重命名前后端的参数值

@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {@RequestMapping("/show-time")public String showTime(@RequestParam("t1") String start, @RequestParam("t2") String end) {return "开始时间:" + start + "| 结束时间:" + end;}
}

image.png
非必传参数设置
如果我们的业务中前端的参数是一个非必传的参数,我们就可以通过设置@RequestParam中的 required=false来避免不传递时报错。

@RequestMapping("/test") //路由地址@Controller //让框架在启动的时候加载当前类,别人才能访问@ResponseBody //让程序返回的是一个数据而不是页面public class TestController {@RequestMapping("/show-time")public String showTime(@RequestParam("t1", required = false) String start, @RequestParam("t2") String end) {return "开始时间:" + start + "| 结束时间:" + end;}
}

image.png

传递对象

如果前端需要传递多个参数,在使用上面的方法就很麻烦要写多个参数,就算你能写多个参数,此时需求要你增加或减少参数,参数那么多就可能造成参数多或参数少,很难发现。此时就需要传递参数来解决。将前端要传的参数包装成一个对象,此时参数就只有这个对象。至于这么多参数怎么变成一个对象是框架帮你完成
image.png

接收JSON对象

使用@RequestBody接收JSON对象,在和第三方系统通讯时的常见场景(双方使用的语言不同,需要通过JSON来进行交互)

@RequestMapping("/test") //路由地址
@Controller //让框架在启动的时候加载当前类,别人才能访问
@ResponseBody //让程序返回的是一个数据而不是页面
public class TestController {@RequestMapping("/json")public String showJson(@RequestBody User user) {return user.toString();}
}

image.png

获取URL的参数 @PathVariable

举个例子:localhost:8080/login?username=zhangsan&password=1234获取参数是从?开始根据key值来获取value。由于?后面的键值对动态改变的,SEO效果比较差.

SEO是一种搜索引擎优化的方式,利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名。

而如果把上面的url写成localhost:8080/login/zhangsan/1234,搜索引擎就会认为这是一个固定地址,SEO效果更佳。那要怎么获取这个url的参数呢?

@RequestMapping("/login/{username}/{password}")//位置一定要正确
public String login(@PathVariable("username") String name,@PathVariable("password") String password) {return name + ": " + password;
}

image.png

上传文件 @RequestPart
@RestController
@RequestMapping("/test")
public class TestController {@RequestMapping("/upfile")public String upfile(@RequestPart("myfile")MultipartFile file) throws IOException {//根目录String path = "D:\\javaee_advanced\\Test.2023.5.30\\";//根目录 + 唯一的文件名(使用UUID生成随机数)path += UUID.randomUUID().toString().replace("-", "");//再加上文件的后缀path += file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//保存文件file.transferTo(new File(path));return path;}
}

使用postman实现上传一个文件
image.png

获取Cookie

在servlet时期,我们是使用HttpServletRequest和HttpServletResponse来获取,在Spring MVC同样适用,可以直接使用。

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/getck")public String getCookie(HttpServletRequest request) {Cookie[] cookies = request.getCookies();for (Cookie item :cookies) {//通过日志来打印log.error(item.getName() + ": " + item.getValue());}return "get cookie";}
}

如果直接输入网址访问,会报空指针异常,所以需要自己造cookie
image.png
image.png
image.png
上面的代码是获取所有的cookie,在Spring mvc中可以使用**@CookieValue **来获取单个cookie

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/getSingleCookie")public String getCookie(@CookieValue("zhangsan") String value) {return "Cookie Value: " + value;}
}

image.png

获取header

使用Servlet时期的HttpServletRequest来实现

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/header1")public String getHeader1(HttpServletRequest request) {String header = request.getHeader("User-Agent");return header;}
}

image.png
在Spring MVC中可以使用 @RequestHeader 实现获取header头。

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/header2")public String getHeader2(@RequestHeader("User-Agent") String header) {return header;}
}

image.png

获取session

使用HttpServletRequest实现session的存和取

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/setsess")public String setSession(HttpServletRequest request) {HttpSession session = request.getSession(true);//没有session就新建session.setAttribute("userinfo", "用户信息");//设置session的键值对return "set session success";}
}

image.png

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/getsess")public String getSession(HttpServletRequest request) {HttpSession session = request.getSession(false);//没有session不新建if(session != null && session.getAttribute("userinfo") != null) {return (String) session.getAttribute("userinfo");}return "暂无session信息";}
}

image.png
在Spring MVC中可以使用 @SessionAttribute获取Session

@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {@RequestMapping("/getsess2")public String getSession2(@SessionAttribute(value = "userinfo", required = false) //设置非必传,防止报500String userinfo) {return userinfo;}
}

image.png

返回数据

返回静态页面
@Controller
@RequestMapping("/resp")
//不添加@Responsebody 表示返回的是页面
public class RespController {@RequestMapping("/index")public Object index() {return "/index.html";}
}

image.png
image.png

返回JSON对象
@Controller
@RequestMapping("/resp")
public class RespController {@RequestMapping("/json")@ResponseBody //表示返回的不是页面,是数据public HashMap<String, String> returnJson() {HashMap<String, String> map = new HashMap<>();map.put("java", "java value");map.put("mysql", "mysql value");map.put("spring", "spring value");return map;}
}

从哈希表变成json格式的操作是框架帮我们完成的
image.png
我们使用Fiddler抓包看看,返回的格式是不是json
image.png

请求转发和请求重定向
  1. forward: 请求转发
  2. redirect: 请求重定向
@Controller
@RequestMapping("/resp")
//不添加@Responsebody 表示返回的是页面
public class RespController {//请求重定向@RequestMapping("/redirect")public String index1() {return "redirect:/index.html";}//请求转发@RequestMapping("/forward")public String index2() {return "forward:/index.html";}
}

image.png
请求转发是服务器帮你转发,转发的地址不发生改变,有可能造成外部资源不能访问的问题。
image.png
而请求重定向是重新定位访问资源,转发的地址会发生改变,和访问新地址效果一样。