SpringMVC修炼之旅(2)基础入门

news2025/1/22 16:03:18

一、第一个程序

1.1环境配置

1.2代码实现

package com.itheima.controller;

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

//定义表现层控制器bean
@Controller
public class UserController {

    //设置映射路径为/save,即外部访问路径
    @RequestMapping("/save")
    //设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }

    //设置映射路径为/delete,即外部访问路径
    @RequestMapping("/delete")
    @ResponseBody
    public String delete(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }
}

1.3注解解析

@Controller

类型:类注解

位置:SpringMVC控制器类定义上方

作用:用于标记控制器类。当一个类被@Controller注解标记时,Spring会自动将该类识别为一个控制器类,并负责处理与该类相关的HTTP请求。

@Controller
public class UserController 
{

}

@RequestMapping

类型:方法注解

位置:SpringMVC控制器方法定义上方

作用:用于映射HTTP请求到特定的处理方法。它可以应用于类、方法或参数上。当一个类被@RequestMapping注解标记时,Spring会自动将该类中的所有带有@RequestMapping注解的方法识别为处理特定URL路径的处理器。:

@Controller
public class UserController {

    @RequestMapping(value = "/save")
    public void save() {
        System.out.println("user save ...");
    }
}

 相关属性 value(默认):请求访问路径

@ResponseBody

 类型:方法注解

位置:SpringMVC控制器方法定义上方

作用:用于将控制器方法的返回值直接写入HTTP响应体中。这样,当客户端发起请求时,服务器端会将处理结果以指定的格式(如JSON、XML等)发送给客户端

1.4bean加载控制

Spring控制的bean

  • 业务bean(Service)
  • 功能bean(DataSource等)

@Configuration

`@Configuration`注解是Spring框架中的一个注解,用于标记一个类作为配置类。配置类通常用于定义Bean的创建和依赖关系,以便在应用程序中进行依赖注入。

 @ComponentScan

类型:类注解

位置:应该放在Spring配置文件的类上,通常是在配置类中

作用:用于指定要扫描的包路径,以便自动注册该包及其子包中的组件。当使用@ComponentScan注解时,Spring会自动扫描指定的包路径下的所有类,并将带有@Component、@Service、@Repository或@Controller等注解的类注册为Spring容器中的Bean。

@Configuration
@ComponentScan(value = "com.com.example",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
}

 excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes) includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)

@EnableAutoConfiguration

是Spring Boot框架提供的一个注解,用于自动配置Spring应用程序的配置。它会根据应用程序的依赖和配置自动配置Spring应用程序的配置。这样可以减少开发人员的配置工作,提高开发效率。@EnableAutoConfiguration注解通常与@SpringBootApplication注解一起使用,用于启用Spring Boot自动配置功能。

@SpringBootApplication

`@SpringBootApplication`注解是Spring Boot框架中的一个注解,用于标记`@SpringBootApplication`注解是Spring Boot框架中的一个注解,用于标记一个类作为Spring Boot应用程序的主入口。它包含了`@Configuration`、`@EnableAutoConfiguration`和`@ComponentScan`三个注解的组合,可以自动配置Spring Boot应用程序的组件扫描路径、自动配置和其他相关设置。 

 二、请求和响应

2.1请求映射路径

多个控制器类处理相同的请求路径

可以通过以下方法解决

使用@RequestMapping注解的value属性指定请求路径的具体值,可以在不同的控制器类中使用不同的请求路径来区分不同的处理方法。

@Controller
@RequestMapping("/example")
public class ExampleController1 {
    @RequestMapping("/test")
    public String test() {
        //处理逻辑
        return "test";
    }
}

@Controller
@RequestMapping("/example2")
public class ExampleController2 {
    @RequestMapping("/test")
    public String test() {
        //处理逻辑
        return "test2";
    }
}
使用@RequestMapping注解的params属性来区分不同的请求处理方法,可以根据请求参数的不同来调用不同的处理方法。
@Controller
@RequestMapping("/example")
public class ExampleController {
    @RequestMapping(value = "/test", params = "param1")
    public String test1() {
        //处理逻辑
        return "test1";
    }

    @RequestMapping(value = "/test", params = "param2")
    public String test2() {
        //处理逻辑
        return "test2";
    }
}

使用@RequestMapping注解的headers属性来区分不同的请求处理方法,可以根据请求头的不同来调用不同的处理方法。

@Controller
@RequestMapping("/example")
public class ExampleController {
    @RequestMapping(value = "/test", headers = "header1=value1")
    public String test1() {
        //处理逻辑
        return "test1";
    }

    @RequestMapping(value = "/test", headers = "header2=value2")
    public String test2() {
        //处理逻辑
        return "test2";
    }
}

 2.2请求方式

  • Get请求
  • Post请求

Get请求传参

普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数 

@RequestMapping("/commonParam")
    @ResponseBody
    public String handleCommonParam(String name,Integer age) {
        System.out.println("Name: " + name + ", age: " + age);
        return "{'module':'common param'}";
    }
GET http://localhost:8080/commonParam?name=11&age=11

 Post请求参数

POST http://localhost:8080/commonParam
Content-Type: application/x-www-form-urlencoded

name=11&age=18

Get请求和 Post请求的区别

GET和POST是HTTP协议中两种最常被使用的请求方法,它们在原理、使用、速度和安全性等方面都有所区别。具体来说:

  1. 参数传递方式:GET方法将参数包含在URL中,而POST方法通过request body传递参数。这意味着,使用GET提交的数据会显示在URL上,而POST提交的数据则不会显示在URL上。

  2. 数据用途:GET请求通常用于从服务器获取数据,而POST请求则主要用于向服务器提交数据,例如提交表单数据。

  3. 缓存与历史记录:GET请求可以被浏览器缓存,同时也会保存在浏览器的历史记录中。相反,POST请求不会被缓存,且不会保存在历史记录中。

  4. 安全性:由于GET请求将参数直接暴露在URL中,因此可能存在安全隐患。相反,POST请求通过加密的request body传递参数,因此在安全性方面相对较高。

  5. 数据量限制:GET方法由于数据量受限于URL的长度,因此对于大量数据的提交不太适用。而POST方法没有这方面的限制。

  6. 影响刷新和回退:当使用GET请求时,刷新页面或回退操作不会影响之前的数据。但是,使用POST请求时,回退可能会导致数据被重新提交。

2.3请求参数

参数种类

  • 普通参数
  • POJO类型参数
  • 嵌套POJO类型参数
  • 数组类型参数
  • 集合类型参数 

普通参数:

  • url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数 
  • 请求参数名与形参变量名不同,使用@RequestParam绑定参数关系
 @RequestMapping("/commonParam")
    @ResponseBody
    public String handleCommonParam(@RequestParam("name") String name1,Integer age) {
        System.out.println("Name: " + name1 + ", age: " + age);
        return "{'module':'common param'}";
    }

@RequestParam 注解

类型:形参注解

位置:SpringMVC控制器方法形参定义前面

作用:用于将请求参数绑定到方法的参数上。它可以用于处理 GET 和 POST 请求中的查询参数和表单数据。使用 @RequestParam 注解可以将请求参数的值绑定到方法的参数上

它有以下两个参数:

  1. required:布尔类型,表示该参数是否为必传参数。如果设置为 true,则在请求中必须包含该参数;如果设置为 false,则可以不包含该参数,此时参数的默认值为 null

  2. defaultValue:字符串类型,表示当请求中没有提供该参数时使用的默认值。如果不设置此参数,或者设置为空字符串,那么在请求中没有提供该参数时,参数的值将为 null

@RequestMapping("/commonParam")
    @ResponseBody
    public String handleCommonParam(@RequestParam(value = "name", required = false, defaultValue = "defaultValue1") String name1,Integer age) {
        System.out.println("Name: " + name1 + ", age: " + age);
        return "{'module':'common param'}";
    }

POJO参数:

请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数

pojo类

@RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("pojo参数传递 user ==> "+user);
        return "{'module':'pojo param'}";
    }

嵌套POJO参数:

POJO对象中包含POJO对象

请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数

 @RequestMapping("/pojoContainPojoParam")
    @ResponseBody
    public String pojoContainPojoParam(User user){
        System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
        return "{'module':'pojo contain pojo param'}";
    }
GET http://localhost:8080//pojoContainPojoParam?name1=11&age=11&Address.province=12&Address.city=12

 数组参数:

同名请求参数可以直接映射到对应名称的形参数组对象中

//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
        System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
        return "{'module':'array param'}";
    }
GET http://localhost:8080/arrayParam?likes=1&likes=2

集合保存普通参数:

请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系 

 //集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
    @RequestMapping("/listParam")
    @ResponseBody
    public String listParam(@RequestParam List<String> likes){
        System.out.println("集合参数传递 likes ==> "+ likes);
        return "{'module':'list param'}";
    }

 集合参数:json格式

 @RequestMapping("/listParamForJson")
    @ResponseBody
    public String listParamForJson(@RequestBody List<String> likes){
        System.out.println("list common(json)参数传递 list ==> "+likes);
        return "{'module':'list common for json param'}";
    }
POST http://localhost:8080//listParamForJson
Content-Type: application/json

["like1", "like2", "like3"]

POJO参数:json数据

json数据与形参对象属性名相同,定义POJO类型形参即可接收参数

@RequestMapping("/pojoParamForJson")
    @ResponseBody
    public String pojoParamForJson(@RequestBody User user){
        System.out.println("pojo(json)参数传递 user ==> "+user);
        return "{'module':'pojo for json param'}";
    }
POST http://localhost:8080/pojoParamForJson
Content-Type: application/json

{
"name": "John Doe", "age": 25,"address": {"province": "Ontario", "city": "Toronto"}
}

POJO集合参数:json

json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数

//集合参数:json格式
    //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
    //2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
    @RequestMapping("/listPojoParamForJson")
    @ResponseBody
    public String listPojoParamForJson(@RequestBody List<User> list){
        System.out.println("list pojo(json)参数传递 list ==> "+list);
        return "{'module':'list pojo for json param'}";
    }
POST http://localhost:8080/listPojoParamForJson
Content-Type: application/json

[
  {
    "name": "John Doe", "age": 25,"address": {"province": "Ontario", "city": "Toronto"}
  },
  {
    "name": "John Doe", "age": 25,"address": {"province": "Ontario", "city": "Toronto"}
  }
]

@RequestBody与@RequestParam区别

区别

  • @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
  • @RequestBody用于接收json数据【application/json】

应用

  • 后期开发中,发送json格式数据为主,@RequestBody应用较广
  • 如果发送非json格式数据,选用@RequestParam接收请求参数

日期类型参数传递

//日期参数
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
                        @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
                        @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
    System.out.println("参数传递 date ==> "+date);
    System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
    System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
    return "{'module':'data param'}";
GET http://localhost:8080/dataParam?date1=2023-12-06&date2=2023/12/06 10:10:10

想要将日期作为查询参数传递,因此你应该使用GET请求而不是POST请求。此外,由于日期值需要按照指定的格式进行设置,你需要对日期2的值进行编码,因为URL中的空格是不允许的

2.4响应 

响应页面

@RequestMapping("/toJumpPage")
public String toJumpPage(){
    System.out.println("跳转页面");
    return "redirect:/page.jsp";
}

响应数据

  • 文本数据
  • json数据 
文本数据
//响应文本数据
    //返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
    @RequestMapping("/toText")
    @ResponseBody
    public String toText(){
        System.out.println("返回纯文本数据");
        return "response text";
    }

 

json数据 
 @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("itcast");
        user.setAge(15);
        return user;
    }
 @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        System.out.println("返回json集合数据");
        User user1 = new User();
        user1.setName("烟雨");
        user1.setAge(15);

        User user2 = new User();
        user2.setName("平生");
        user2.setAge(12);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);

        return userList;
    }

HttpMessageConverter接口

// 定义一个名为HttpMessageConverter的接口,泛型参数为T
public interface HttpMessageConverter<T> {
    // 判断是否可以读取指定类型的数据,参数为类对象和媒体类型(可以为空)
    boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
    // 判断是否可以写入指定类型的数据,参数为类对象和媒体类型(可以为空)
    boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
    // 获取支持的媒体类型列表
    List<MediaType> getSupportedMediaTypes();
    // 从输入消息中读取指定类型的数据,参数为类对象和输入消息对象
    T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
        throws IOException, HttpMessageNotReadableException;
    // 将指定类型的数据写入输出消息,参数为数据对象、内容类型(可以为空)和输出消息对象
    void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException;
}

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

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

相关文章

初识MQ——消息队列技术选型

文章目录 同步和异步通讯同步通讯异步通讯 技术对比 同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c…

CCF编程能力等级认证GESP—C++1级—20230318

CCF编程能力等级认证GESP—C1级—20230318 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)每月天数长方形面积 答案及解析单选题判断题编程题1编程题2 单选…

SQL手工注入漏洞测试(Sql Server数据库)-墨者

———靶场专栏——— 声明&#xff1a;文章由作者weoptions学习或练习过程中的步骤及思路&#xff0c;非正式答案&#xff0c;仅供学习和参考。 靶场背景&#xff1a; 来源&#xff1a; 墨者学院 简介&#xff1a; 安全工程师"墨者"最近在练习SQL手工注入漏洞&#…

国内AI翘楚,看看有没有你心动的offer?

科技创新争占高地&#xff0c;AI领域各显神通。从一战成名的阿尔法狗到引起轩然大波的ChatGPT&#xff0c;我们早已卷入了一场没有硝烟的革命。前方世人看到的科技日新日异、岁月静好&#xff0c;后方是各大企业的绞尽脑汁、争先恐后。人工智能时代&#xff0c;AI是挡不住的时代…

Lebesgue积分及应用

Lebesgue积分及应用 文章目录 Lebesgue积分及应用一、Lebesgue测度和可测函数1.1 Riemann积分和Lebesgue积分1.2 直线上的Lebesgue测度【定义】外测度&#xff08;Outer Measure&#xff09;【定理】外测度的性质【定义】内测度【定义】可测、Lebesgue测度【定理】卡氏条件&…

Java注册并监听全局快捷键

背景 之前在博客中分享了SWT托盘功能, 随之带来一个问题, 当程序最小化后无法快速唤醒, 按照平时使用软件的思路, 自然想到了注册全局快捷键, 本文介绍使用java方式实现全局快捷键的注册. 方案 通过google,搜到一个现成的库: jintellitype, 使用maven可以直接引用, 非常方便…

C语言易错知识点八(整形与浮点型在内存中存储的实质)

整形与浮点型在内存中存储的实质 当我们在刷抖音或者其他短视频平台时&#xff0c;可能会时不时(总是&#xff0c;我相信大家肯定是不会被外表骗到的那一类人ヾ(●゜ⅴ゜)&#xff89;)刷到各种帅哥美女的视频&#xff0c;或者我们在学校里看到帅哥美女时&#xff0c;如果我们只…

NFC和蓝牙在物联网中有什么意义?如何选择?

#NFC物联网# #蓝牙物联网# 在物联网中&#xff0c;NFC和蓝牙有什么意义&#xff1f; NFC在物联网中代表近场通信技术。它是一种短距离、高频的无线通信技术&#xff0c;可以在近距离内实现设备间的数据传输和识别。NFC技术主要用于移动支付、电子票务、门禁、移动身份识别、防…

Vue2中v-html引发的安全问题

前言&#xff1a;v-html指令 1.作用&#xff1a;向指定节点中渲染包含html结构的内容。 2.与插值语法的区别&#xff1a; (1).v-html会替换掉节点中所有的内容&#xff0c;{{xx}}则不会。 (2).v-html可以识别html结构。 3.严重注意&#xff1a;v-html有安全性问题&#xff0…

STM32串口接收数据包(自定义帧头帧尾)

1、基本概述 本实验基于stm32c8t6单片机&#xff0c;串口作为基础且重要的外设&#xff0c;具有广泛的应用。本文主要理解串口数据包的发送与接收是如何实现的&#xff0c;重要的是理解程序的实现思路。 2、关键程序 定义好需要用到的变量&#xff1a; uint8_t rxd_buf[4];//…

湖南麒麟下默认使用串口输出系统日志

有时候为了调试方便&#xff0c;需要将系统日志通过CPU的串口进行输出&#xff0c;以下是针对至强E5V4处理器上安装湖南麒麟操作系统后将日志通过串口输出的配置。 首先在bios中打开串口重定向功能&#xff0c;这里的BIOS是AMI的BIOS 内部配置如下&#xff0c;波特率115200配置…

ESP32网络开发实例-发送邮件

发送邮件 文章目录 发送邮件1、邮件发送配置2、软件准备3、硬件准备4、代码实现本文将详细介绍在ESP32中如何使用SMTP协议发送邮件。 1、邮件发送配置 在本次实例中,我们将通过QQ邮箱向指定邮件地址发送邮件。 第一步,注册QQ邮箱 第二步,开启QQ邮箱SMTP/IMAP 服务: 生成…

一文搞懂Git版本控制系统

1. Git简介 当涉及到软件开发或协作时&#xff0c;版本管理是一个不可或缺的概念。无论你是一个独立开发者还是一个团队成员&#xff0c;都会遇到需要跟踪和管理代码变更的情况。这时候&#xff0c;Git作为一个强大而流行的版本控制系统就发挥着重要的作用。 Git&#xff08;读…

使用Pytoch实现Opencv warpAffine方法

随着深度学习的不断发展&#xff0c;GPU/NPU的算力也越来越强&#xff0c;对于一些传统CV计算也希望能够直接在GPU/NPU上进行&#xff0c;例如Opencv的warpAffine方法。Opencv的warpAffine的功能主要是做仿射变换&#xff0c;如果不了解仿射变换的请自行了解。由于Pytorch的图像…

每日一题:LeetCode-75. 颜色分类

每日一题系列&#xff08;day 12&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

【多线程】线程的三种常见创建方式

文章目录 线程创建方式1——Thread线程创建方式2——Runnable线程创建方式2——匿名内部类线程创建方式3——Callable、FutureTask,带返回值 线程其实是程序中的一条执行路径。 那怎样的程序才是多线程程序呢&#xff1f; 例如12306网站就是支持多线程的&#xff0c;因为同时可…

通过仿真理解信道化接收机分析过程

概要 信道化从子信道带宽划分上可分为临界抽取和非临界抽取两种&#xff0c;从各子信道中心频率布局上可分为偶型排列和奇型排列&#xff0c;从处理流程上可分为信道化分析与信道化综合过程。本文主要通过仿真来理解偶型排列/临界抽取/信道化分析过程。 基本原理 常规的数字…

基于KSZ9897VLAN 虚拟WAN网络接口

目录 1:先看看高通的8327是如何虚拟网络接口 2: Linux 内核中选上802.1Q 3: 实际效果展示 4&#xff1a;配置使用 1:先看看高通的8327是如何虚拟网络接口 rootOpenWrt:~# cat /etc/config/wirelessconfig wifi-device wifi0option type qcawifioption macaddr 68:89:75:04:…

三十九、TCC模式

目录 一、定义 1、需要实现的方法&#xff1a; 2、优点&#xff1a; 3、缺点&#xff1a; 二、原理 1、例子&#xff1a; 2、工作模型图&#xff1a; 3、空回滚和业务悬挂 三、实现TCC模式 1、编写TCC服务接口 2、实现TCC服务接口 一、定义 TCC模式是Translucent Tr…

三焦不通,百病丛生?三焦指的到底是什么?

本 期 导 读 今天来讲一讲&#xff0c;看起来比较古怪的腑——三焦。 三焦的名字虽出于《内经》&#xff0c;但对它的描述却不像其他十一脏腑那么具体&#xff0c;留下了极大的解说空间。 三焦真的不可捉摸吗&#xff1f;当然不是。本文就带你揭开三焦的那层似有还无的面纱…