第七章:SpringMVC中
第七章:SpringMVC中
7.1:SpringMVC
的视图
SpringMVC
中的视图是View
接口,视图的作用渲染数据,将模型Model
中的数据展示给用户SpringMVC
视图的种类很多,默认有转发视图和重定向视图。
当工程引入jstl
的依赖,转发视图会自动转换为JstlView
,若使用的视图技术为Thymeleaf
,在SpringMVC
的配置文件中配置了Thymeleaf
的视图解析器,由此视图解析器解析之后得到的是ThymeleafView
。
-
ThymeleafView
当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被
SpringMVC
配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀。后缀所得到的最终路径,会通过转发的方式实现跳转。@RequestMapping("/test/view/thymeleaf") public String testThymeleafView() {return "success"; }
-
转发视图
SpringMVC
中默认的转发视图是InternalResoutceView
,SpringMVC
中创建转发视图的情况:当控制器方法中所设置的视图名称以forward:
为前缀时,创建InternalResourceView
视图,此时的视图名称不会被SpringMVC
配置文件中所配置的视图解析器解析,而是会将前缀forward:
去掉,剩余部分作为最终路径通过转发的方式实现跳转。@RequestMapping("/test/view/forward") public String testInternalResourceView() {return "forward:/test/model"; }
-
重定向视图
SpringMVC
中默认的重定向视图是RedirectView
,当控制器方法中所设置的视图名称以redirect:
为前缀时,创建RedirectView
视图,此时的视图名称不会被SpringMVC
配置文件中所配置的视图解析器解析,而是会将前缀redirect:
去掉,剩余部分作为最终路径通过重定向的方式实现跳转。 重定向视图在解析是,会先将
redirect:
前缀去掉,然后会判断剩余部分是否以/
开头,若是则会自动拼接上下文路径。@RequestMapping("/test/view/redirect") public String testRedirectView() {return "redirect:/test/model"; }
-
视图控制器
view-controller
当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理方法使用
view-controller
标签进行表示。<!-- 在Springmvc.xml中配置 --> <!-- 开启mvc的注解驱动 --> <mvc:annotation-driven /><!-- 视图控制器:为当前的请求直接设置视图名称实现页面跳转若设置视图监控器,则只有视图监控器所设置的请求会被处理,其他的请求将全部404,此时必须在配置一个开启mvc的注解驱动的标签--> <mvc:view-controller path="/" view-name="index"></mvc:view-controller>
7.2:RESTful
-
RESTful
简介REST
:Representational State Transfer
,表现层资源状态转移。-
资源
资源是一种看待服务器的方式,即,将服务器看作由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。一个资源可以有一个或多个
URI
来标识。URI
既是资源的名称,也是资源在Web
上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI
与其进行交互。 -
资源的表述
资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器之间转义。资源的表述可以有多种格式。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。
-
状态转移
在客户端和服务器端之间转义(
transfer
)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。
-
-
RESTful
的实现 具体说,就是
HTTP
协议里面,四个表示操作方式的动词:GET
、POST
、PUT
、DELETE
。它们分别对应四种基本操作:GET
用来获取资源,POST
用来新建资源,PUT
用来更新资源,DELETE
用来删除资源。
REST
风格提倡URL
地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为URL
地址的一部分,以保证整体风格的一致性。操作 传统方式 REST
风格查询操作 getUserById?id=1
user/1
—>get
请求方式保存操作 saveUser
user
---->post
请求方式删除操作 deleteUser?id=1
user/1
—>delete
请求方式更新操作 updateUser
user
—>put
请求方式 -
HiddenHttpMethodFilter
创建一个新的模块,
spring_mvc_rest_15
,复用spring_mvc_demo_14
的依赖、web.xml
、springmvc.xml
配置文件、html
页面。-
使用
REST
风格完成查询所有的用户信息// @RequestMapping(value = "/user", method = RequestMethod.GET) @GetMapping("/user") public String getAllUser() {System.out.println("查询所有的用户信息 ----> /user ----> get");return "success"; }
-
使用
REST
风格完成查询单个的用户信息// @RequestMapping(value = "/user/{id}", method = RequestMethod.GET) @GetMapping("/user/{id}") public String getUserById(@PathVariable("id") Integer id) {System.out.println("根据id查询用户信息 ----> /user/" + id + " ----> get");return "success"; }
-
使用
REST
风格完成添加用户信息// @RequestMapping(value = "/user", method = RequestMethod.POST) @PostMapping("/user") public String insertUser() {System.out.println("添加用户信息 ----> /user ----> post");return "success"; }
-
使用
REST
风格完成修改用户信息 由于浏览器只支持发送
get
和post
方式的请求,若要发送put
和delete
请求,需要在web.xml
中配置一个过滤器HiddenHttpMethodFilter
,配置了过滤器之后,发送的请求要满足两个条件,才能将请求方式转换为put
或delete
。- 当前请求的请求方式必须为
post
。 - 当前请求必须传输请求参数
_method
,_method
的值才是最终的请求方式。
<!-- 设置处理请求方式的过滤器 --> <filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern> </filter-mapping>
// @RequestMapping(value = "/user", method = RequestMethod.PUT) @PutMapping("/user") public String updateUser() {System.out.println("修改用户信息 ----> /user ----> put");return "success"; }
<form th:action="@{/user}" method="post"><input type="hidden" name="_method" value="put"><input type="submit" value="修改用户信息"> </form>
- 当前请求的请求方式必须为
-
使用
REST
风格完成删除用户信息// @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE) @DeleteMapping("/user/{id}") public String deleteUser(@PathVariable("id") Integer id) {System.out.println("删除用户信息 ----> /user/" + id + " ----> put");return "success"; }
-
HiddenHttpMethodFilter
原理public class HiddenHttpMethodFilter extends OncePerRequestFilter {private static final List<String> ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));public static final String DEFAULT_METHOD_PARAM = "_method";private String methodParam = DEFAULT_METHOD_PARAM;public void setMethodParam(String methodParam) {Assert.hasText(methodParam, "'methodParam' must not be empty");this.methodParam = methodParam;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {HttpServletRequest requestToUse = request;if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {String paramValue = request.getParameter(this.methodParam);if (StringUtils.hasLength(paramValue)) {String method = paramValue.toUpperCase(Locale.ENGLISH);if (ALLOWED_METHODS.contains(method)) {requestToUse = new HttpMethodRequestWrapper(request, method);}}}filterChain.doFilter(requestToUse, response);}private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {private final String method;public HttpMethodRequestWrapper(HttpServletRequest request, String method) {super(request);this.method = method;}@Overridepublic String getMethod() {return this.method;}} }
-
7.3:SpringMVC
处理ajax
请求
创建一个新的模块,spring_mvc_ajax_16
,复用spring_mvc_rest_15
的依赖、web.xml
、springmvc.xml
配置文件。
-
@RequestBody
@RequestBody
可以获取请求体信息,使用@RequestBody
注解标识控制器方法的形参,当前请求的请求体就会为当前注解锁标识的形参赋值。<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><meta charset="UTF-8"><title>首页</title> </head> <body> <div id="app"><h1>index.html</h1><input type="button" value="测试SpringMVC处理ajax" @click="testAjax()"> </div><script type="text/javascript" th:src="@{/js/vue.js}"></script> <script type="text/javascript" th:src="@{/js/axios.min.js}"></script> <script type="text/javascript">var vue = new Vue({el: "#app",methods: {testAjax() {axios.post("/SpringMVC/test/ajax?id=1001",{username:"admin", password:"123456"}).then(response => {console.log(response.data);});} }}) </script> </body> </html>
@RequestMapping("/test/ajax") public void testAjax(Integer id,@RequestBody String requestBody,HttpServletResponse response)throws IOException{System.out.println("requestBody: " + requestBody);System.out.println("id: " + id);response.getWriter().write("hello, axios"); }
-
@RequestBody
获取json
格式的请求参数使用
@RequestBody
注解将json
格式的请求参数转换为java
对象,需要以下步骤:-
导入
jackson
的依赖<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version> </dependency>
-
在
SpringMVC
的配置文件中设置:<mvc:annotation-driven />
-
在处理请求的控制器方法的形参位置,直接设置
json
格式的请求参数要求转换的java
类型的形参,使用@RequestBody
注解标识即可。
<input type="button" value="使用@RequestBody处理json格式的请求参数" @click="testRequestBody()"><br>
testRequestBody() {axios.post("/SpringMVC/test/RequestBody/json",{username: "admin", password: "123456", age: 23, gender: "男"}).then(response=> {console.log(response.data);}); }
// 根据上面传递的参数自行创建User实体类 @RequestMapping("/test/RequestBody/json") public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {System.out.println(user);response.getWriter().write("hello, RequestBody"); }
-
-
@ResponseBody
@ResponseBody
用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器。@RequestMapping("/test/ResponseBody") @ResponseBody public String testResponseBody() {return "success"; }
<a th:href="@{/test/ResponseBody}">测试@ResponseBody注解响应浏览器数据</a><br>
-
@ResponseBody
响应浏览器josn
数据使用
@ResponseBody
注解响应浏览器json
格式的数据,需要以下步骤:- 导入
jackson
的依赖 - 在
SpringMVC
的配置文件中设置:<mvc:annotation-driven />
- 将需要转换为
json
字符串的java
对象直接作为控制器方法的返回值,使用@ResponseBody
注解标识控制器方法就可以将java
对象直接转换为json
字符串,并响应到浏览器。 - 常用的
java
对象转换为json
的结果- 实体类 ——>
json
对象 map
——>json
对象list
——>list
数组
- 实体类 ——>
<input type="button" value="使用@ResponseBody注解响应json格式的数据" @click="testResponseBody()"><br>
testResponseBody() {axios.post("/SpringMVC/test/ResponseBody/json").then(response => {console.log(response.data);}) }
@RequestMapping("/test/ResponseBody/json") @ResponseBody public List<User> testResponseBodyJson() {User user1 = new User(1001, "admin1", "123456", 20, "男");User user2 = new User(1002, "admin2", "123456", 20, "男");User user3 = new User(1003, "admin3", "123456", 20, "男");List<User> list = Arrays.asList(user1, user2, user3);return list; }
- 导入
-
@RestContrller
注解
@RestContrller
注解是SpringMVC
提供的一个复合注解,标识在控制器的类上,就相当于为添加了@Controller
注解,并且为其中的每个方法添加了@ResponseBody
注解。
7.4:文件上传和下载
-
文件下载
ResponseEntity
用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文使用ResponseEntity
实现下载文件的功能。@RequestMapping("/test/down") public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取服务器中文件的真实路径String realPath = servletContext.getRealPath("img");realPath = realPath + File.separator + "1.jpg";//创建输入流InputStream is = new FileInputStream(realPath);//创建字节数组,is.available()获取输入流所对应文件的字节数byte[] bytes = new byte[is.available()];//将流读到字节数组中is.read(bytes);//创建HttpHeaders对象设置响应头信息MultiValueMap<String, String> headers = new HttpHeaders();//设置要下载方式以及下载文件的名字headers.add("Content-Disposition", "attachment;filename=1.jpg");//设置响应状态码HttpStatus statusCode = HttpStatus.OK;//创建ResponseEntity对象ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);//关闭输入流is.close();return responseEntity; }
-
文件上传
文件上传要求
form
表单的请求方式必须为post
,并且添加enctype="multipart/form-data"
。SpringMVC
中将上传的文件封装到MultipartFile
对象中,通过此对象可以获取文件相关信息。-
添加依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version> </dependency>
-
在
SpringMVC
的配置文件中添加配置<!-- 配置文件上传解析器 id必须为multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> </bean>
-
控制器方法
@RequestMapping("/test/up") public String testUp(MultipartFile photo, HttpSession session) throws IOException {//获取上传的文件的文件名String fileName = photo.getOriginalFilename();//处理文件重名问题String hzName = fileName.substring(fileName.lastIndexOf("."));String uuid = UUID.randomUUID().toString();fileName = uuid + hzName;//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取当前工程下photo目录的真实路径String photoPath = servletContext.getRealPath("photo");//创建photoPath所对应的File对象File file = new File(photoPath);//判断file所对应目录是否存在if(!file.exists()){file.mkdir();}String finalPath = photoPath + File.separator + fileName;//上传文件photo.transferTo(new File(finalPath));return "success"; }
-
相关文章:

第七章:SpringMVC中
第七章:SpringMVC中 7.1:SpringMVC的视图 SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户SpringMVC视图的种类很多,默认有转发视图和重定向视图。 当工程引入jstl的依赖&…...

MySQL数据库——DQL操作——基本查询
文章目录 前言事前准备——测试数据整表查询指定列查找别名查询MySQL运算符条件查询模糊查询排序查询聚合查询分组查询分组之后的条件筛选 分页查询将整张表的数据插入到另一张表中 前言 MySQL数据库常见的操作是增删查改,而其中数据的查询是使用最多,也…...

Electron 开发,报handshake failed; returned -1, SSL error code 1,错误
代码说明 在preload.js代码中,暴露参数给渲染线程renderer.js访问, renderer.js 报:ERROR:ssl_client_socket_impl.cc(978)] failed; returned -1, SSL error code 1,错误 问题原因 如题所说,跨进程传递消息,这意味…...

知识区博主转型——兼做知识区和改造区博主!!!!!
想脱单的进来,一起交流如何能脱单!!! 为什么——我太羡慕有对象的人了哭死!!!!!! 你是不是很羡慕别人怎么都有女朋友 别人家的女朋友怎么都那么好ÿ…...

Resnet与Pytorch花图像分类
1、介绍 1.1数据集介绍 flower_data├── train│ └── 1-102(102个文件夹)│ └── XXX.jpg(每个文件夹含若干张图像)├── valid│ └── 1-102(102个文件夹)└── ─── └── XXX.jp…...
【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分)
接续上文 【NLP概念源和流】 02-稠密文档表示(第 2/20 部分)...

【React】关于组件之间的通讯
🌟组件化:把一个项目拆成一个一个的组件,为了便与开发与维护 组件之间互相独立且封闭,一般而言,每个组件只能使用自己的数据(组件状态私有)。 如果组件之间相互传参怎么办? 那么就要…...

item_get-小红薯-商品详情
一、接口参数说明: smallredbook.item_get,点击更多API调试,请移步注册API账号点击获取测试key和secret 公共参数 请求地址: https://api-gw.onebound.cn/smallredbook/item_get 名称类型必须描述keyString是调用key(http://o0…...

网络安全进阶学习第十课——MySQL手工注入
文章目录 一、MYSQL数据库常用函数二、MYSQL默认的4个系统数据库以及重点库和表三、判断数据库类型四、联合查询注入1、具体步骤(靶场演示):1)首先判断注入点2)判断是数字型还是字符型3)要判断注入点的列数…...

2.3 网络安全协议
数据参考:CISP官方 目录 OSI七层模型TCP/IP体系架构TCP/IP安全架构 一、OSI七层模型 简介 开放系统互连模型(Open System Interconnection Reference Model,OSI)是国际标准化组织(ISO)于1977年发布的…...

Apache Flink概述
Flink 是构建在数据流之上的一款有状态的流计算框架,通常被人们称为第三代大数据分析方案 第一代大数据处理方案:基于Hadoop的MapReduce 静态批处理 | Storm 实时流计算 ,两套独立的计算引擎,难度大(2014年9月&#x…...

django使用mysql数据库
Django开 发操作数据库比使用pymysql操作更简单,内部提供了ORM框架。 下面是pymysql 和orm操作数据库的示意图,pymysql就是mysql的驱动,代码直接操作pymysql ,需要自己写增删改查的语句 django 就是也可以使用pymysql、mysqlclient作为驱动&a…...

MongoDB文档--基本概念
阿丹: 不断拓展自己的技术栈,不断学习新技术。 基本概念 MongoDB中文手册|官方文档中文版 - MongoDB-CN-Manual mongdb是文档数据库 MongoDB中的记录是一个文档,它是由字段和值对组成的数据结构。MongoDB文档类似于JSON对象。字段的值可以包…...

【TypeScript】TS入门及基础学习(一)
【TypeScript】TS入门及基础学习(一) 【TypeScript】TS入门及基础学习(一)一、前言二、基本概念1.强类型语言和弱类型语言2.动态语言和静态语言 三、TypeScript与JavaScript的区别四、环境搭建及演练准备4.1 安装到本地4.2 在线运…...

Dockerfile构建LNMP镜像(yum方式)
目录 Dockerfile构建LNMP镜像 1、建立工作目录 2、编写Dockerfile文件 3、构建镜像 4、测试容器 5、浏览器访问测试: Dockerfile构建LNMP镜像 1、建立工作目录 [roothuyang1 ~]# mkdir lnmp/ [roothuyang1 ~]# cd lnmp/ 2、编写Dockerfile文件 [roothuyang1 …...

Flink Windows(窗口)详解
Windows(窗口) Windows是流计算的核心。Windows将流分成有限大小的“buckets”,我们可以在其上应用聚合计算(ProcessWindowFunction,ReduceFunction,AggregateFunction或FoldFunction)等。在Fl…...

AssetBundle学习
官方文档:AssetBundle 工作流程 - Unity 手册 (unity3d.com) 之前写的博客:AssetBundle学习_zaizai1007的博客-CSDN博客 使用流程图: 1,指定资源的AssetBundle属性 (xxxa/xxx)这里xxxa会生成目录&…...

CompletableFuture原理与实践
文章目录 1 为何需要并行加载2 并行加载的实现方式2.1 同步模型2.2 NIO异步模型2.3 为什么会选择CompletableFuture? 3 CompletableFuture使用与原理3.1 CompletableFuture的背景和定义3.1.1 CompletableFuture解决的问题3.1.2 CompletableFuture的定义 3.2 Complet…...

8.3 作业
整理思维导图 2. 递归实现,输入一个数,输出这个数的每一位 #include <myhead.h> void fun(int t) {if(t 0) return;fun(t/10);printf("%d\n",t%10); } int main(int argc,const char *argv[]) {int t1623809; fun(t);return 0; } 3.递…...
c# COM组件原理
COM(Component Object Model)是一种微软的软件组件技术,用于实现软件组件之间的互操作性。它是一种二进制接口标准,允许不同的软件组件在不同的进程中进行通信。COM组件可以用多种编程语言编写,并且可以在多个应用程序…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
土建施工员考试:建筑施工技术重点知识有哪些?
《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目,核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容,附学习方向和应试技巧: 一、施工组织与进度管理 核心目标: 规…...