JavaEE进阶:Spring Web MVC入门(1)

本篇文章,会带大家学习常见的一些Spring Web MVC注解,通过SpringMVC完成一些基础的功能,并且了解一些企业中的命名规范.

一.了解Spring Web MVC

官方对于Spring Web MVC的描述:

翻译成中文就是:Spring Web MVC是基于Servlet API构建的web框架,包含在SpirngFramework中.命名为 Spring Web MVC,通常也叫做SpringMVC

什么是Servlet API?

简单来说,Servlet 是一套由 Java 提供的规范(接口),用于扩展 Web 服务器的功能,处理客户端(通常是浏览器)发送的 HTTP 请求,并返回响应。

在后面马上就会用到有关servlet API接口,到时候会有更深的理解.

1.MVC的定义:

MVC是ModelViewController的缩写,它是软件工程中的⼀种软件架构设计模式,它把软件系统分

为模型、视图和控制器三个基本部分.

Spring MVC就是对MVC思想的一种具体实现,此外,SpringMVC还是一个Web框架.

所以,SpringMVC关注点有两个:MVC和Web框架.

其实我们在之前创建SpringBoot项目的时候,勾选的SpringWeb框架,就是SpirngMVC框架.

那么SpringBoot和SpringMVC之间有什么关系呢?

SpringBoot可以添加很多依赖,借助这些依赖实现不同的功能,SpringBoot通过添加SpringMVC框架,来实现web功能.

二.学习Spring MVC

既然是web框架,那么当用户在输入URL之后,我们的SpringMVC项目就可以感知到用户的请求,并给予响应.

学习SpirngMVC,主要就是学习如何通过浏览器和用户交互.

主要分为三个方面:

(1).建立连接:将用户的浏览器和Java程序连接起来,也就是访问一个地址就可以调用我们的Spring程序,

(2).请求:用户请求的时候会携带一些参数,在程序中需要获取这些参数,请求这块主要是获取参数的功能.

(3).响应:执行业务逻辑之后,要把执行的结果返回给用户,也就是响应.

对于SpirngMVC来说,学习完以上三个功能,就相当于掌握了SpringMVC

1.项目准备:

在上篇文章中已经提及,在创建SpirngBoot项目的时候,选择SpringWeb就相当于是创建了SpirngWeb项目.

2.建立连接

在SpringMVC中,使用**@RequestMapping**来映射URL路径,也就是浏览器连接程序的作用.

创建一个UserController类,实现用户通过浏览器和程序的交互,代码如下:

java 复制代码
@RestController
public class UserController {
    @RequestMapping("/hello")
    public String hello(){
        return "hello world";
    }
}

接下来,用户只需要在服务器上访问URL,就可以通过服务器访问到我们的java代码

3.@RequestMapping注解介绍

@RequestMapping作为SpringMVC应用程序中最常被用到的注解之一,他是用来注册接口的路由映射的.

表示服务器接收到请求的时候,路径为/hello的请求就会调用到hello()这个方法.

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

那么我们注意到,在@RequestMapping 这个注解前面还有一个@RestController注解.这个注解是什么作用呢?

我们试着把这个注解去掉,看看有什么区别.

去掉@RestController注解,重新启动服务器代码,通过浏览器访问,会出现404.表示找不到该页面.

这就是@RestController注解的作用.

在一个项目中会有很多的类,也会有很多的方法,Spring程序怎么会知道要执行那个方法呢?

这就需要用到@RestController注解了,如果一个类添加了@RestController注解,Spring才会去看这个类里面的方法有没有添加@RequestMapping这个注解.

当然这只是@RestController注解的其中一个作用,剩下的作用会在后面讲解.

(1)@RequestMapping注解的使用

@RequestMapping注解既可以修饰方法,也可以修饰类.当同时修饰方法和类的时候,访问的地址就是类路径+方法路径.

举个例子:在类前面也加上@RequestMapping注解.

那么这个方法的访问路径就是:/request/hello

此时我们访问/hello就会访问不到

要访问http://127.0.0.1:8080/request/hello

通过@RequestMapping注解,帮助我们实现了网络通信,简化了http协议的使用.

在之前,我们学习http相关知识的时候,直到http是由不同的请求方式的,GET请求POST请求等等.

那么我们使用@RequestMapping使用的是哪种类型呢?

在学习http相关知识的时候,我们学习了有关Fiddler抓包工具的使用,我们可以用抓包工具看看.

通过抓包我们可以知道是支持GET请求的.那么我们怎么知道是否支持POST请求呢?

一种方式,我们可以通过form表单来构造一个POST请求,但是这个需要前端的一些知识.

另一种方式,我们可以使用Postman这个工具.

(2)Postman的使用:

可以看到在Postman上面有这么一行.表示的是传参的类型.

1.Params

我们知道在url后面可以跟查询字符串(在http章节讲过).

在Params这下面添加key,value就会自动拼接到URL后面,我们可以通过前面的√选择是否需要这个查询字符串.

例子:

2.Header

在学习HTTP协议的时候,我们知道发送请求里面有哦Header请求头.里面包含了各种信息.

postman作为一个接口测试工具,可以去由程序员自己编写header里面的内容.

3.body

也就是http协议中的body,

none表示没有body.

form-date表示表单提交的数据,什么是表单提交的数据?类似于登入页面,登入的时候需要你输入账号密码等信息,然后通过点击登入按钮,发送这些数据给服务器,这种数据就可以使用form-date来提交,同时还能上传文件.

x-www-form-urlencoded表示键值对经过URL编码,只能上传文本数据,不能上传文件.

raw表示可以上传任意格式的文本,可以上传text,json,xml,html等等.

了解这些之后我们既可以使用postman来发送不同的请求了.

打开Postman,可以创建一个请求,然后输入URL.这里可以选择各种请求类型

选择POST类型,然后输入正确的URL,点击send,就可以和浏览器一样看到效果了.

可以看到这里我们选择POST类型,然后依旧可以正常访问

再试试别的请求类型,结果还是一样,说明@RequestMapping注解可以支持所有类型的请求.

4.如何在请求中传递参数

访问不同的路径,就是发送不同的请求,在发送请求的时候,可能会带有一些参数,所以学习Spring的请求,就是在学习如何传递参数到后端以及后端如何接收.

1.传递单个参数

接收单个参数,我们只需要在Spring MVC中直接用方法中的参数就可以了.我们只需要保持方法中的参数名和URL中查询字符串中的参数名一致即可.

代码:

java 复制代码
    @RequestMapping("/getname")
    public String getname(String name){
        return "name:" + name;
    }

如果我们将name改为name1,这样就会接收不到参数

这里要注意一个点,使用基本类型进行传参的时候,参数必须传(boolean类型除外),否则会报500错误,类型不匹配会报400错误.这是因为基本类型无法接收null值.

java 复制代码
    @RequestMapping("/getage")
    public String getage(int age){
        return "接收到age:" + age;
    }

使用Fidedler抓包,可以发现正常情况下状态码为200,Content-Type类型为text/html.

此时我们不传递age,再试一次.

可以看到此时状态码为500.我们查看服务器代码日志.这里告诉我们age不能为null,可以考虑将其声明为包装类,这时候我们将int改为integer就行

将int改为Interger之后,重新运行代码,发现接收到null值

当我们传递参数不匹配的时候,也会报400错误,

对于包装类来说,如果不传递对应的参数,则会接收到null,所以在企业开发中,对于参数可能为空的数据,建议使用包装类.

2.传递多个参数

传递多个参数的方法和传递单个参数一样,只需要用多个参数接收即可.

java 复制代码
    @RequestMapping("/getuser")
    public String getuser(String name,Integer age){
        return "接收到用户,name:" + name + " age:" + age;
    }

当传递多个参数的时候,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的我盒子不影响后端获取参数的结果.

3.传递对象

创建一个Person对象,传递这个对象.

java 复制代码
    @RequestMapping("/getperson")
    public Person getperson(Person person){
        return person;
    }

和传递多个参数一样,我们只需要将Person的各个属性正确的填进去,就可以传递过去.

Spring会根据参数名称自动绑定到对象的各个属性上,如果某个属性没有传递,则复制为null.基本类型会赋值为默认初始值,比如int默认为0

4.后端参数重命名(后端参数映射)

某些情况下,前端传递的参数名和后端接收用的参数名称不一致,这时候就会出现接收不到的情况,出现这种情况,我们可以使用@RequestParam这个注解来重命名前后端的参数值

比如,现在前端发送过来的数据名叫name,后端用username接收,正常情况是接收不到的.

java 复制代码
    @RequestMapping("/getUsername")
    public String getUsername(String username){
        return "username:" + username;
    }

我们添加@RequestParam注解,括号内填入前端传递的参数名,就可以接收到了.

java 复制代码
    @RequestMapping("/getUsername")
    public String getUsername(@RequestParam("name") String username){
        return "username:" + username;
    }

此时还是一样的URL,我们就可以接收到传递的数据了

此时如果我们在添加@RequestParam注解之后,使用的是原来的参数名username,就会报错

查看后台日志,告诉我们请求所需要的参数"name"不存在,可以得出结论

在我们使用@RequestParam注解重命名之后,请求的参数只能和@RequestParam括号内声明的名称一致,才能进行参数的绑定和赋值.

使用@RequestParam注解进行参数重命名时,参数就变成了必传参数.

通过查看@RequestParam的具体实现,我们可以发现@RequestParam注解有四个属性.分别是value,name,required,defaultValue

通过代码注解可以知道,required表示这个参数是否是必传参数,我们可以更改值来让他变成非必传参数.

当我们将上面的注释内容进行更改,然后使用一样的URL传递参数,可以发现这时候不会报错,而是会接收到null值.

也就是说,我们添加required = false之后,依然要用@RequestParam注解括号内的value或者name值进行参数传递,只是这个时候如果不传递参数,不会报错.只会接收到null值

java 复制代码
    @RequestMapping("/getUsername")
    public String getUsername(@RequestParam(value = "name",required = false) String username){
        return "username:" + username;
    }

5.传递数组

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

后端实现代码:

java 复制代码
    @RequestMapping("/getarr")
    public String getarr(String[] arr){
        return Arrays.toString(arr);
    }

前端传递:

有多种URL传递数组的方式,一种就是下面这种

还可以:

还可以下面这样,%2c就是代表逗号:

URL编码对应表:

6.传递集合:

传递集合和传递数组类似,同一个请求的参数有多个**,但是与数组不同的是,传递集合需要使用@RequestParam绑定参数关系.**

默认情况下,请求中参数名相同的多个值,是封装到数组,如果要封装到集合,需要@RequestParam绑定参数关系.

7.传递JSON数据:

传递JSON数据,需要使用@RequestBody注解

java 复制代码
    @RequestMapping("/getPerson")
    public String getPerson(@RequestBody Person person){
        return "person:" + person;
    }

使用Fiddler抓包看看,可以看到这边请求是application/json.

当我们去掉@Requestbody注解,看看效果.后端未收到结果.

8.获取URL中的参数@PathVariable

PathVariable:路径变量,这个注解的作用就是在请求URL路径上的数据绑定.

通过URL中{}里面的变量名获取值,PathVariable括号中的值要跟URL中的名称保持一致,后面的UserId则是后端使用的变量名,可以一致,也可以不一致.

java 复制代码
    @RequestMapping("/getPathVariable/{id}/{name}")
    public String getPathVariable(@PathVariable("id") Integer UserId, @PathVariable("name") String UserName){
        return "id:" + UserId + " name:" + UserName;
    }

9.上传文件@RequestPart

java 复制代码
    public String getFile(@RequestParam("file") MultipartFile file) throws IOException {
        //获取到文件名称
        String fileName = file.getOriginalFilename();
        //保存文件到新的位置
        file.transferTo(new File("D:/" + fileName));
        return "接收到file" + fileName;
    }

获取到原来的文件名,上传到新的位置.使用Postman发送请求.

可以看到在我们预想的路径下出现了该文件.

10.获取Cookie和Session

在我们学习HTTP协议的时候,我们知道HTTP协议自身是属于"无状态"协议.

也就是说默认情况下的HTTP通信这次通信和下次通信之间是没有直接的联系.

但是在实际开发中,我们是需要知道请求之间的关联关系的.

所以这时候就需要Cookie和Session了.

什么是Cookie?

简单来说,Cookie是服务器让浏览器在客户端保存的一小段文本数据.用来作为身份标识.

比如,在我们登入一个网站的时候,第一次登入浏览器会给一个Cookie值,就比如Set-Cookie: user_id=abc123,然后这个Cookie值就会存在浏览器这边,下次这个再次访问这个网站,浏览器就会带着这个Cookie值去访问服务器,服务器就知道是哪个用户了.

就好比上面这个流程,Cookie就相当于是令牌.

Session是什么呢?

Session是服务器为每一个客户端创建的一个服务端数据存储,用来记住用户的状态.它的本质是一个哈希表,存储了一些键值对,Key就是SessionID,Value就是用户信息.

用户登入成功,服务器会生成一个唯一的SessionID,服务器会把用户的信息保存在自己的数据库中,然后服务器把SessionID通过Cookie发送给浏览器,这个Cookie的key一般叫JSESSIONID 或者叫PHPSESSID.浏览器后续请求都会带上这个Cookie,然后服务器收到请求会去数据库找对应用户的数据.

Cookie和Session的区别:

1.Cookie 是客户端保存用户信息的一种机制. Session 是服务器端保存用户信息的一种机制.

2.Cookie 和 Session 之间主要是通过 SessionId 关联起来的,SessionId 是 Cookie 和 Session 之间的桥梁.

3.Cookie 和 Session 经常会在一起配合使用。但是不是必须配合.完全可以用 Cookie 来保存一些数据在客户端。这些数据不一定是用户身份信息,也不一定是 SessionId.Session 中的 sessionId 也不需要非得通过 Cookie/Set-Cookie 传递,比如通过 URL 传递

1.获取Cookie

我们知道SpringMVC是基于servletAPI构建的web框架,HttpServletRequest,HttpServletResponse是Servlet提供的两个类,可以拿到Http里面的各种数据.

java 复制代码
    @RequestMapping("/getCookie")
    public String getCookie(HttpServletRequest request, HttpServletResponse response){
        //获取到请求中的Cookie信息.
        Cookie[] cookies = request.getCookies();
        //通过循环打印Cookie信息
        StringBuffer sb = new StringBuffer();
        if(cookies != null){
            for (Cookie cookie : cookies) {
                sb.append(cookie.getName() + ":" + cookie.getValue() + " ");
            }
        }

        return "cookie:" + sb.toString();
    }

运行程序,我们会发现啥也没有,这是因为这里面的Cookie是空的,这时候我们可以去添加几对cookie

重新运行程序,就可以拿到这里面的cookie值.

还有更加简单的获取cookie的方法:
通过@CookieValue注解的方式获取,在括号内加入Cookie的key值.如果不存在默认情况下会抛出异常.可以通过制定required = false来避免这个异常.

java 复制代码
    @RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue(value = "cookie1") String cookie1){
        return "cookie:" + cookie1;
    }

当我们删掉这个Cookie,就会报400.

改动代码,让required = false

java 复制代码
    @RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue(value = "cookie1",required = false) String cookie1){
        return "cookie:" + cookie1;
    }

就会显示null

2.存储和获取Session

Session是服务器端的机制,我们需要先存储,才能获取.

设置Session:

java 复制代码
    @RequestMapping("setSession")
    public String setSession(HttpServletRequest request, HttpServletResponse response){
        //先获取到Session
        HttpSession session = request.getSession();
        session.setAttribute("session1","session1");
        return "session:" + session.getAttribute("session1");
    }

获取session:

java 复制代码
    @RequestMapping("getSession")
    public String getSession(HttpServletRequest request, HttpServletResponse response){
        HttpSession session = request.getSession();
        return "获取到session1:" + session.getAttribute("session1");
    }

通过@SessionAttribute注解获取Session

java 复制代码
    @RequestMapping("getSession2")
    public String getSession2(@SessionAttribute(value = "session1",required = false) String session1){
        return "获取到session1:" + session1;
    }

通过SpringMVC内置对象HttpSession来获取

java 复制代码
    @RequestMapping("getSession3")
    public String getSession3(HttpSession session){
        String key = "session1";
        return "获取到session1:" + session.getAttribute(key);
    }

11.获取Header

传统获取Header:

java 复制代码
    @RequestMapping("getHeader")
    public String getHeader(HttpServletRequest request, HttpServletResponse response){
        String value = request.getHeader("User-Agent");
        return "获取到User-Agent:" + value;
    }

通过Fiddler抓包对比,观察结果是否正确

通过@RequestHeader注解简洁获取Header,括号内的参数值为请求报头中的key.

java 复制代码
    @RequestMapping("getHeader2")
    public String getHeader2(@RequestHeader(value = "User-Agent") String userAgent){
        return "获取到User-Agent:" + userAgent;
    }
相关推荐
暗不需求2 小时前
React新手小白:如何入门 React 响应式交互与 JSX 艺术
前端·react.js
前端缘梦2 小时前
深入理解React Fiber架构:渲染流程与双缓冲机制全解析
前端·react.js·面试
砍材农夫2 小时前
spring-ai 第十二mcp server调用入门(http协议)
人工智能·spring·http
尘埃落定wf2 小时前
2026 年 LangChain (记忆)Memory 怎么用?三个核心类 + 完整代码示例
开发语言·前端·python
952362 小时前
SpringMVC
后端·学习·spring
Maic2 小时前
用AI写了一个命理应用
前端
一叶飘零_sweeeet2 小时前
Spring AI 与 Spring AI Alibaba怎么选?
java·spring·spring ai
毛骗导演2 小时前
Claude Code REPL.tsx 架构深度解析
前端·架构
Mike_jia2 小时前
AllinSSL:SSL证书自动化管理的终极利器,让HTTPS部署再无烦恼
前端