什么是SpringWebMVC

Spring WebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。它的 正式名称“SpringWebMVC”来⾃其源模块的名称(Spring-webmvc),但它通常被称为"Spring MVC".

MVC定义

MVC是ModelViewController的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分
在这里插入图片描述

  • View(视图) 指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源.
  • Model(模型) 是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分.
  • Controller(控制器) 可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型 来处理,以及处理完后需要跳回到哪⼀个视图。即⽤来连接视图和模型

什么是Spring MVC

与另外两者的区别请看这:Spring,Spring Boot 和 Spring MVC 的关系以及区别
MVC是⼀种架构设计模式,也是⼀种思想, ⽽SpringMVC是对MVC思想的具体实现.除此之外, Spring MVC还是⼀个Web框架.

总结来说,SpringMVC是⼀个实现了MVC模式的Web框架.

所以,SpringMVC主要关注有两个点: 1. MVC 2. Web框架

学习Spring MVC

主要分为一下三个方面:

  1. 建⽴连接:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring 程序。

  2. 请求: ⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数, 所以请求这块主要是 获取参数的功能.

  3. 响应: 执⾏了业务逻辑之后,要把程序执⾏的结果返回给用户, 也就是响应.

创建项目

Spring MVC 项目创建和 Spring Boot 创建项目相同,在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。
在这里插入图片描述

建立连接

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

@RequestMapping是什么?

假设有以下代码:

import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
public class TestController {  
    @RequestMapping("/hello")  
    public String hello() {  
        return "hello";  
    }  
}

那么我们通过浏览器访问:http://127.0.0.1:8080/hello 就可以看到程序返回的数据了

@RequestMapping注解介绍

@RequestMapping 是 Spring Web MVC 应⽤程序中最常被用到的注解之⼀,它是用来注册接口的路由映射的.

表示服务收到请求时, 路径为 /hello 的请求就会调用 hello 这个方法的代码

路由映射: 当用户访问⼀个 URL 时, 将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射.

既然如此,为什么要添加@RestController呢

如果我们把RestController去掉,程序会报404,即找不到界面

why?
在我们的项目中,会有很多类,每个类会有很多的方法,Spring会对所有的类进行扫描,如果类存在@RestController注解,Spring才会去扫描类方法里面是否有添加@RequestMapping 这个注解

@RequestMapping使用
  1. @RequestMapping 既可修饰类,也可以修饰方法 ,当修饰类和方法时,访问的地址是类路径 + 方法路径.
  2. 支持GetPost和其他请求方式
    如上代码可以改成:
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  

@RequestMapping("/test")  
@RestController  
public class TestController {  
    @RequestMapping("/hello")  
    public String hello() {  
        return "hello";  
    }  
}

那么我们通过浏览器访问:http://127.0.0.1:8080/test/hello 就可以看到程序返回的数据了

[!IMPORTANT] 注意事项

  1. @RequestMapping的URL 路径最前⾯加不加 / (斜杠)都可以, Spring程序启动时, 会进行判断, 如果前面没有加 / , Spring会拼接上⼀个 /
  2. @RequestMapping支持GET和POST请求,需要显示支持的话可以添加method进行选择:
  • @RequestMapping(value = "/getRequest",method= RequestMethod.POST)
  • 可以点击注释类,查看其源码结构,更清晰易懂

传递参数

传参常见的4种方法介绍here

@RestController  
public class TestController {  
    @RequestMapping("/hello")  
    public String hello(String name) {  
        return name;  
    }  
}

注意事项

  1. 前端与后端传入的参数名字和类型需要相同,除非使用[[@RequestParam]]进行绑定
  2. 使用基本类型来接收参数时, 参数必须传(除boolean类型), 否则会报500错误,类型不匹配时, 会报400错误.
  • 所以在项目开发中,对于参数可能为空的数据,建议使用包装类型

如果参数很多呢?
我们可以把这些参数封装为一个对象

@Data   
public class User {    
    private Long id;  
    private String userName;     
    private String password;  
}
@RestController  
public class TestController {  
    @RequestMapping("/hello")  
    public String hello(User user) {  
        return user.toString();  
    }  
}
  • 这样前端传参的时候就需要用JSON格式进行传参
{

    "id": "1",

    "userName": "12345",

    "password": "12345",

} 
  • Spring 会根据参数名称⾃动绑定到对象的各个属性上, 如果某个属性未传递, 则赋值为null(基本类型则赋值为默认初识值, ⽐如int类型的属性, 会被赋值为0)

传递数组

SpringMVC可以自动绑定数组参数的赋值

使⽤浏览器发送请求并传参,下列请求都是对的

  1. http://127.0.0.1:8080/param/m5?arrayParam=zhangsan&arrayParam=lisi&arrayParam=wangwu

  2. http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu

  3. http://127.0.0.1:8080/param/m5?arrayParam=zhangsan,lisi,wangwu
    此时后端接受代码:

@RestController  
public class TestController {  
    @RequestMapping("/hello")  
    public String hello(String[] strings) {  
        return Arrays.toString(strings);  
    }  
}

当 URL 中需要包含一些特殊字符,例如逗号、空格等,这些字符不能直接放在 URL 中,需要进行 URL 编码。 %2c 就是逗号的 URL 编码。

传递集合

集合参数:和数组类似, 同⼀个请求参数名有为多个, 且需要使⽤ @RequestParam 绑定参数关系
请求方式和数组类似:
⽅式⼀: http://127.0.0.1:8080/param/m6?listParam=zhangsan&listParam=lisi&listParam=wangwu
⽅式⼆: http://127.0.0.1:8080/param/m6?listParam=zhangsan%2clisi%2cwangwu

此时后端接受代码:

public class TestController {  
    @RequestMapping("/hello")  
    public String hello(@RequestParam List<String> listParam) {  
        return "size:"+ listParam.size() + ",listParam:" + listParam; 
    }  
}

传递JSON数据

什么是JSON?

详解:什么是JSON

JSON字符串和Java对象互转
  • JSON本质上是⼀个字符串, 通过⽂本来存储和描述数据

  • Spring MVC框架也集成了JSON的转换⼯具, 我们可以直接使⽤, 来完成JSON字符串和Java对象的互转,内置是通过jackson-databind的依赖进行的转化的

  • 后端在进行接收JSON对象, 需要使⽤@RequestBody注解

public class TestController {  
    @RequestMapping("/hello")  
    public String hello(@RequestBody person) {  
        return person.toString(); 
    }  
}

获取URL中参数@PathVariable

@PathVariable与@RequestParam的区别

  • path variable: 路径变量:即字⾯表达的意思, 这个注解主要作用在请求URL路径上的数据绑定

默认传递参数写在URL上,SpringMVC就可以获取到,如: http://127.0.0.1:8080/param/m8/5/zhangsan

后端代码:

public class TestController {  
    @RequestMapping("/hello/{id}/{name}")  
    public String hello(@PathVariable Integer id,@PathVariable("name") String userName) {  
        return "获取参数, id:" id +", name:" + userName; 
    }  
}

注意点

  1. 如果方法参数名称和需要绑定的URL中的变量名称⼀致时, 可以简写, 不用给@PathVariable的属性赋值, 如上述例子中的id变量
  2. 如果⽅法参数名称和需要绑定的URL中的变量名称不⼀致时, 需要@PathVariable的属性value赋值, 如上述例子中的userName变量

上传⽂件@RequestPart

后端代码实现:

@RequestMapping("/upFile")  
public String getfile(@RequestPart("file") MultipartFile file) throws IOException {  
    //获取文件名称  
    String fileName = file.getOriginalFilename();  
    //文件上传到指定路径  
    file.transferTo(new File("F:/temp/" +fileName));  
    return "接受到的文件名为" +fileName;  
}

练习:图片上传|利用@RequestPart实现图片上传

获取Cookie/Session

什么是Cookie/Session:here

传统方法获取Cookie
@RequestMapping("/m10")
public String method10(HttpServletRequest request,HttpServletResponse response)
{
    // 获取所有 cookie 信息
    Cookie[] cookies = request.getCookies();
    // 打印Cookie信息
    StringBuilder builder = new StringBuilder();
    if (cookies!=null){
        for (Cookie ck:cookies) {
            builder.append(ck.getName()+":"+ck.getValue());
        }
    }
    return "Cookie信息:"+builder;
}
  • httpServlet请求,httpServletResponseServlet 提供的两个类别,是SpringMVC方法的内置对象。需要时直接在方法中添加声明即可。
  • httpServlet 请求对象代表客户端的请求,当客户端通过HTTP协商访问服务器时,HTTP请求
    求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信
    休息。
  • httpServletResponse 对象代表服务器的响应。HTTP响应的信息都在这个对象中,例如向客户
    端发送的数据,响应头,状态码等,通过这个对象提供的方法,可以获得服务器响应的所有内容
  • SpringMVP在这两个对象的基础上进行了封装,为我们提供了更多简单的使用方法。
简洁方法获取Cookie
@RequestMapping("/getCookie")
public String cookie(@CookieValue("bite") String bite) {
    return "bite: " + bite;
}
  • Session是服务器端的机制,我们需要先存储,才能再获取
  • Session也是基于HttpServletRequest 来存储和获取的
Session存储
@RequestMapping("/setSess")
public String setSess(HttpServletRequest request)
{
    HttpSession session = request.getSession();
    if (session != null) {
        session.setAttribute("username", "java");
    }
    return "session 存储成功";
}

这个代码中看不到 SessionId 这样的概念的,getSession 操作内部提取到请求中的Cookie 里的 SessionId,然后根据SessionId获取到对应的Session对象。Session 对象用HttpSession来描述
在这里插入图片描述

获取Session有两种方式

  1. HttpSession getSession(boolean create);
  2. HttpSession getSession();
  • HttpSession getSession(boolean create): 参数如果为 true, 则当不存在会话时新建会话; 参数如果为 false, 则当不存在会话时返回 null
  • HttpSession getSession(): 和getSession(true) 含义一样,默认值为true。
  • void setAttribute(String name, Object value): 使用指定的名称绑定一个对象到该 session 会话
Session读取

读取 Session 可以使用 HttpServletRequest

@RequestMapping("/getSess")
public String getSess(HttpServletRequest request) {
    // 如果 session 不存在,不会自动创建
    HttpSession session = request.getSession(false);
    String username = null;
    if (session != null && session.getAttribute("username") != null) {
        username = (String) session.getAttribute("username");
    }
    return "username: " + username;
}

Object getAttribute(String name): 返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。

简洁获取 Session(1)
@RequestMapping("/getSess2")
public String getSess2(@SessionAttribute(value = "username",required = false)
String username) {
    return "username: "+username;
}
简洁获取 Session(2)

通过Spring MVC内置对象HttpSession 来获取

@RequestMapping("/getSess3")
public String getSess3(HttpSession session) {
    String username = (String)session.getAttribute("username");

    return "username: "+username;
}

HttpSession session = request.getSession();
Session 不存在的话,会自动创建

获取Header

获取Header也是从 HttpServletRequest 中获取

@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
{
    String userAgent = request.getHeader("User-Agent");
    return name + ":" + userAgent;
}

使用HttpServletRequest 提供的getHeader方法来获取,参数对应HTTP请求报头的"Key"

简洁获取 Header
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
    return "userAgent:" + userAgent;
}

@RequestHeader注解的参数值为HTTP请求报头中的"Key"

响应

在我们前⾯的代码例⼦中,都已经设置了响应数据, Http响应结果可以是数据, 也可以是静态⻚⾯,也可以针对响应设置状态码, Header信息等

返回数据@ResponseBody

后端代码:

@Controller  
public class TestController {
	@RequestMapping("/index")  
	@ResponseBody  
	public String returnData(){  
	    return "返回数据";  
	}
}
  • 使用浏览器访问:http://127.0.0.1:8080/returnData,可以看到可以成功返回数据

如果去除@ResponseBody会报404错误,因为此时程序认为需要返回的是视图,根据内容去查找文件,但是查询不到,路径不存在

  • 同时如果在返回的数据中有HTML代码,也会被浏览器进行解析
@Controller  
public class TestController {
	@RequestMapping("/index")  
	@ResponseBody  
	public String returnData(){  
	    return "<h1>返回html数据<h1>";  
	}
}

[!EXAMPLE] 响应中的Content-Type常见取值有以下几种:

  1. text/html: body的数据格式是HTML
  2. text/css: body的数据格式是CSS
  3. application/javascript: body的数据格式是JavaScript
  4. application/JSON: body的数据格式是JSON

返回JSON

后端返回结果为对象:

@Controller  
public class TestController {
	@RequestMapping("/json")  
	@ResponseBody  
	public HashMap<String,String> returnJSON(){  
	    HashMap<String,String> map = new HashMap<>();  
	    map.put("id","1");  
	    map.put("name","doublez");  
	    return map;  
	}
}

设置状态码

Spring MVC会根据我们方法的返回结果自动设置响应状态码,但是也可以手动指定状态码 通过SpringMVC的内置对象HttpServletResponse提供的方法来进⾏设置

@RequestMapping("/status")  
@ResponseBody  
public String setStatus(HttpServletResponse response){  
    response.setStatus(401);  
    return "设置状态码成功";  
}
Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐