Spring MVC 的创建连接和使用

news2024/12/23 9:04:50

目录

前言:

MVC 是什么?

1. Spring MVC 项目的创建和连接:

1.1 创建

 1.2 连接

2. @RequestMapping 注解使用详析:

2.1 指定请求类型:

2.1.1 指定 GET 请求

2.1.2 指定 POST 请求

3. 参数的获取与传递:

3.1 传递单个参数

3.2 传递对象

3.3 传递多个参数/表单传参(非对象)

3.4 后端参数重命名:

非必传参数的设置

3.5 @RequestBody 接收 JSON 对象

3.6 获取 URL 中的基础参数

3.7 上传文件

3.8 获取 Cookie/Header/Session:

3.8.1 获取 Cookie

3.8.2 获取 Header

3.8.3 Session 的存储和获取

3.9 获取静态页面

3.10 请求转发 和 请求重定向:

二者的区别



前言:

        Spring MVC 原名“Spring Web MVC”,是基于 Servlet API 构建的原始 Web 框架。

MVC 是什么?

        MVC 即 Model View Controller,是一种软件架构模式,可以把软件系统分为模型、视图、控制器三个部分;

  • Model (模型):用于处理应用程序数据逻辑的部分;
  • View(视图):应用程序中处理数据显示的部分;
  • Controller(控制器):应用程序中用于处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

        因此可以认为:Spring MVC 是实现了一个 MVC 模式,并继承了 Servlet API 的 Web 框架。同时 Spring MVC 项目就可以感知到用户在浏览器 URL 里输入的请求。

        学习 Spring MVC 要掌握其主要的三个功能:

  1. 连接的功能:将浏览器和 java 程序连接起来,通过访问一个地址就能调用到对应的 Spring 程序;
  2. 获取参数的功能:在程序中获取用户访问传递的参数;
  3. 输出数据的功能:将执行结果返回给用户;

1. Spring MVC 项目的创建和连接:

1.1 创建:

        Spring MVC 项目的创建和 Spring boot 项目创建步骤一样,只需要添加依赖时加上 “Spring Web” 即可。

 1.2 连接:

        连接既是路由映射,在 Spring MVC 中使用 @RequestMapping 注解来实现与浏览器 URL 的路由映射。访问时直接在浏览器 URL 中访问对于路径即可。

         


2. @RequestMapping 注解使用详析:

        以上只是简单了解了一下使用该注解建立连接,下面剖析该注解的具体使用规则;

        @RequestMapping 用来注册接口路由映射,当用户访问一个 URL 时,将用户的请求对应到程序中某个类的某个方法中。

  •         @RequestMapping 注解可以修饰 [类和方法] ,也可以直接修饰[方法] 。
  •         @RequestMapping 可以指定使用 GET/POST 请求;

2.1 指定请求类型:

2.1.1 指定 GET 请求:

        普通的 @RequestMapping 默认就是发送的 GET 请求;

       △ GET请求的三种写法:

    // GET 请求的三种写法:
    // 第一种:
    @RequestMapping("/request")
    // 第二种:
    @RequestMapping(value = "/request", method = RequestMethod.GET)
    // 第三种:
    @GetMapping("/request")

2.1.2 指定 POST 请求:

       △ POST 请求的两种写法:

// POST 请求两种写法:
    // 第一种:
    @RequestMapping(value = "/request", method = RequestMethod.POST)
    // 第二种:
    @PostMapping("/request")

        


3. 参数的获取与传递:

3.1 传递单个参数:

        在 Spring MVC 中可以直接使用方法中的参数进行传参;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 传递参数
    @RequestMapping("/send")
    public Object sendParam(String username) {
        return "username: " + username;
    }
}

        在 postman 中构造请求:

3.2 传递对象:

         Spring MVC 可以自动将传递的参数赋值给对象;

@Component
@Data
public class Student {
    private int id;
    private String name;
    private int age;
}
@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 传递对象
    @RequestMapping("/send")
    public Object sendObject(Student student) {
        return "student 对象:" + student;
    }
}

        在 postman 中构造请求:

3.3 传递多个参数/表单传参(非对象):

        当有多个参数时,前后端是以参数名来进行参数匹配的,因此参数的位置不会影响后端获取参数的结果。

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/send")
    public Object sendManyParas(String name, String pwd) {
        String user = name + " " + pwd;
        return user;
    }
}

3.4 后端参数重命名:

         当前端给后端传递的参数与后端代码中设置的参数名不一样时,后端就可以通过参数重命名-参数映射来匹配。

        使用 @RequestParam 注解来重命名参数:

        这个例子中,前端传递的参数为 uid,但后端设置与之对应的重命名参数为:username;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/send")
    // 参数重命名
    public Object resetPara(@RequestParam(value = "uid") String username) {
        return "uid : " + username;
    }
}

非必传参数的设置: 

 反过来想:既然后端的参数名为:username,那前端传一个 username 可不可以呢?

 报错 400 了,可见是不行的。因为 @RequestParam 注解重命名意为:后端规定前端必须传一个“uid”的参数,与后端的 username 匹配,进入该注解内部可以看到:

 所以这里报错就是因为我们在没有设置 required 的情况下传了个 username,不是后端规定的“uid”。那么可以通过设置 required 的值来提高前端传参的灵活性,让“uid”变成非必须传递的参数:

 注意:这样只是设置非必须传递的参数,并不代表传的参数可以被匹配到;


3.5 @RequestBody 接收 JSON 对象:

后端接收 Json 对象:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping(value = "/send", method = RequestMethod.POST)
    public Object sendJson(@RequestBody Student student) {
        return "Json 对象:" + student;
    }
}

前端构造 Json 对象:

 如果去掉 @RequestBody,可以拿到 Json 对象但无法接收到Json对象里属性的值:


3.6 获取 URL 中的基础参数:

        使用 @PathVariable 来获取 URL 里 ? 之前的参数:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 获取 URL 键值参数
    @PostMapping("/send/{name}/{password}")
    public Object getURLKV(@PathVariable String name, @PathVariable String password) {
        return "name:" + name + " password:" + password;
    }
}

 注意:

  • @RequestParam:获取 URL 里 ? 之后的参数中的参数;
  • @PathVariable:获取 URL 里 ? 之前基础部分的参数;


3.7 上传文件: 

        上传文件使用 @RequestPart 注解;

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/upload")
    public Object uploadFile(@RequestPart("myfile")MultipartFile file) {
        // 获取文件名
        String fileName = UUID.randomUUID() +
                file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        // 文件保存路径
        File savaFile = new File("D:\\MVCupload\\" + fileName);
        // 保存文件
        try {
            file.transferTo(savaFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

        获取文件名时借助 UUID 和 substring 保证多次上传同一个文件不会导致同名覆盖;

        如果担心上传的文件超过了限制大小,可以在配置文件中设置文件可上传最大量:


3.8 获取 Cookie/Header/Session:

3.8.1 获取 Cookie:

        使用 @CookieValue 注解来获取 cookie:

        这是用来获取单个 Cookie 的方法:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/cookie")
    public Object getCookie(@CookieValue(value = "load", required = false) String load) {
        return "load:" + load;
    }
}

         如果要获取所有的 Cookie,就可以使用传统获取方法,借助 request 对象获取:

    @RequestMapping("/cookie")
    public Object getCookies(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        return cookies;
    }

3.8.2 获取 Header:

        使用 @RequestHeader 注解获取 Header 中的信息:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/header")
    public Object getHeader(@RequestHeader("User-Agent") String userAgent) {
        return "User-Agent:" + userAgent;
    }
}

3.8.3 Session 的存储和获取:

         先按照 HttpServletRequest 存储 Session,再通过 @SessionAttribute 注解获取 Session:

@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
    // 存储 Session
    @RequestMapping("/setSession")
    public void setSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute(SESSION_KEY,"张三");
    }
    private static final String SESSION_KEY = "USER_SESSION";
    // 获取 Session
    @RequestMapping("/getSession")  
    public Object getSession(@SessionAttribute(SESSION_KEY) String name) {
        return "session_name:" + name;
    }
}

         更简洁的方式获取 session:

    @RequestMapping("/session")
    public Object getSession(@SessionAttribute(value = "session", required = false) String session) {
        return session;
    }

3.9 获取静态页面:

         首先在 static 目录下创建一个 index.html 文件:

         

        获取这个静态页面时,一定要注意是 return "/index.html",这个 / 斜杠的作用是从根目录找 index.html 这个静态页面,因为其直接被放在 static 目录下;

        如果这个文件被放在 static 目录下的 index 目录下,就要这样写:return "index.html" ,同时 URL 中路径为:http://localhost:8080/index/index.html

@RequestMapping("/test")
public class TestController {
    @RequestMapping("/index")
    public Object getIndex() {
        return "/index.html";
    }
}


3.10 请求转发 和 请求重定向:

二者的区别:

  1. 定义不同:
       请求转发(Forward):发生在服务端程序内部,当服务端收到客户端发来的请求时,会将请求转发给最终的目的地址,再将目的地址的结果返回给客户端。
       请求重定向(Redirect):服务端接收到客户端的请求之后,会给客户端换返回一个临时响应头,这个临时响应头中记录着客户端需要再次发送请求的 URL 地址,客户端再收到这个新的地址后,就重新向新的地址发送请求。
            形象举例:老大找老二借钱,老二现在没钱,但是老二去找老三借到钱后给老大,这个过程就是“请求转发”,如果老二只是让老大去找老三借钱,这个过程就是“请求重定向”。
  2. 请求方不同:
            请求转发主要是服务端在完成任务,而请求重定向主要是客户端和服务端在不断交互完成任务。
  3. 数据共享不同:
            请求转发的整个执行流程中,服务端带着同一个Request 和 Response 对象完成了所有的交互,所以请求和返回的数据是共享的;而请求重定向每次的请求和返回数据是不同意的。
  4. 最终 URL 地址不同:
    请求转发是服务端作为代理请求去找目的地址,最终将结果再带回来,所以最终的 URL 地址不变;而请求重定向在每次交互中 URL 都在发生改变。
  5. 实现代码不同,具体代码如下。
@Controller
@RequestMapping("/test")
public class TestController {
    // 请求转发
    @RequestMapping("/forward")
    public Object forward() {
        return "forward:/index.html";
    }
}

 请求转发的最终地址还是原请求的地址:

@Controller
@RequestMapping("/test")
public class TestController {
    // 请求重定向
    @RequestMapping("/redirect")
    public Object redirect() {
        return "redirect:/index.html";
    }
}

 请求重定向最终的地址是重定向的地址:

需要注意的:请求转发时,如果资源和转发的页面不在同一个目录下,会导致外部资源不可访问,但 redirect 可以访问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/643254.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTR预估之WideDeep系列模型:DeepFM/DCN

前言 在CTR预估中,FM系列模型使用浅层网络(线性模型),让模型自己学习特征组合交互,为显式建模的方式;而DNN系列模型使用深层网络,隐式挖掘模型的高阶特征交互。 本文继续介绍结合这两者优点的…

在我电脑中待了很久的5款使用办公软件

你电脑中用的最久的软件是哪些?以下是否有你曾经使用过的软件呢?工欲善其事,必先利其器,今天继续分享五款实用的办公软件。 矢量图绘制——Inkscape Inkscape是一款用于绘制和编辑矢量图形的工具。它可以让你用简单的操作来创建…

AI学术交流——“人工智能”和“神经网络学习”

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 目录 前言 一.人工智能 1.“人工智能之父” 2.达特茅斯会议(人工智能起源&a…

2023四大服装管理软件,第1款最受欢迎!

对于服装行业来说,依靠传统的方式管理服装门店或工厂,很难实现精准高效的管理,往往是耗费了大量的时间和精力,也没有挣到什么钱。 这就需要借助服装管理软件,来降低管理和运营的成本,减少工作量的同时&…

自带海量设计模板的网站 精准尺寸一键套用出图

现在大家通过手机去购物时都是通过查看商品的详情页,因为详情页会介绍产品的功能和产品的设计优势等,还有产品的基本信息。那么对于刚接触电商的商家来讲,制作详情页和商品主图是一件困难的事情,但如果套用模板或者是直接选择一个…

vue结合elementui表格el-table实现弹窗checkbox自定义列显示隐藏,刷新保持上次勾选不丢失,附完整代码

el-table实现自定义列显示隐藏 有时候表格太多列,要是默认全都显示就会很拥挤,又不能固定只显示某些列,这时候我们可以让用户自定义要显示隐藏哪些列。 网上很多教程都是用的v-if,但是v-if非常麻烦,每一列都要写判断条件,本篇文章将用动态渲染的方式来控制表格列的显示隐…

【Linux】perf使用和FrameGraph

本文主要说明perf和FrameGraph的使用,例如:火焰图的输出,系统性能状态查看等。 Author:mayimin perf version 3.10.0-1160.80.1.el7.x86_64.debug 参考资料:perf example: https://www.brendangregg.com/perf.html 一…

100天精通Golang(基础入门篇)——第7天:深入学习键盘输入和打印输出,掌握常用函数和包

🌷 博主 libin9iOak带您 Go to Golang Language.✨ 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 🌊 《I…

【UE】滑动UI

效果 步骤 1. 新建一个控件蓝图,这里命名为“WBP_Slide” 2. 在关卡蓝图添加如下节点来显示控件蓝图 3. 打开“WBP_Slide”,添加一个滚动框控件 设置滚动框的锚点 设置滚动朝向为水平 在滚动框中添加一个画布面板 在画布面板中添加一个图像控件 由于我有…

设计优质微信小程序的实用指南!

微信小程序是一种快速发展的应用形式,设计良好的小程序能够提升用户体验并吸引更多的用户。在设计微信小程序时,有一些关键的指南可以帮助我们做出出色的设计。以下是即时设计总结的一些设计指南,希望能对准备设计微信小程序的人有所帮助。 …

64位和32位相比优势是什么(二)

程序的执行过程 当 CPU 执行程序的时候: 1.首先,CPU 读取 PC 指针指向的指令,将它导入指令寄存器。具体来说,完成读取指令这件事情有 3 个步骤: 步骤 1:CPU 的控制单元操作地址总线指定需要访问的内存地…

[CKA]考试之备份还原 etcd

由于最新的CKA考试改版,不允许存储书签,本博客致力怎么一步步从官网把答案找到,如何修改把题做对,下面开始我们的 CKA之旅 题目为: Task 首先,为运行在https://127.0.0.1:2379上的现有 etcd 实例创建快照…

36 # 加载 json 的处理流程

require 源码大致过程 mod.require 会默认调用 require 语法Module.prototype.require 模块的原型上有 require 方法Module._load 调用模块的加载方法,最终返回的是 module.exportsModule._resolveFilename 解析文件名,将文件名变成绝对路径&#xff0c…

UTF是变长编码

在阅读关于UTF8变长编码的文档时,看到如下内容, 文档中1110表示涉及3个字节,10表示涉及一个字节,还有后面的1110高位有三个1,表示从当前字节起有3字节参与表示UNICODE,后面的高位有1个1,表示从当…

Netty实战(十六)

UDP广播事件(二)编写广播者和监视器 一、编写广播者二、编写监视器三、运行 LogEventBroadcaster 和 LogEventMonitor 一、编写广播者 Netty 提供了大量的类来支持 UDP 应用程序的编写。下面我们列出一些要用到的类型: 名 称描 述interface…

价格·歧视

一级价格歧视与耳机价格歧视 价格歧视指的是厂商对于两个完全一样的产品收取不同的价格,无论是对同一消费者还是对不同消费者。 一级价格歧视(完全价格歧视) 对于每一个消费者都收取不同的价格,而且价格定在消费者最多愿意支付的…

基于Java新生报到系统设计与实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

ZooKeeper【客户端命令行】

客户端连接ZooKeeper服务器 启动ZooKeeper集群 ./zkServer.sh start 启动客户端 ./zkCli.sh 我们发现启动客户端时它会默认连接本地的服务器,这是因为zookeeper客户端启动时默认连接的是本地模式。 指定连接集群中的服务器 ./zkServer.sh start -server hadoo…

C语言之结构体讲解

目录 结构体类型的声明 结构体初始化 结构体成员访问 结构体传参 对于上期指针初阶(2)我们后期还会讲数组指针是什么?大家可以先思考一下,后期我们会讲 1.结构体的声明 结构是一些值的集合,这些值被称为成员变量&am…

swagger解析

1.引用swagger包&#xff1a; !-- swagger --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.7.0</version> </dependency> <dependency><groupId>io…