SpringMVC框架学习笔记(四):模型数据 以及 视图和视图解析器

模型数据处理-数据放入 request

说明:开发中, 控制器/处理器中获取的数据如何放入 request 域,然后在前端(VUE/JSP/...)取出显 示

1.1 方式 1: 通过 HttpServletRequest 放入 request

(1)前端发送请求

<h1>添加主人信息</h1>
<form action="vote/vote05" method="post">主人号:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>宠物号:<input type="text" name="pet.id"><br>宠物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和宠物">
</form>

(2)后端接收请求

springmvc会自动把获取的model模型,放入到request域中

/*** 1. 将提交的数据封装到java对象->springmvc 会自动的将其放入到request域* 2. 这样我们就可以在跳转到的页面取出数据.*/
@RequestMapping(value = "/vote05")
public String test05(Master master, HttpServletRequest request) {//1. springmvc会自动把获取的model模型,放入到request域中,名字就是master//2. 也可以手动将master放入到requestrequest.setAttribute("address", "beijing");//3. 如果我们希望修改master的属性值master.setName("nono");//4. 分析一下springmvc默认存放对象到request域中,属性名是//   request域 ("master", master) 属性名是类名/类型名 首字母小写//返回到一个结果return "vote_ok";
}

(3)跳转页面

<h1>获取的的数据显示页面</h1>
<hr>
取出 request域的数据-通过 el表达式来获取
<br>
address: ${requestScope.address}<br>
主人名字= ${requestScope.master.name}
主人id= ${requestScope.master.id}
宠物名字= ${requestScope.master.pet.name}

(4)页面显示结果

1.2 方式 2: 通过请求的方法参数 Map<String,Object> 放入 request

(1)前端发送请求

<h1>添加主人信息[测试 Map ]</h1>
<form action="vote/vote06" method="post">主人号:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>宠物号:<input type="text" name="pet.id"><br>宠物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和宠物">
</form>

(2)后端接收请求

/*** 通过Map<String,Object> 设置数据到request域*/
@RequestMapping(value = "/vote06")
public String test06(Master master, Map<String, Object> map) {//1. 需求是通过map对象,添加属性到request中//2. 原理分析:springmvc会遍历map,然后将map的k-v, 存放到request域map.put("address", "beijing...");//返回到一个结果return "vote_ok";
}

(3)跳转页面同方式1

(4)页面显示结果

1.3 方式 3: 通过返回 ModelAndView 对象 实现 request 域数据

(1)前端发送请求

<h1>添加主人信息[测试ModelAndView]</h1>
<form action="vote/vote07" method="post">主人号:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>宠物号:<input type="text" name="pet.id"><br>宠物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和宠物">
</form>

(2)后端接收请求

说明:

  • 从本质看,请求响应的方法 return "xx", 是返回了一个字符串,其实本质是返回了一个 ModelAndView 对象,只是默认被封装起来的.
  • ModelAndView 即可以包含 model 数据,也可以包含视图信息
  • ModelAndView 对象的 addObject 方法可以添加 key-val 数据,默认在 request 域中
  • ModelAndView 对象 setView 方法可以指定视图名称
/*** 通过返回ModelAndView对象,将数据放入到request域*/
@RequestMapping(value = "/vote07")
public ModelAndView test07(Master master) {System.out.println("----test07----");ModelAndView modelAndView = new ModelAndView();//放入属性到modelAndView对象modelAndView.addObject("address", "shanghai");//可以把从数据库得到的数据->对象,放入modelAndView//这里指定跳转的视图名称modelAndView.setViewName("vote_ok");//返回结果return modelAndView;
}

(3)跳转页面同方式1

(4)页面显示结果

2 模型数据处理-数据放入 session

说明:开发中, 控制器/处理器中获取的数据如何放入 session 域,然后在前端(VUE/JSP/...)取出显 示

应用实例:

(1)前端发送请求

<h1>添加主人信息[测试session]</h1>
<form action="vote/vote08" method="post">主人号:<input type="text" name="id"><br>主人名:<input type="text" name="name"><br>宠物号:<input type="text" name="pet.id"><br>宠物名:<input type="text" name="pet.name"><br><input type="submit" value="添加主人和宠物">
</form>

(2)后端接收请求

/*** 将数据设置到session域中*/
@RequestMapping(value = "/vote08")
public String test08(Master master, HttpSession httpSession) {System.out.println("----test08----");//master对象是默认放在request域//这里将master对象放入到session域httpSession.setAttribute("master", master);httpSession.setAttribute("address", "guangzhou");return "vote_ok";//请求转发
}

(3)跳转页面

取出 session域的数据 <br>
address: ${sessionScope.address}<br>
主人名字= ${sessionScope.master.name}
主人信息= ${sessionScope.master}

(4)页面显示结果

3 @ModelAttribute 实现 prepare 方法

说明:开发中,有时需要使用某个前置方法(比如 prepareXxx(), 方法名由程序员定)给目标方法准 备一个模型对象

@ModelAttribute 注解可以实现 这样的需求,在某个方法上,增加了@ModelAttribute 注解后 那么在调用该 Handler 的任何一个方法时,都会先调用这个方法

案例:

/*** 1. 当Handler的方法被标识 @ModelAttribute,就视为一个前置方法* 2. 当调用该Handler的其它的方法时,都会先执行该前置方法* 3. 类似Spring中AOP的前置通知[底层是AOP机制]* 4. prepareModel前置方法,会切入到其它方法前执行*/
@ModelAttribute
public void prepareModel(){System.out.println("prepareModel()-----完成准备工作-----");
}

使用场景举例:

修改用户信息(就是经典的使用这种机制的应用),流程如下:

1. 在修改前,在前置方法中从数据库查出这个用户

2. 在修改方法(目标方法)中,可以使用前置方法从数据库查询的用户

3. 如果表单中对用户的某个属性修改了,则以新的数据为准,如果没有修改,则以数据库 的信息为准,比如,用户的某个属性不能修改,就保持原来的值 

4 视图和视图解析器

4.1 基本介绍

(1)在 springMVC 中的目标方法最终返回都是一个视图(有各种视图).

(2)返回的视图都会由一个视图解析器来处理 (视图解析器有很多种)

4.2 自定义视图

4.2.1 为什么需要自定义视图

(1)在默认情况下,我们都是返回默认的视图, 然后这个返回的视图交由 SpringMVC 的 InternalResourceViewResolver 视图处理器来处理的

<!--下面配置springMVC的视图解析器,如果我们的controller return 的是 login_ok
那么要跳转的页面页面就是 /WEB-INF/pages/login_ok-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--配置属性suffix(后缀) 和 prefix(前缀)--><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/>
</bean>

(2)在实际开发中,我们有时需要自定义视图,这样可以满足更多更复杂的需求.

4.2.2 自定义视图实例-代码实现

(1)配置 applicationContext-mvc, 增加自定义视图解析器

<!--
1. 配置自定义视图解析器BeanNameViewResolver
2. BeanNameViewResolver可以去解析我们自定义的视图
3. 配置 属性 order, 表示视图解析器执行的顺序, 值越小, 优先级越高
4. 属性 order 的默认值是最低优先级 ,值为 Integer.MAX_VALUEint LOWEST_PRECEDENCE = 2147483647
-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"><property name="order" value="99"/>
</bean>

(2)创建 MyView.java - 自定义视图类

package com.web.viewresolver;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.AbstractView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;/*** 1. MyView继承了AbstractView, 就可以作为一个视图使用* 2. @Component(value = "myView"),该视图会注入到容器中, 名字/id是 myView*/
@Component(value = "myView")
public class MyView extends AbstractView {@Overrideprotected void renderMergedOutputModel(Map<String, Object> model,HttpServletRequest request,HttpServletResponse response) throws Exception {//完成视图渲染//并且可以确定我们要跳转的页面 [请求转发]System.out.println("进入到自己的视图..");//1. 下面就是进行请求转发到 /WEB-INF/pages/my_view.jsp//2. /WEB-INF/pages/my_view.jsp 会被springmvc解析成 /springmvc/WEB-INF/pages/my_view.jsprequest.getRequestDispatcher("/WEB-INF/pages/my_view.jsp").forward(request, response);}
}

(3)创建 GoodsHandler.java

@RequestMapping("/goods")
@Controller
public class GoodsHandler {@RequestMapping(value = "/buy")public String buy() {System.out.println("------buy()-----");// 这里返回自定义视图类在容器中的名字/idreturn "myView";}
}

(4)创建 web\view.jsp 和 /WEB-INF/pages/my_view.jsp 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>自定义视图测试</title>
</head>
<body>
<h1>自定义视图测试</h1>
<a href="goods/buy">点击到自定义视图-</a><br/>
<a href="goods/order">测试在目标方法中指定请求转发或者重定向的页面-</a><br/>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>my_view页面</title>
</head>
<h1>进入到my_view页面</h1>
<p>是从自定义视图来的..</p>
<body></body>
</html>

 (5)效果如下

初始页面:

跳转页面:

4.2.3 自定义视图工作流程小结

自定义视图-小结

  • 自定义视图: 创建一个 View 的 bean, 该 bean 需要继承自 AbstractView, 并实现 renderMergedOutputModel 方法.
  • 需要把自定义 View 加入到 IOC 容器中
  • 自定义视图的视图处理器,使用 BeanNameViewResolver, 这个视图处理器也需要配置 到 ioc 容器
  • BeanNameViewResolver 的调用优先级需要设置一下,设置 order 比 Integer.MAX_VAL 小的值. 以确保其在 InternalResourceViewResolver 之前被调用

自定义视图-工作流程

  • SpringMVC 调用目标方法, 返回自定义 View 在 IOC 容器中的 id
  • SpringMVC 调用 BeanNameViewResolver 解析视图: 从 IOC 容器中获取 返回 id 值对 应的 bean, 即自定义的 View 的对象
  • SpringMVC 调用自定义视图的 renderMergedOutputModel 方法渲染视图
  • 说明: 如果在 SpringMVC 调用目标方法, 返回自定义 View 在 IOC 容器中的 id, 不存在, 则仍然按照默认的视图处理器机制处理。但是如果先按照默认视图解析器进行解析,就是解析出来的页面不存在,也不会进入到自定义解析器,而会直接报错

4.3 目标方法直接指定转发或重定向

4.3.1 说明

(1)默认返回的方式是请求转发,然后用视图处理器进行处理,比如在目标方法中这样写:

@RequestMapping(value = "/login")
public String login(){System.out.println("login ok....");return "login_ok";
}

(2)也可以在目标方法直接指定重定向或转发的 url 地址

(3)如果指定重定向,不能定向到 /WEB-INF 目录中,因为这个目录是tomcat的一个类路径

4.3.2 应用实例

(1)修改 GoodsHandler.java, 增加方法 order() 

/*** 演示直接指定要请求转发的或者是重定向的页面*/
@RequestMapping(value = "/order")
public String order() {System.out.println("=======order()=====");//请求转发到 /WEB-INF/pages/my_view.jsp//forward 关键字表示请求转发//请求转发可以到/WEB-INF/ 目录下,也可以转发到这个目录外面的页面//下面的 /WEB-INF/pages/my_view.jsp 会被解析成 /springmvc/WEB-INF/pages/my_view.jsp//return "forward:/WEB-INF/pages/my_view.jsp"; // 等价于 return "my_view.jsp"//请求转发到/WEB-INF/目录外面的页面//return "forward:/aaa/bbb/ok.jsp";//直接指定要重定向的页面//1. 对于重定向来说,可以重定向到web目录,不能重定向到 /WEB-INF/ 目录下//2. redirect 关键字,表示进行重定向//3. /login.jsp 在服务器解析 /springmvc/login.jspreturn "redirect:/login.jsp";// /WEB-INF/pages/my_view.jsp 被解析 /springmvc/WEB-INF/pages/my_view.jsp 该路径是访问不到的//return "redirect:/WEB-INF/pages/my_view.jsp";//这样写会报错
}

 (2)前端发出请求

<a href="goods/order">测试在目标方法中指定请求转发或者重定向的页面-</a><br/>

 (3)跳转页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>登录成功</title>
</head>
<body>
<h1>恭喜 登录成功</h1>
</body>
</html>

(4)跳转成功

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

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

相关文章

基于RNN和Transformer的词级语言建模 代码分析 _generate_square_subsequent_mask

基于RNN和Transformer的词级语言建模 代码分析 _generate_square_subsequent_mask flyfish Word-level Language Modeling using RNN and Transformer word_language_model PyTorch 提供的 word_language_model 示例展示了如何使用循环神经网络RNN(GRU或LSTM)和 Transforme…

【AI大模型】如何让大模型变得更聪明?基于时代背景的思考

【AI大模型】如何让大模型变得更聪明 前言 在以前&#xff0c;AI和大模型实际上界限较为清晰。但是随着人工智能技术的不断发展&#xff0c;基于大规模预训练模型的应用在基于AI人工智能的技术支持和帮助上&#xff0c;多个领域展现出了前所未有的能力。无论是自然语言处理、…

JavaScript的垃圾回收机制

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、垃圾…

匹配字符串

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Python提供了re模块&#xff0c;用于实现正则表达式的操作。在实现时&#xff0c;可以使用re模块提供的方法&#xff08;如search()、match()、finda…

信息系统项目管理师0603:项目整合管理 — 考点总结(可直接理解记忆)

点击查看专栏目录 文章目录 项目整合管理 — 考点总结(可直接理解记忆) 输入、输出、工具和技术 历年考题直接考输入,输出、工具和技术的有17年11月第34、35,19年5月第34、35,20年11月27、28,21年5月第26,28,21年11月第28,22年5月第25,22年11月第22考题 项目章程是正…

CasaOS玩客云安装全平台高速下载器Gopeed并实现远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于Python的酒店客房入侵检测系统的设计与实现

基于Python的酒店客房入侵检测系统的设计与实现 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 酒店客房入侵管理界面 结合上文的结构搭建和用户需求&#xff0c;酒店客房入侵检测系统的…

【Unity Shader入门精要 第12章】屏幕后处理效果(一)

1. 原理和过程 屏幕后处理是绑定摄像机的&#xff0c;通过抓取当前摄像机渲染的图像作为 SrcTextrue&#xff0c;然后按需依次调用处理接口&#xff0c;对 SrcTexture 进行处理&#xff0c;最后将处理完成的 DstTexture 显示到屏幕上&#xff0c;整个过程的调度通过 C# 脚本完…

【机器学习】Adaboost: 强化弱学习器的自适应提升方法

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 Adaboost: 强化弱学习器的自适应提升方法引言Adaboost基础概念弱学习器与强学习…

【蓝桥杯嵌入式】 第六届国赛

目录 题目 配置 注意事项 代码 - 默写大师 EEPROM读写函数 LED驱动函数 ADC采集 上电初始化 LCD 按键 PWM互补输出 全部代码 hardware.c hardware.h control.c control.h main.c 题目 配置 注意事项 复制LCD的工程&#xff0c;先配置资源 --- 勾选完选项一…

CCIG 2024:合合信息文档解析技术突破与应用前景

目录 背景当前大模型训练和应用面临的问题训练Token耗尽训练语料质量要求高LLM文档问答应用中文档解析不精准 合合信息的文档解析技术1. 具备多文档元素识别能力2. 具备版面分析能力3. 高性能的文档解析4. 高精准、高效率的文档解析文档多板式部分示例 文档解析典型技术难点元素…

案例|开发一个美业小程序,都有什么功能

随着移动互联网的迅猛发展&#xff0c;美业连锁机构纷纷寻求数字化转型&#xff0c;以小程序为载体&#xff0c;提升服务效率&#xff0c;增强客户体验。 线下店现在面临的困境&#xff1a; 客户到店排队时间过长&#xff0c;体验感受差 新客引流难&#xff0c;老用户回头客…

基于EV54Y39A PIC-IOT WA的手指数量检测功能开发(MPLAB+ADC)

目录 项目介绍硬件介绍项目设计开发环境及工程参考总体流程图硬件基本配置光照传感器读取定时器检测逻辑 功能展示项目总结 &#x1f449; 【Funpack3-2】基于EV54Y39A PIC-IOT WA的手指数量检测功能开发 &#x1f449; Github: EmbeddedCamerata/PIC-IOT_finger_recognition 项…

Flutter基础 -- Dart 语言 -- 注释函数表达式

目录 1. 注释 1.1 单行注释 1.2 多行注释 1.3 文档注释 2. 函数 2.1 定义 2.2 可选参数 2.3 可选参数 默认值 2.4 命名参数 默认值 2.5 函数内定义 2.6 Funcation 返回函数对象 2.7 匿名函数 2.8 作用域 3. 操作符 3.1 操作符表 3.2 算术操作符 3.3 相等相关的…

上海亚商投顾:沪指冲高回落 两市成交金额仅剩7000亿

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日冲高回落&#xff0c;午后一度集体翻绿&#xff0c;临近尾盘小幅回升。光伏产业链再度走强&#…

aws 在ecs外部实例上运行gpu负载

参考资料 https://docs.amazonaws.cn/zh_cn/AmazonECS/latest/developerguide/ecs-gpu.htmlhttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/accelerated-computing-instances.html#gpu-instanceshttps://docs.amazonaws.cn/AWSEC2/latest/UserGuide/install-nvidia-drive…

LeetCode 63.不同路径Ⅱ

思路&#xff1a; 在有障碍物的地方增加一个判断即可 class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {int dp[105][105];int mobstacleGrid.size();int nobstacleGrid[0].size();for(int i0;i<m;i){for(int j0…

K8s集群之 存储卷 PV PVC

目录 默写 1 如何将pod创建在指定的Node节点上 2 污点的种类(在node上设置) 一 挂载存储​​​​​​​ 1 emptyDir存储卷 2 hostPath存储卷 ①在 node01 节点上创建挂载目录 ② 在 node02 节点上创建挂载目录 ③ 创建 Pod 资源 ④ 在master上检测一下&#xff1a;…

C++ vector 模拟实现

vector的底层也是一个动态数组&#xff0c;他与 string 的区别就是&#xff0c;string 是专门用来存储字符类数据的&#xff0c;为了兼容C语言&#xff0c;使用C语言的接口&#xff0c;在string的动态数组内都会都开一块空间用来存 \0 &#xff0c;而vector则不会。 首先我们要…

【Linux多线程】认识多线程创建线程

文章目录 什么是多线程为什么称linux下的线程是轻量级进程呢&#xff1f; 线程的优点线程的缺点线程异常线程和进程创建线程1.pthread_create2.pthread_self 什么是多线程 进程是正在运行的程序的实例&#xff0c;而线程&#xff08;thread&#xff09;是进程中的一个执行路线…