SpringMVC学习(一)——请求与响应处理

目录

一、SpringMVC简介

二、@RequestMapping:请求路径映射

三、@RestController

四、请求限定

五、请求处理

1.使用普通变量,收集请求参数

2.使用@RequestParam明确指定获取参数 

3.目标方法参数是一个pojo 

4.@RequestHeader:获取请求头信息       

5.@CookieValue注解:获取cookie信息

6.使用pojo级联封装复杂属性

7.@RequestBody:获取请求体的JSON数据

8.单/多文件上传

9.HttpEntity:获取整个请求

10.传入原生API

六、响应处理

1.返回JSON:自动将返回的对象转为JSON格式

2.文件下载


一、SpringMVC简介

        Spring MVC是一个基于Java的实现MVC(Model-View-Controller)设计模式的Web应用程序框架。它是Spring框架的一部分,专门用于构建Web应用程序。以下是Spring MVC的一些关键特性:

  1. 请求驱动:Spring MVC以请求为中心,所有的操作都是围绕请求进行的。

  2. 灵活的控制器:开发者可以定义自己的控制器来处理请求,控制器可以是一个普通的 Java类,里面包含一个或多个处理请求的方法。

  3. 视图解析器:Spring MVC提供了灵活的视图解析机制,可以根据返回值自动选择视图模板进行渲染。

  4. 数据绑定:Spring MVC提供了强大的数据绑定功能,可以将请求参数自动绑定到控制器方法的参数上。

  5. 模型和视图:控制器可以向视图传递模型数据,这些数据可以是简单的值,也可以是复杂的对象。

  6. 拦截器:Spring MVC支持拦截器,可以在请求处理的不同阶段执行自定义逻辑。

  7. 异常处理:Spring MVC提供了异常处理器,可以集中处理控制器方法抛出的异常。

  8. 国际化:Spring MVC支持国际化,可以根据不同地区的用户显示不同的内容。

  9. 集成测试:Spring MVC提供了测试支持,可以方便地进行集成测试。

  10. RESTful 支持:Spring MVC支持构建RESTful Web服务。

        Spring MVC通过注解(如@Controller、@RequestMapping、@RequestParam等)简化了配置和开发过程,使得开发者可以更专注于业务逻辑的实现。它与Spring框架的其他模块(如Spring Security、Spring Data JPA)紧密集成,提供了一个完整的企业级Web应用程序开发解决方案。

二、@RequestMapping:请求路径映射

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
@Controller
public class HelloController {@ResponseBody  // 把返回值放到响应体中@RequestMapping("/hello")public String hello(){return "hello 你好~~"; // 默认认为返回值是跳到一个页面}
}

  

精确路径必须全局唯一

路径位置通配符:多个都能匹配上,精确匹配优先

        * :匹配任意多个字符(0~n):不能匹配多个路径

        **:匹配任意多层路径

        ? :匹配任意单个字符(1)

精确程度:完全匹配 > ? > * > **

三、@RestController

        @RestController用于定义一个控制器类,该类中的所有方法默认返回的是数据而不是视图。
        作用:@RestController是@Controller和@ResponseBody的组合注解。它表明该类中的所有方法返回的数据直接写入HTTP响应体中,而不是返回一个视图。
        使用场景:通常用于构建RESTful Web 服务,返回JSON或XML格式的数据。

四、请求限定

@RestController
public class RequestMappingLimitController {/*** 限制请求方式*/@RequestMapping(value = "/test01", method = {RequestMethod.POST, RequestMethod.GET})public String test01() {return "test01";}/*** 限制请求参数*/@RequestMapping(value = "/test02", params = {"age=18", "username", "gender!=1"})public String test02() {return "test02";}/*** 限制请求头*/@RequestMapping(value = "/test03", headers = {"username=admin"})public String test03() {return "test03";}/*** 限制请求内容类型* application/json:表示浏览器必须使用json格式发送数据*/@RequestMapping(value = "/test04", consumes = "application/json")public String test04() {return "test04";}/*** 限制响应内容类型* text/html;charset=utf-8:表示浏览器必须使用html格式接收数据*/@RequestMapping(value = "/test05", produces = "text/html;charset=utf-8")public String test05() {return "<h1>test05<h1>";}
}

五、请求处理

1.使用普通变量,收集请求参数

@RequestMapping("/handle01")
public String handle01(Integer id,String name) {System.out.println(id);System.out.println(name);return "ok";
}

2.使用@RequestParam明确指定获取参数 

defaultValue:如果参数没有传递,则使用默认值
required:是否必须传递,默认为true
value:指定参数名
无论请求参数带到了请求体中,还是没有带到请求体中,都可以直接用@RequestParam或者同一个变量名获取到参数值。

@RequestMapping("/handle02")
public String handle02(@RequestParam("id") Integer id,@RequestParam(required = false, defaultValue = "admin") String name) {System.out.println(id);System.out.println(name);return "ok";
}

3.目标方法参数是一个pojo 

如果目标方法参数是一个pojo:SpringMVC会自动把请求参数和pojo属性对应起来
效果:1.pojo的所有属性值都是来自于请求参数
           2.请求参数必须和pojo属性名一致,否则无法对应
           3.如果请求参数没有和pojo属性对应上,封装为null,也可以给出默认值 

@RequestMapping("/handle03")
public String handle03(Person person) {System.out.println(person);return "ok";
}

运行结果: 

Person(id=12, name=李四)

4.@RequestHeader:获取请求头信息       

@RequestMapping("/handle04")
public String handle04(@RequestHeader("host") String host,@RequestHeader("User-Agent") String userAgent,@RequestHeader("Accept") String Accept) {System.out.println(host);System.out.println(userAgent);System.out.println(Accept);return "ok";
}

5.@CookieValue注解:获取cookie信息

@RequestMapping("/handle05")
public String handle05(@CookieValue String username) {System.out.println(username);return "ok";
}

  

6.使用pojo级联封装复杂属性

@Data
public class Person {private Integer id;private String name;private Address address;private String[] hobbies;
}@Data
public class Address {private String street;private String city;private String state;private String zipCode;
}
@RequestMapping("/handle06")
public String handle06(Person person) {System.out.println(person);return "ok";
}

运行结果:  

Person(id=101, name=admin, address=Address(street=平安大街, city=北京, state=东城区, zipCode=100101), hobbies=[唱, 跳, rap, 篮球])

7.@RequestBody:获取请求体的JSON数据

@RequestBody:获取请求体的JSON数据,自动转为对象

  • 如果是@RequestBody Person person:则得到一个对象
  • 如果是@RequestBody String str:则直接接收JSON字符串
@RequestMapping("/handle07")
public String handle07(@RequestBody Person person) {System.out.println(person);return "ok";
}

运行结果:

Person(id=101, name=admin, address=Address(street=平安大街, city=北京, state=东城区, zipCode=100101), hobbies=[唱, 跳, rap, 篮球])

8.单/多文件上传

@RequestParam取出文件项,封装为MultipartFile,就可以拿到文件内容

application.properties: 

# 每个单独上传的文件不能超过 50MB
spring.servlet.multipart.max-file-size=50MB
# 限制整个 multipart/form-data 请求的最大允许大小
spring.servlet.multipart.max-request-size=100MB
@RequestMapping("/handle08")
public String handle08(Person person,@RequestParam("headerImg") MultipartFile headerImgFile,@RequestParam("lifeImg") MultipartFile[] lifeImgFiles) throws IOException {System.out.println(person);System.out.println("原始文件名:" + headerImgFile.getOriginalFilename());System.out.println("获取表单字段的名称:" + headerImgFile.getName());System.out.println("文件大小:" + headerImgFile.getSize());System.out.println("文件流:" + headerImgFile.getInputStream());System.out.println("文件类型:" + headerImgFile.getContentType());// 文件保存到本地headerImgFile.transferTo(new File("D:\\img\\" + headerImgFile.getOriginalFilename()));System.out.println("文件数组:" + Arrays.toString(lifeImgFiles));if (lifeImgFiles.length > 0) {for (MultipartFile lifeImgFile : lifeImgFiles) {lifeImgFile.transferTo(new File("D:\\img\\" + lifeImgFile.getOriginalFilename()));}}return "ok";
}

运行结果:

Person(id=13, name=admin, address=null, hobbies=null)
原始文件名:girl.png
获取表单字段的名称:headerImg
文件大小:4360
文件流:java.io.FileInputStream@7d79526d
文件类型:image/png
文件数组:[org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@d0bebd7, org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@57e61fe3, org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@7f3c2d62, org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@48e1e2d2]

9.HttpEntity:获取整个请求

@RequestMapping("/handle09")
public String handle09(HttpEntity<Person> entity) {// 获取请求头信息System.out.println("请求头:" + entity.getHeaders());// 获取请求体信息System.out.println("请求体:" + entity.getBody());return "ok";
}

运行结果: 

请求头:[user-agent:"Apifox/1.0.0 (https://apifox.com)", accept:"*/*", host:"localhost:8080", accept-encoding:"gzip, deflate, br", connection:"keep-alive", content-length:"281", Content-Type:"application/json;charset=UTF-8"]
请求体:Person(id=101, name=admin, address=Address(street=平安大街, city=北京, state=东城区, zipCode=100101), hobbies=[唱, 跳, rap, 篮球])

10.传入原生API

@RequestMapping("/handle10")
public void handle10(HttpServletRequest req,HttpServletResponse resp,HttpMethod method) throws IOException {System.out.println("请求方法:" + method);String username = req.getParameter("username");System.out.println(username);resp.getWriter().write("ok " + username);
}

运行结果: 

请求方法:GET
admin

六、响应处理

1.返回JSON:自动将返回的对象转为JSON格式

@RequestMapping("/resp01")
public Person resp01() {Person person = new Person();person.setId(1);person.setName("张三");Address address = new Address();address.setStreet("北七家街道");address.setCity("北京市");address.setState("北京市");address.setZipCode("100000");person.setAddress(address);person.setHobbies(new String[]{"打游戏", "看电影"});return person;
}

2.文件下载

方式一:

@RequestMapping("/download")
public ResponseEntity<InputStreamResource> download() throws IOException {try (FileInputStream fileInputStream = new FileInputStream("G:\\64q\\student\\group9\\baseProj\\src\\main\\webapp\\imgs\\girl.png");) {// 一次性读取所有文件会溢出// byte[] bytes = fileInputStream.readAllBytes();// 解决文件名中文乱码问题String encode = URLEncoder.encode("头像.png", "UTF-8");// 解决文件过大OOM问题(内存溢出)InputStreamResource resource = new InputStreamResource(fileInputStream);return ResponseEntity// 创建一个状态码为 200 (OK) 的响应.ok()// 设置响应的内容类型为二进制流,适用于文件下载。.contentType(MediaType.APPLICATION_OCTET_STREAM)// 内容大小,fileInputStream.available()只是一个估计值,并不一定准确。.contentLength(fileInputStream.available())// 添加响应头,指示浏览器将此响应作为附件下载,并设置下载后的文件名为编码后的文件名。.header("Content-Disposition", "attachment; filename=" + encode)// 设置响应体为 InputStreamResource,即文件内容.body(resource);}
}

方式二:

@AutowiredHttpServletRequest request;@GetMapping("/test1")public ResponseEntity<byte[]> download(String name) throws IOException {//获取文件路径String realPath = request.getServletContext().getRealPath("/save/");//文件的全路径String allPath = realPath + name;//获取下载需要的文件流信息FileInputStream inputStream = new FileInputStream(allPath);//获取流的数组byte[] buffer = new byte[inputStream.available()];//读取inputStream.read(buffer);//文件下载的时候,显示的名字,需要改文件名了,再修改//设置响应的头信息,告诉浏览器,返回的是文件HttpHeaders httpHeaders = new HttpHeaders();//设置响应的头信息,访问文件名中文乱码httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(name,"utf-8"));ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(buffer,httpHeaders, HttpStatus.OK);return responseEntity;}

方式三: 

@AutowiredHttpServletResponse response;@GetMapping("/test2")public void  download2(String name) throws FileNotFoundException, UnsupportedEncodingException {//获取文件路径String realPath = request.getServletContext().getRealPath("/save/");//文件的全路径String allPath = realPath + name;//判断文件是否存在File file = new File(allPath);if (!file.exists()){throw new FileNotFoundException(name+"文件不存在");}//代码能执行到这一行,说明文件肯定存在//编码格式是utf-8的文件名String encodeFileName = URLEncoder.encode(name, StandardCharsets.UTF_8.toString());//设置头信息 headerresponse.setHeader("Content-Disposition","attachment;filename*=UTF-8''"+encodeFileName);//使用 try--with --resources 关闭流try(FileInputStream inputStream = new FileInputStream(file);OutputStream outputStream = response.getOutputStream()){IOUtils.copy(inputStream,outputStream);outputStream.flush();} catch (IOException e) {throw new RuntimeException(e);}}

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

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

相关文章

数据分析的分类和EDIT思维框架

为了服务于企业不同层次的决策&#xff0c;商业数据分析过程需要提供相应的数据科学产出物。 一般而言&#xff0c;数据分析需要经历从需求层、数据层、分析层到输出层四个阶段。 第一个阶段是需求层——确定目标&#xff0c;具体目标需要依据具体的层次进行分析&#xff1a…

实验五 时序逻辑电路部件实验

一、实验目的 熟悉常用的时序逻辑电路功能部件&#xff0c;掌握计数器、了解寄存器的功能。 二、实验所用器件和仪表 1、双 D触发器 74LS74 2片 2、74LS162 1片 3、74194 1片 4、LH-D4实验仪 1台 1.双…

iOS 中的 nil、Nil、NULL、NSNull 僵尸对象和野指针

iOS 中的 nil、Nil、NULL、NSNull 僵尸对象和野指针-CSDN博客 类型含义使用场景示例nil表示一个指向 Objective - C 对象的空指针。在 Objective - C 和 Swift&#xff08;与 Objective - C 交互时&#xff09;中用于表示对象不存在。当一个对象变量没有指向任何有效的对象实例…

JS面试题|[2024-12-28]

1.JS的设计原理是什么&#xff1f; JS引擎 运行上下文 调用栈 事件循环 回调 执行流程&#xff1a; JS引擎将代码解析为电脑可以执行的代码&#xff0c;调用一些API&#xff08;运行上下文&#xff09;让浏览器执行 JS是单线程的&#xff0c;每次从调用栈里面取出来的代码进行调…

全面了解 SQL Server:功能、优势与最佳实践

SQL Server 是微软公司推出的一款关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;广泛应用于企业级数据存储、数据分析、应用开发等领域。作为全球最受欢迎的数据库管理系统之一&#xff0c;SQL Server 提供了强大的功能和工具&#xff0c;支持从小型应用到大型…

jdk动态代理和cglib动态代理对比

jdk动态代理和cglib动态代理对比&#xff1a; CGLIB 和 JDK 动态代理都可以用来在运行时生成代理对象 1. 基本概念 JDK 动态代理&#xff1a;只代理接口&#xff08;interface&#xff09;&#xff0c;无法代理类。它使用 java.lang.reflect.Proxy 类和 java.lang.reflect.I…

攻破 Kioptix Level 1 靶机

找教程然后自己练习&#xff0c;论菜狗的自我修养 基本步骤 1.确定目标IP 2.扫描端口&#xff0c;服务&#xff0c;版本信息&#xff0c;漏洞信息 3.查找漏洞可利用脚本 4.运行脚步 一、信息获取 arp-scan -l nmap -sS -p- -sV -sC -A --min-rate5000 192.168.5.130 二、查…

b站ip属地评论和主页不一样怎么回事

在浏览B站时&#xff0c;细心的用户可能会发现一个有趣的现象&#xff1a;某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测&#xff0c;究竟是什么原因导致了这种情况的发生呢&#xff1f;本文将对此进行深入解析&#xff0c;帮助大家揭开这一…

音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件

通过FFmpeg命令可以将mp4文件转换为ps文件。由于ps文件对应的FFInputFormat结构为&#xff1a; const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),.p.flags …

【数据结构与算法】单向链表

一、什么是链表 链表由一系列节点组成&#xff0c;每个节点都包含一个 data 域&#xff08;存放数据&#xff09;和一个 next 域&#xff08;指向下一节点&#xff09;。链表中的节点可以按照任意顺序存放在内存中&#xff0c;它们之间并不连续。每个节点都记录了下一个节点的地…

【计组】例题课后题

第一章 计算机如何区分指令和数据&#xff1f; 一般来讲&#xff0c;在取指周期中从内存读出的信息是指令流,它流向控制器&#xff1b;而执行周期中从内存读出的信息流是数据流,它由内存流向运算器。 从存放位置看&#xff0c;从代码段取出的是指令流&#xff0c;从数据…

一网多平面

“一网多平面”是一种网络架构概念&#xff0c;具体指的是在一张物理网络之上&#xff0c;逻辑划分出“1N”个平面。以下是对“一网多平面”的详细解释&#xff1a; 定义与构成 01一网多平面 指的是在统一的物理网络基础设施上&#xff0c;通过逻辑划分形成多个独立的网络平面…

跨语言数据格式标准化在 HarmonyOS 开发中的实践

文章目录 前言数据格式标准化的意义数据传递中的痛点标准化的优势 JSON 与 Protocol Buffers 的比较JSONProtocol Buffers HarmonyOS 跨语言数据传递示例示例代码&#xff1a;定义 Protocol Buffers 消息格式生成 Java 和 C 代码示例代码&#xff1a;Java 端序列化与传递数据C …

【Python】基于界面库PyQt5+Qt Dsigner的环境配置和界面绘制

目录 一 安装PyQt5以及PyQt5-tools 二 配置外部开发工具 三 使用Qt Designer设计界面 四 使用PyUIC将ui文件转换为py文件 五 CU分离实现逻辑代码 一 安装PyQt5以及PyQt5-tools 之前做的一些Python脚本、软件都是基于 Tkinter 实现的&#xff0c;其中界面的设计布局是很头疼…

Java读取InfluxDB数据库的方法

本文介绍基于Java语言&#xff0c;读取InfluxDB数据库的方法&#xff0c;包括读取InfluxDB的所有数据库&#xff0c;以及指定数据库中的measurement、field、tag等。 首先&#xff0c;创建一个Java项目&#xff0c;用于撰写代码。如果大家是基于IDEA来创建项目&#xff0c;则可…

嵌入式驱动开发详解7(并发、竞争、中断)

文章目录 前言并发和竞争原子操作自旋锁信号量互斥体 中断中断简介中断API上半部和下半部设备树分析中断号获取源码 后续参考文献 前言 中断会引起线程的切换&#xff0c;并发和竞争也是对线程切换的一种灵活保护和处理&#xff0c;因此这里将中断和并发与竞争放在一块讲解说明…

11.MySQL视图特性

目录 视图基本使用视图规则和限制 视图 视图是一个虚拟表, 其内容有查询定义. 同真实的表一样, 视图包含一系列带有名称的列和行数据. 视图的数据变化会影响到基表, 基表的数据变化也会影响到视图, 这个视图和刚刚讲的ReadView之间没有任何关系. 基本使用 创建视图: create vi…

【RabbitMQ高级篇】消息可靠性问题(1)

目录 1.消息可靠性 1.1.生产者消息确认 1.1.1.修改配置 1.1.2.定义Return回调 1.1.3.定义ConfirmCallback 1.2.消息持久化 1.2.1.交换机持久化 1.2.2.队列持久化 1.2.3.消息持久化 1.3.消费者消息确认 1.3.1.演示none模式 1.3.2.演示auto模式 1.4.消费失败重试机制…

ASO优化之增加应用程序评论行之有效的成功战略

应用评论不仅对于用户信任至关重要&#xff0c;而且对于提高应用可见度、转化率以及整体应用商店优化&#xff08;ASO&#xff09;也至关重要。评论和评分会影响App Store和Google Play平台上算法的排名,这些平台优先考虑具有更高参与度和满意度指标的应用程序。下面,我们将概述…

字符串存储、分割相关总结(strncpy 函数和strtok() 函数相关)

1.想用这些函数都需要导入头文件 #include<string.h> 2.怎么创建字符串并输入 #define maxsize 100 char a[maxsize1];//创建字符串&#xff0c;预留一个位置放\0 【1】scanf("%s",a);//使用 scanf 函数读取不带空格的字符串 【2】fgets(a, sizeof(a), stdi…