【Spring MVC】

目录

🍮1 什么是 MVC ?

🎁2 Spring MVC 的连接

🍘2.1 @RequestMapping 实现 POST 和 GET 请求

🥣2.2 @GetMapping 只支持 GET 请求

🫖2.3 @PostMapping 只支持 POST 请求

🍬3 Spring MVC 获取参数的功能

🍩3.1 传递单个参数

😚3.2 传递对象

🍟3.3 后端参数重命名

🍭3.4 获取 json 对象

🧃3.5 获取 URL 中参数 @PathVariable

🍳3.6 上传文件 @RequestPart

😎3.7 获取 cookie

🍉3.8 获取 session

🍖3.9 获取 header

🍱4 Spring MVC 输出数据的功能

🎑 5. 请求转发与请求重定向的区别


1 什么是 MVC ?

MVC 全称 Model View Controller,是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。

 MVC 的作用是将软件用户界面与业务逻辑分离,从而使代码变得更加容易维护、更加易于复用,灵活性更强。总的来说就是,View 层是界面,Model 层是业务逻辑,Controller 层用来调度 View 层以及 Model 层,是用户界面与业务逻辑沟通的桥梁。

实现逻辑是这样子的:View 提交数据给 Model,让它实现某一具体逻辑,但在 MVC 中,View 不会直接就交给 Model,而是交给了 Contrller,让 Contrller 转交给 Model。乍一看,还觉得复杂了。但如果有一天,旧的业务逻辑不再适用了呢,此时只需要在 Controller 中将原来的 Model 替换成新的 Model 就可以,旧的依旧可以保留。Controller 起到中转站的作用,将不同的 View 转到对应的 Model 中。

MVC 是一种思想,而 Spring MVC 是对 MVC 的具体实现,是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。

市面上绝大多数的 Java 项目是基于 Spring 或 Spring Boot 的,而 Spring MVC 就是 Spring 的核心框架,可以说 Spring MVC 是一切项目的基础,这也是我们学习 Spring MVC 的一个重要原因。

2 Spring MVC 的连接

路由映射:当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类或某个类的某个⽅法的过程。

2.1 @RequestMapping 实现 POST 和 GET 请求

package com.example.demo.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/sayhi")
    public String sayHi(){
        return "你好 Spring MVC";
    }
}

@RequestMapping 是 Spring Web 中最常⽤到的注解之⼀,它是⽤来注册接⼝的路由映射的。

@RequestMapping 即可修饰类,也可以修饰⽅法,当修饰类和⽅法时,访问的地址是类 + ⽅ 法。 @RequestMapping 也可以直接修饰⽅法,此时直接写方法地址即可。

 

 

如果想要规定 @RequestMapping 只支持 Post 请求,那么就得加参数了。

package com.example.demo.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping(path = "/sayhi", method = RequestMethod.POST)
    public String sayHi(){
        return "你好 Spring MVC";
    }
}

 

 由于浏览器的默认方法是 GET 请求,所以浏览器也请求失败了。

 

package com.example.demo.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping(path = "/sayhi", method = RequestMethod.GET)
    public String sayHi(){
        return "你好 Spring MVC";
    }
}

 

2.2 @GetMapping 只支持 GET 请求

@GetMapping("/sayhi2")
    public String sayHi2(){
        return "Hey You!";
    }

 等价于上面的 @RequestMapping(path = "/sayhi", method = RequestMethod.GET)

2.3 @PostMapping 只支持 POST 请求

@PostMapping("/sayhi3")
    public String sayHi3(){
        return "Yo Ho~~ Beauty~";
    }

等价于上面的 @RequestMapping(path = "/sayhi", method = RequestMethod.POST)

3 Spring MVC 获取参数的功能

3.1 传递单个参数

package com.example.demo.Controller;

import com.example.demo.Model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test2")
public class TestController2 {
    // 传递单个参数
    @RequestMapping("/single")
    public String wordOfFamily(String word){
        return word;
    }
}

3.2 传递对象

package com.example.demo.Model;

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private String password;
    private int age;
}

package com.example.demo.Controller;

import com.example.demo.Model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test2")
public class TestController2 {
    // 传递对象
    @RequestMapping("/user")
    public User userMessage(User user){
        return user;
    }
}

 

也可以使用 form 表单提交。

 

3.3 后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,⽐如前端传递了⼀个 time 给后端,⽽后端⼜是有 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值。

    // 后端参数重命名
    @RequestMapping("/name")
    public String name(@RequestParam(value = "time") String createtime ){
        return createtime;
    }

上⾯的列⼦,如果我们是前端传递⼀个⾮ time 的参数,就会出现程序报错的情况。这是因为后端已经声明了前端必须传递⼀个 time 的参数,但是前端没有给后端传递,我们查看 @RequestParam 注解的实现细节就可以发现端倪,注解实现如下:

required 必须的意思,默认值为 true,前端一定要传递指定参数,否则就会 400 报错。

如果我们的实际业务前端的参数是⼀个⾮必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,具体实现如下:

    // 后端参数重命名
    @RequestMapping("/name")
    public String name(@RequestParam(value = "time", required = false) String createtime ){
        return createtime;
    }

 

3.4 获取 json 对象

使用 RequestBody 来获取 json 对象,只能用来修饰参数。

    // 接收 json 格式
    @RequestMapping("/user_json")
    public User userJson(@RequestBody User user){
        return user;
    }

 

看过上面的那么多例子,会发现框架会根据输入的参数类型,返回相应的格式。如果是 html 呢?

    @RequestMapping("/html")
    public String html(){
        return "<h1>hello html<h1>";
    }

 

 

3.5 获取 URL 中参数 @PathVariable

之前是通过 URL 参数部分去获取参数的,这一部分讲解从 URL 地址部分/非参数部分获取参数。比如下面的稀土掘金:

 最后的那串数字是文章的 id,但不是使用以前的那种写法 ?id=7269952188927017015

    // URL非参数部分获取参数
    @RequestMapping("/detail/{id}")
    public Integer detail(@PathVariable("id") Integer id){
        return id;
   }

// URL 获取多个参数
    @RequestMapping("/detail2/{id}/{name}")
    public String detail2(@PathVariable Integer id, @PathVariable String name){
        return "id = "+id+" name = "+name;
    }

3.6 上传文件 @RequestPart

上传文件使用 POST 请求。

    // 上传文件
    @RequestMapping("upload")
    public String upload(@RequestPart("myfile")MultipartFile file) throws IOException {
        String path = "C:\\image\\img.png";
        //保存文件
        file.transferTo(new File(path));
        return path;
    }

 所有上传的图片都会被命名成 img.png ,可不可以更加灵活的处理保存上传图片并命名呢?

生成唯一的 id,一定使用 UUID。觉得 UUID 中的 - 很难看,可以去掉。UUID 是全球唯一 id。

UUID = 网卡+随机数+随机种子+加密算法

保证其唯一性

// 上传文件修改版本
    @RequestMapping("upload")
    public String upload1(@RequestPart("myfile")MultipartFile file) throws IOException {
        // 1. 生成一个唯一的 id | UUID 
        String name = UUID.randomUUID().toString().replace("-","");
        // 2. 得到源文件的后缀名
        // 对完整文件名进行截取
        name += (file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")));
        String path = "C:\\image" + name ;
        //保存文件
        file.transferTo(new File(path));
        return path;
    }

3.7 获取 cookie

// 获取 Cookie
    @RequestMapping("/getcookie")
    public String cookie(@CookieValue(value = "java", required = false) String ck){
        return ck;
    }

3.8 获取 session

    // 设置 Session
    @RequestMapping("/set_session")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        if(session != null){
            session.setAttribute("SESSION_KEY", "栗子");
            return "session set successes";
        }else{
            return "session set fails";
        }
    }

    /**
     * 获取 Session
     */
    @RequestMapping("/get_session")
    public String getSession(@SessionAttribute(required = false, value = "SESSION_KEY") String name){
        return name;
    }

 

3.9 获取 header

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

4 Spring MVC 输出数据的功能

package com.example.demo.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TestController3 {
    @RequestMapping("/index")
    public String index(){
        return "hello.html";
    }
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h1>hello, I'm a hello page~~</h1>
</body>
</html>

 早期的 Spring MVC 前端不分离,后端会给前端返回一个 html 的网页,如今前后端分离了,后端只负责给前端传递数据,这就用到了 @ResponseBody 这个注解。

package com.example.demo.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@ResponseBody
public class TestController3 {
    @RequestMapping("/index")
    public String index(){
        return "hello.html";
    }
}

 5. 请求转发与请求重定向的区别


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

创建本地镜像

通过前面文章的阅读&#xff0c;读者已经了解到所谓的容器实际上是在父镜像的基础上创建了一个可读写的文件层级&#xff0c;所有的修改操作都在这个文件层级上进行&#xff0c;而父镜像并未受影响&#xff0c;如果读者需要根据这种修改创建一个新的本地镜像&#xff0c;有两种…

Smartbi电子表格软件版本更新,首次推出Excel轻应用和语音播放

Smartbi电子表格软件又又又更新啦&#xff01; 此次更新&#xff0c;首次推出了新特性——Excel轻应用和语音播报。另外&#xff0c;还对产品功能、Demo示例、配套文档进行了完善和迭代。 低代码开发Excel轻应用 可实现迅速发布web应用 业务用户的需求往往都处于“解决问题”…

APP调用bindService的跨进程调用过程

app执行bindService时会经过如下8次跨系统进程调用过程&#xff1a; 第1步&#xff1a;通过AMS.getService跨进程调用 第2步&#xff1a;AMS返回它的IBinder 第3步&#xff1a;通过AMS的IBinder调用AMS的bindService方法 第4步&#xff1a;而AMS存放有Server端的IBinder&…

ChatGPT在医疗系统的应用探索动态

注意&#xff1a;本信息仅供参考&#xff0c;发布该内容旨在传递更多信息的目的&#xff0c;并不意味着赞同其观点或证实其说法。 生成式人工智能&#xff0c;如OpenAI开发的ChatGPT&#xff0c;被认为是可以颠覆医疗行业的工具。尽管该技术刚刚起步&#xff0c;但已有许多医…

Vue2向Vue3过度Vuex核心概念mutations

目录 1 核心概念-mutations1.定义mutations2.格式说明3.组件中提交 mutations4.练习5.总结 2 带参数的 mutations1.目标&#xff1a;2.语法2.1 提供mutation函数&#xff08;带参数&#xff09;2.2 提交mutation 3 练习-mutations的减法功能1.步骤2.代码实现 4 练习-Vuex中的值…

kettle实现爬虫

步骤概览 获取请求 请求地址 东方财富网股票请求 自定义常量数据 获取HTTP请求之前&#xff0c;必须先定义一个URL常量作为HTTP client的输入 HTTP client 注&#xff1a;此处得到的数据并不是原生的json字符串&#xff0c;自己可以用文本文件输出测试以下。如下图 JavaScri…

Vue2向Vue3过度核心技术路由

目录 1 路由介绍1.思考2.路由的介绍3.总结 2 路由的基本使用1.目标2.作用3.说明4.官网5.VueRouter的使用&#xff08;52&#xff09;6.代码示例7.两个核心步骤8.总结 3 组件的存放目录问题1.组件分类2.存放目录3.总结 4 路由的封装抽离5 Vue路由-重定向1.问题2.解决方案3.语法4…

谈谈子网划分的定义、作用、划分方式以及案例

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、子网划分的定义 二、子网掩码的作用 1、…

林业气象站——林业种植气象观测

林业气象站是一种用于观测林区气象环境的仪器&#xff0c;能够观测林区天气、土壤等自然环境参数&#xff08;温度、湿度、风速、风向、降雨量、气压、放射线、土壤湿度等&#xff09;&#xff0c;为开展环境观测、天气预报、灾害预警、林区虫害防治起到综合指导作用。 林业气…

Unity中的数学基础——贝塞尔曲线

一&#xff1a;前言 一条贝塞尔曲线是由一组定义的控制点P0到 Pn&#xff0c;n1为线性&#xff0c;n2为二次......第一个和最后一个控制点称为起点和终点&#xff0c;中间的控制点一般不会位于曲线上 获取两个点之间的点就是通过线性插值&#xff08; Mathf.Lerp&#xff09…

基于Python+djangoAI 农作物病虫害预警系统智能识别系统设计与实现(源码&教程)

1.背景 随着科技的发展&#xff0c;机器学习技术在各个领域中的应用越来越广泛。在农业领域&#xff0c;机器学习技术的应用有助于提高农作物的产量和质量&#xff0c;降低农业生产的成本。本文针对农作物健康识别问题&#xff0c;提出一种基于机器学习方法的农作健康识别系统&…

FOC之SVPWM学习笔记

一、参考资料 【自制FOC驱动器】深入浅出讲解FOC算法与SVPWM技术 - 知乎FOC入门教程_zheng是在下的博客-CSDN博客DengFOC官方文档技术干货 |【自制】FOC驱动板SVPWM_扇区判断_时间计算_哔哩哔哩_bilibili 二、FOC控制算法流程框图 在FOC控制中主要用到三个PID环&#xff0c;从内…

picGo+gitee+typora设置图床

picGogiteetypora设置图床 picGogitee设置图床下载picGo软件安装picGo软件gitee操作在gitee中创建仓库在gitee中配置私人令牌 配置picGo在插件设置中搜索gitee插件并进行下载 TyporapicGo设置Typora 下载Typora进行图像设置 picGogitee设置图床 当我了解picGogitee可以设置图床…

基础论文学习(2)——DETR

目标检测 DETR&#xff1a;End-to-End Detection with Transformer detr是facebook提出的引入transformer到目标检测领域的算法&#xff0c;效果很好&#xff0c;做法也很简单&#xff0c;相较于RCNN和YOLO系列算法&#xff0c;避免了Proposal/AnchorNMS的复杂流程。 1. detr…

网络安全在医疗行业中的重要性

不可否认&#xff0c;现代世界见证了技术和医疗行业的交织&#xff0c;塑造了我们诊断、治疗和管理健康状况的新方式。随着电子健康记录取代纸质文件&#xff0c;远程医疗缩短了患者和医疗服务提供者之间的距离&#xff0c;数字化转型既是福音&#xff0c;也是挑战。最近的全球…

数据库三大范式是什么,又为什么要反范式?

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

opencv/C++ 人脸检测

前言 本文使用的测试资源说明&#xff1a; opencv版本&#xff1a;opencv 4.6.0 人脸检测算法 Haar特征分类器 Haar特征分类器是一个XML文件&#xff0c;描述了人体各个部位的Haar特征值。包括&#xff1a;人脸、眼睛、鼻子、嘴等。 opencv 4.6.0自带的Haar特征分类器&…

vue3+uni——watch监听props中的数据(组件参数接收与传递defineProps、defineEmits)

案例说明 A页面引用的子组件B A页面 <template><view>//引用组件<serviceOrder change"change" :list"list" :current"type"></serviceOrder></view> </template><script setup>import serviceOrd…

SpringCloud超详细教程

1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff1a;将业务的所有…

vue中实现echarts三维散点图

需要安装 echarts 同时引入 echarts-gl 我安装的版本&#xff1a; "echarts": "^5.3.2", "echarts-gl": "^2.0.9", import Vue from "vue"; import * as echarts from "echarts"; Vue.prototype.$echarts echa…