web学习--SpringMVC--1 基础学习

news2024/11/28 8:43:48
写在前面:
所有的web学习基于springboot项目,而不会去单独的使用spring来进行。

文章目录

  • SpringMVC介绍
    • 原理
    • MVC模式
  • 入门使用
    • 导入依赖
    • 编写controller类
  • 详细介绍
    • 注解详解
      • @Controller
      • @RequestMapping
      • @ResponseBody
      • @RestController
      • @RequestParam
      • @RequestBody
      • @Request其他
      • @DateTimeFormat
    • 各类参数接收
      • 简单参数
        • 原始获取
        • map
        • 自动匹配
      • 实体参数
        • 简单实体
        • 复杂实体
        • 同属性名字的不同实体同时接收
      • 数组
      • 集合
      • 日期时间类
      • json
      • 路径参数
  • 扩展
    • 统一返回类型
    • 静态资源存放

SpringMVC介绍

原理

SpringMVC底层就是Servlet,SpringMVC就是对Servlet进行深层次的封装。

MVC模式

MVC分别是:模型model(javabean)、视图view(jsp/img)、控制器Controller(Action/servlet)。

入门使用

导入依赖

有2种方式,一般第一种

  1. 在springboot创建项目的时候可以勾选spring web
    在这里插入图片描述
  2. 手动导入依赖
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>

编写controller类

在类上添加注解

@RestController

新建一个方法,在方法上指定请求路径

@RequestMapping("/uri")

这样一个简单的controller就完成好了。

@RestController
public class HellowController {

  @RequestMapping("/hello")
  public String hello(String username,String password){
    System.out.println("hello");
    return "hello";
  }
}

详细介绍

注解详解

@Controller

作用于:类
作用:该注解用来类上标识这是一个控制器组件类并创建这个类实例,告诉spring我是一个控制器。
不加这个
在这里插入图片描述
如果有controller就会显示了
在这里插入图片描述

@RequestMapping

作用于:类、方法
作用:用来指定请求路径。类设置的是这个类全局的请求路径,所以一个方法接收的uri为 类 m a p p i n g + 方法 m a p p i n g 类mapping+方法mapping mapping+方法mapping

@ResponseBody

作用于:类
作用:将方法的返回值直接响应到浏览器
如果是数据,就直接用数据展示
如果是实体类/集合则会以json返回

先给结论,如果不加这个,会返回静态资源文件,就是resource下static的对应文件名的文件。如果加了这个就是返回数据。

因为这个,我们也可以通过一个没有ResponseBody的控制类,来进行资源跳转和资源的获取

首先让我们尝试不加这个注解
在这里插入图片描述
发送请求,发现没有找到
在这里插入图片描述
但是如果我们将返回值修改为一个我们准备的页面
在这里插入图片描述
这次发送直接返回的是index.html的页面
在这里插入图片描述
直接在浏览器返回也是
在这里插入图片描述
而且还必须要有.html,如果只是index会显示没有页面
在这里插入图片描述
接下来我们添加
在这里插入图片描述

重启发送请求,就只是在数据放在上面。
在这里插入图片描述
下面演示集合,返回json字符串

    @GetMapping()
    public Map getName(){
        return Map.of("id",123,"name","张三");
    }

在这里插入图片描述

@RestController

作用于:类
作用:这个注解是controller的升级,包括了controller和ResponseBody,并且建议以REST风格来书写代码
在这里插入图片描述

@RequestParam

作用于:方法参数
作用:获取url请求参数
可选值:

  • required:表示是否一定需要
  • defaultValue:默认值
  • name:绑定到的请求参数
  • value:别名name,书写更简洁,因为只有value的时候可以省略

@RequestBody

作用于:方法参数
作用:获取请求体的参数
可选值:

  • required:表示是否一定需要

@Request其他

作用于:方法参数
作用:方法参数应绑定到web请求标头
其他:

  • Attribute
  • Header

@DateTimeFormat

作用于:方法参数
作用:声明字段或方法参数应格式化为日期或时间。
无论何时使用style或pattern属性,格式化java.util.Date值时都将使用JVM的默认时区
可选值:

  • pattern:格式化的格式
  • iso:格式化
    在这里插入图片描述
  • style:格式化字段或方法参数的样式模式
    短日期、短时间默认为“SS”。如果希望根据默认样式以外的通用样式设置字段或方法参数的格式,请设置此属性
  • fallbackPatterns:在主模式、iso或style属性解析失败时用作回退的一组自定义模式

各类参数接收

首先明确,参数的位置有2种,一种在url上一种在请求体上。
在请求体上的需要@RequestBody 而且最多只能出现一次,就是说需要一个实体接收全部的请求体参数。
这里先简单的做一个了解,后面在说匹配的问题。
在这里插入图片描述
打印出来的id就是

System.out.println("id = " + id);

在这里插入图片描述

简单参数

只推荐使用按名字匹配的,其他不推荐。

原始获取

    public String getID(HttpServletRequest request){
        String id = request.getParameter("id");
        System.out.println("id = " + id);
        return null;
    }

在这里插入图片描述
在这里插入图片描述

map

    @PostMapping()
    public String getName(@RequestParam Map user) {
        System.out.println("user = " + user);
        return null;
    }

结果

POST http://localhost/a?id=1&name=2

user = {id=1, name=2}

自动匹配

这是springboot的方式
会根据名字来进行匹配

    public String getName(String id, @RequestParam("id") Integer i){
        System.out.println("i = " + i);
        System.out.println("id = " + id);
        return null;
    }

在这里插入图片描述
会发现都可以获取到id。
即使类型不一样,也会进行自动转换。

接下来我们将请求id设置为z
返回为400且控制台出现类型转换的错误

2023-07-05 13:59:09.160  WARN 19200 --- [p-nio-80-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: "z"]

在这里插入图片描述

如果对应不上,那么默认就是null
但是如果是基本数据类型对应不上如定义了int id但是没有给id
那么就会报错因为int类型不能为null
所以在参数定义上都用包装类

实体参数

简单实体

只需要保证请求的形参名和实习参数一致

    record User(String name, Integer id){}
    @PostMapping()
    public String getName(User user){
        System.out.println("user = " + user);
        return null;
    }

结果

###
POST http://localhost:80/a?id=1

user = User[name=null, id=1]

###
POST http://localhost:80/a?id=1&name=2

user = User[name=2, id=1]

复杂实体

复杂类型传参就用.来区分
这里本来也想用record的,但是record由于没有遵守bean标准,不提供setter和无参构造会导致初始化失败。而无法赋值。
所以通过案例也可以知道,这里推测是调用无参构造init然后通过setter赋值

    @Data
    static class User {
        String name;
        Integer id;
        Address address;
    }

    @Data
    static class Address {
        Integer city;
        Integer id;
    }

    @PostMapping()
    public String getName(User user) {
        System.out.println("user = " + user);
        return null;
    }

结果

POST http://localhost/a?id=1&name=2&address.city=4&address.id=5

user = ResponseBodyController.User(name=2, id=1, address=ResponseBodyController.Address(city=4, id=5))

前面提到map传参,那么这里可以用吗.
可以看到这里其实吧address.city当成key而不是一个实体类了。

POST http://localhost/a?id=1&name=2&address.city=4&address.id=5

user = {id=1, name=2, address.city=4, address.id=5}

同属性名字的不同实体同时接收

    record User(String name, Integer id){}
    record Student(String name, Integer id){}
    @PostMapping()
    public String getName(User user,Student student){
        System.out.println("user = " + user);
        System.out.println("student = " + student);
        return null;
    }
###
POST http://localhost:80/a?id=1

user = User[name=null, id=1]
student = Student[name=null, id=1]


###
POST http://localhost:80/a?id=1&name=2

user = User[name=2, id=1]
student = Student[name=2, id=1]

可以看到,两个对象的值都被赋上了,但是,大部分情况下,不同的对象的值一般都是不同的

数组

    @PostMapping()
    public String getName(Integer[] id) {
        System.out.println("dis = " + Arrays.toString(id));
        return null;
    }
POST http://localhost/a?id=1&id=2

dis = [1, 2]

那么如果不是数组类型而传递了多个呢。
只有第一个有效

POST http://localhost/a?id=1&id=2

is = 1

集合

必须写来源在哪里,如RequestParam或者RequestBody
不然会出现

No primary or single unique constructor found for interface java.util.List
    public String getName(@RequestParam List<Integer> id) {
        System.out.println("id = " + id);
        return null;
    }

结果

POST http://localhost/a?id=1&id=2

id = [1, 2]

日期时间类

    public String getName(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime time) {
        System.out.println("time = " + time);
        return null;
    }

结果

POST http://localhost/a?time=2023-07-03 23:01:14

time = 2023-07-03T23:01:14

json

    @PostMapping()
    public String getName(@RequestBody User user) {
        System.out.println("user = " + user);
        return null;
    }

结果

POST http://localhost/a
Content-Type: application/json

{
  "name":"test",
  "id": 1,
  "address": {
    "city": 1,
    "id": 1
  }
}

user = ResponseBodyController.User(name=test, id=1, address=ResponseBodyController.Address(city=1, id=1))

但是这里是可以用record的,所以路径解析和url请求解析是不一样的。

    record User(String name, Integer id,Address address){}
    record Address(Integer id){}

    @PostMapping()
    public String getName(@RequestBody User user) {
        System.out.println("user = " + user);
        return null;
    }
POST http://localhost/a
Content-Type: application/json

{
  "name":"test",
  "id": 1,
  "address": {
    "id": 1
  }
}

user = User[name=test, id=1, address=Address[id=1]]

路径参数

    @PostMapping("{id}")
    public String getName(@PathVariable Integer id) {
        System.out.println("id = " + id);
        return null;
    }
POST http://localhost/a/1

id = 1

扩展

统一返回类型

因为返回的类型可能什么都有,所以我们需要一个统一的返回类型
一般有这3个属性

  • code 响应码
  • data 存放数据
  • msg 消息

由于这个返回类只用一次,所以可以用record简化。
这里给我的做的一个参考,根据自己的业务修改

package com.yu.common;

/**
 * 通用返回类
 *
 * @param code 200成功 500失败
 * @param data 返回的数据
 * @param msg  返回的信息
 */
public record R(Integer code, Object data, String msg) {
    public static R ok(Object data) {
        return new R(Code.SUCCESS.code(), data, "");
    }

    public static R ok() {
        return new R(Code.SUCCESS.code(), null, "");
    }
    public static R ok(Code code){
        return new R(code.code(),null,code.msg());
    }

    public static R error() {
        return new R(Code.ERROR.code(), null, "");
    }

    public static R error(Code code) {
        return new R(code.code(), null, code.msg());
    }

}

枚举类

package com.yu.common;

/**
 * 通用返回状态码类
 */
public enum Code {
    SUCCESS(200,"成功"),
    ERROR(500,"失败"),
    NOT_FOUND(404,"未找到"),
    NOT_LOGIN(401,"未登录"),
    NOT_AUTH(403,"未授权"),
    NOT_ALLOWED(405,"不允许的请求方式"),
    PARAM_ERROR(400,"参数错误"),
    SERVER_ERROR(500,"服务器错误"),
    PASSWORD_ERROR(1001,"密码错误"),
    NOT_NULL(1002,"不能为空"),
    NOT_EXIST_STUDENTS(1003,"不存在该学生"),
    ;

    private final int code;
    private final String msg;

    Code(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static Code get(int code){
        for (Code value : Code.values()) {
            if (value.code == code){
                return value;
            }
        }
        return null;
    }

    public int code() {
        return code;
    }

    public String msg() {
        return msg;
    }
}

静态资源存放

springboot的静态目录(html,css,js等)默认存放目录为classpath:/static、classpath:/public、classpath:/resources
一般放在static里面
访问直接localhost:port/相当于static/
如访问static/index/index.html
就可以通过localhost:port/index/index.html访问

当然前后端分离项目不会在static下存放

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

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

相关文章

聚观早报 | 字节跳动要造机器人;苹果已开发悬空虚拟键盘

今日要闻&#xff1a;字节跳动要造机器人&#xff1b;苹果已开发悬空虚拟键盘&#xff1b;苹果汽车或售价9万美元&#xff1b;全球首例猪心脏移植患者仅存活60天&#xff1b;首款搭载ChatGPT的自行车问世 字节跳动要造机器人 7 月 3 日消息&#xff0c;「机器人」作为未来科技…

MySQL-分库分表详解(四)

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

记录安装ESXI-6.7遇到的问题(DELL)

从官网下载完ISO镜像,使用rufus制作启动盘 安装过程中报错信息 缺少网卡驱动 安装打包网卡驱动请查看此链接:https://www.cnblogs.com/Sunzz/p/11438066.html 通过检测网卡驱动后,报错信息 解决办法 关闭BIOS中的Secure Boot 具体步骤如下&#xff1a; 1.按F2进入bios 2…

最长回文子串 (力扣) 动态规划 JAVA

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&#…

FlinkSQL 解析字符串+行转列

近期遇到一个实时flinksql需求&#xff0c;需要根据ids数组字段解析成名称数组字段。。。 其中parent_path存放的内容是点号分割的字符串"1659077318807721985.1659120595539924993.1659121050219255810" 第一步&#xff1a;新建kafka source源 create TEMPORARY t…

怎样处理服务器无法复制粘贴问题?服务器不能复制粘贴怎么办?

我们经常需要在服务器上进行一些操作&#xff0c;如复制粘贴文件、修改配置等等。但有时候我们会遇到服务器无法使用复制粘贴功能的问题&#xff0c;这时该怎么办呢&#xff1f;以下是一些解决方法。 1&#xff0e;检查RDP剪贴板功能是否开启 在远程桌面连接(RDP)中&#xff…

基于多案例系统学习防洪评价报告编制方法与水流数学模型建模

查看原文>>>基于多案例系统学习防洪评价报告编制方法与水流数学模型建模 随着社会经济的快速发展&#xff0c;我国河道周边土地开发利用率不断增大&#xff0c;临河建筑物与日俱增&#xff0c;部分河道侵占严重&#xff0c;导致防洪压力增大。加之部分河流沿岸临河建…

Win10无法安装到这个磁盘,选中的磁盘具有mbr分区

关闭这个窗口执行一下操作; 1.按住 shiftF10快捷键&#xff0c;打开命令提示符终端&#xff1b; 2.输入diskpart &#xff0c;并按下回车 &#xff1b; 3.输入list disk&#xff0c;并按下回车&#xff0c;查看盘的使用情况 ; 4.输入 select disk 0 &#xff0c;并按下回车&am…

Mybatis-SQL分析组件 | 京东云技术团队

背景 大促备战&#xff0c;最大的隐患项之一就是慢sql&#xff0c;带来的破坏性最大&#xff0c;也是日常工作中经常带来整个应用抖动的最大隐患&#xff0c;而且对sql好坏的评估有一定的技术要求&#xff0c;有一些缺乏经验或者因为不够仔细造成一个坏的sql成功走到了线上&am…

SpringBoot使用EasyExcel实现Excel的导入导出

一、概念 EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下&#xff0c;快速完成 Excel 的读、写等功能。 二、EasyExcel常用注解 注解名称属性介绍ExcelProperty value属性设置表头的名称 i…

CSPM是什么?

背景 2021年10月&#xff0c;中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系&#xff0c;开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会&#xff08;CAS&#xff09;组织开…

【lora模块调试:亿百特lora-型号E22-400T30D-V=代码调试-STM32H7xx/F4xx/F1xx-基础样例(2)】

【lora模块调试&#xff1a;亿百特lora-型号E22-400T30D-V代码调试-STM32H7xx/F4xx/F1xx-基础样例&#xff08;2&#xff09;】 1、概述2、实验环境3、实验说明3-1调试开发板H71、先了解硬件H72、测试keil版本的H7软件代码&#xff08;1&#xff09;找到样例代码。&#xff08;…

3.清除浮动

3.1 为什么需要清除浮动? 由于父级盒子在很多情况下&#xff0c;不方便给高度&#xff0c;但是子盒子浮动又不占有位置&#xff0c;最后父级盒子高度为0时&#xff0c;就会影响下面的标准流盒子。 ●由于浮动元素不再占用原文档流的位置&#xff0c;所以它会对后面的元素排…

java开发微信公众平台之素材上传

微信公众平台官方文档 我在本地使用工具请求接口一切正常。 当我开始写代码的时候 我蒙了 后台怎么模拟form表单上传图片 放参考文章链接https://blog.csdn.net/subaiqiao/article/details/122059076 首先引入依赖 <dependency><groupId>com.squareup.okhttp3&l…

环状二肽:16364-36-6,cyclo(Ala-Glu),环(-丙氨酸-谷氨酸),具有明确的生物活性

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ Cyclo(Ala-Glu) 是一种环状二肽&#xff0c;环二肽(2,5-哌嗪二酮)是Z小的环肽&#xff0c;许多天然环二肽化合物都具有明确的生物活性&#xff0c;环二肽结构的特殊性使得这类化合物的合成自成体系&#xff0c;通常由N端游离…

sap abap,forms,smartforms 导出pdf

4种方法&#xff1a; 1.安装pdf程序&#xff0c;Foxit Reader,先敲回车 自动带出&#xff0c;如下图&#xff1a; 直接打印就会弹出保存pdf文档路径&#xff0c;点保存。这种方式是最简单的&#xff0c;可 forms 和 smartforms 。 2. forms 和 smartforms 打印到spool 中&…

Django搭建图书管理系统03:编写博客文章的Model模型

Django 框架主要关注的是模型&#xff08;Model&#xff09;、模板&#xff08;Template&#xff09;和视图&#xff08;Views&#xff09;&#xff0c;称为MTV模式。 它们各自的职责如下&#xff1a; 层次职责模型&#xff08;Model&#xff09;&#xff0c;即数据存取层处理与…

【设计模式】第六章:装饰器模式详解及应用案例

系列文章 【设计模式】七大设计原则 【设计模式】第一章&#xff1a;单例模式 【设计模式】第二章&#xff1a;工厂模式 【设计模式】第三章&#xff1a;建造者模式 【设计模式】第四章&#xff1a;原型模式 【设计模式】第五章&#xff1a;适配器模式 【设计模式】第六章&…

STM32外设系列—ESP8266(WIFI)

文章目录 一、ESP8266简介二、固件库烧录三、常用AT指令四、访问API4.1 获取IP地址4.2 GET天气信息4.3 访问结果展示 五、实战项目5.1 串口配置5.2 检测WIFI模块连接状态5.3 发送配置指令5.4 解析天气信息 六、成果展示 一、ESP8266简介 ESP8266是嵌入式和物联网开发中常用的模…

js实现用时间戳生成13位随机数

效果如图&#xff1a; methods里面写方法&#xff1a; changeTime(val) {//去掉-var reg new RegExp("-", "g");var a val.replace(reg, "");//去掉空格var regs new RegExp(" ", "g");var b a.replace(regs, "&qu…