【SpringMVC】SpringMVC模型数据+视图解析器

news2024/11/17 17:52:22

目录
一、模型数据-如何将数据存入request域
二、模型数据-如何将数据存入session域
三、@ModelAttribute
四、视图解析器


相关文章

【SpringMVC】入门篇:带你了解SpringMVC的执行流程【SpringMVC】入门篇:带你了解SpringMVC的执行流程
【SpringMVC】使用篇:SpringMVC的开始 【SpringMVC】使用篇:SpringMVC的开始

一、模型数据-如何将数据存入request域

 我们在上一节已经对SpringMVC的基本使用有了一个大致的了解。当但我们提出一个新的需求:如何在request域中存入数据呢❓
方案一:利用上一节所讲的,使用ServletAPI来存入。
方案二:利用SpringMVC的机制,将其自动放入request域。
使用方案二,我们有三种实现方式。

演示需要用到的前端页面:

<h2>测试[HttpServletRequest 放入]</h2>
<hr/>
<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>

获取request域信息的页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>获取数据显示页面</title>
</head>
<body>
<h2>添加主人信息</h2>
<hr/>
${requestScope.master.name}<br/>
${requestScope.master.id}<br/>
${requestScope.master.pet.name}<br/>
${requestScope.master.pet.id}<br/>
<h2>手动放入的信息</h2>
<hr/>
${requestScope.address}
</body>
</html>

方式一

@RequestMapping(value = "/vote05")
public String test05(Master master100,HttpServletRequest request){
    // 除了自动放到request中
    // 我们也可以手动放到request中
    request.setAttribute("address","beijing");
    // 我们也可以修改自动放入request域中的 master对象
    master100.setName("mary");
    // springMVC 默认的是将参数名的 首字母小写 作为request中的key
    // 所以:即使我们的形参名和key不对应,但还是可以修改request中的这个对象的属性值(引用的是同一个对象)
    return "vote_ok";
}
  1. 当我们发送请求,封装到对象之后。SpringMVC底层会将其存到request域中,key是该类的类名首字母小写,这个key和形参名没有任何关系。我们形参最终也是指向了这个对象(同一个引用),所以当我们在Handler方式中修改这个对象的值之后,request域中的对象的值也会改变。

方式二

@RequestMapping(value = "/vote06")
public String test06(Master master100, Map<String,Object> map){
    // 通过map对象,将数据放入到request当中
    // 原理:springMVC会遍历我们的这个Map集合,将我们Map的key-val放入到request当中。
    map.put("address","shanghai");

    // 如果我们的map中存在和request中的key重复的情况的话,map中的val会覆盖request原来的那个val
    map.put("master",null);
    return "vote_ok";
}
  1. 当我们的Handler方法的形参中有一个Map对象的时候,springMVC会遍历我们的这个Map集合,将我们Map的key-val放入到request域当中。
  2. 如果我们的map中存在和request中的key重复的情况的话,map中的val会覆盖request原来的那个val。

方式三

@RequestMapping(value = "/vote07")
public ModelAndView test07(Master master100){
    ModelAndView modelAndView = new ModelAndView();
    // 将属性放入到modelAndView
    modelAndView.addObject("address","shenzhen");
    // 同样的,我们要是有相同的key。他就会覆盖request原有的val
    modelAndView.addObject("master",null);
    // 指定跳转的视图名称
    modelAndView.setViewName("vote_ok");
    return modelAndView;
}

 我们在前边在调用Handler方法最后会返回一个字符串,其实本质是返回了一个ModelAndView。所以这里我们可以通过创建一个ModelAndView来将其存到request域中。

二、模型数据-如何将数据存入session域

 我们这里使用的是ServletAPI,可以通过HttpSession作为形参传进来。也可以通过HttpServletRequest获取Session对象。

/**
 * 测试如何将数据放到session域中
 * @return
 */
@RequestMapping(value = "/vote08")
public String test08(Master master,HttpSession session){
    // master默认是放在request域中的
    // 将master放入session中
    session.setAttribute("master",master);
    session.setAttribute("address","guangzhou");
    return "vote_ok";
}

三、@ModelAttribute

@ModelAttribute的功能有点像我们的前置通知,它可以在当前的Handler中的方法执行前进行业务的操作。

/**
* 问题的提出?
*      当我们在执行Handler之前,需要执行一些前置的工作。如何做到?
* 答案:
*      @ModelAttriibute
*/
@ModelAttribute
public void prepareModel(){
   // 当我们调用其他的Handler的时候。都会执行这个前置方法
   // 它的底层是我们的AOP
   System.out.println("前置工作....");
}

四、视图解析器

 还记得在环境搭建的时候,我们在Spring配置文件中配置了一个默认视图解析器。在正式的了解它之前,我们先来了解一下另外一个:自定义视图解析器这里说的自定义视图解析器,是解析我们自定义视图的解析器。并不是我们自定义一个解析器(有没有感juo有点绕😋)
下边来对其进行演示。

自定义视图解析器

前端的页面

<%@ 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>
</body>
</html>

需要跳转的页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>my_view页面</title>
</head>
<body>
<h1>进入到my_view页面</h1>
<p>是从自定义视图来的</p>
</body>
</html>

自定义视图类

package com.jl.web.viewreslover;

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;

/**
 * ClassName: Myview
 * Package: com.jl.web.viewreslover
 * Description: 自定义视图类
 *
 * @Author: Long
 * @Create: 2022/11/27 - 16:27
 * @Version: v1.0
 */

/**
 * 继承了 AbstractView 就可以作为一个视图
 * @Component(value = "myView"),该视图会注入到容器中,名字是myView(可以理解为是一个视图名)
 */
@Component(value = "myView")
public class MyView extends AbstractView {
    @Override
    protected void renderMergedOutputModel(Map<String, Object> model,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        // 完成视图渲染
        // 并且可以确定我们要跳转的页面【请求转发】
        System.out.println("进入到我们自己的视图....");
        request.getRequestDispatcher("/WEB-INF/pages/my_view.jsp").forward(request,response);
    }
}

Handler

@RequestMapping(value = "/goods")
@Controller
public class GoodsHandler {
@RequestMapping(value = "/buy")
public String buy(){
    System.out.println("buy()...");
    return "myView";
}

配置自定义视图解析器

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
    <property name="order" value="99"/>
</bean>
  1. BeanNameViewResolver:可以去解析我们自定义的视图。
  2. order :表示视图解析器的执行顺序,值越小优先级越高。默认order是Integer.MAX_VALUE
  3. 注意:我们必须保证自定义视图解析器的执行顺序在默认的视图解析器之前。

梳理
到了这里,肯定很多朋友没看懂这都干了些啥。我们通过下面的一张图来梳理一下:
在这里插入图片描述

默认视图解析器

 相较于我们的自定义视图解析器,默认的视图解析器它封装了很多东西。在使用的时候,我们只是在目标方法中使用了一个return xxx,返回了一个字符串。但它又是如何进行请求转发和重定向的,这将是我们下面将要探讨的问题❓

 这个字符串也是视图名称,而这个视图是SpringMVC帮我们来创建的。
我们通过Debug来看一下(这里演示的是重定向)。

  1. 发送请求,中央控制器首先会拦截请求。
    在这里插入图片描述
  2. 通过反射调用目标Handler。
    在这里插入图片描述
  3. 返回模型数据(ModelAndView)。在这里插入图片描述
  4. 拿到视图名称(就是return xxx)。
  5. 处理返回的结果。在这里插入图片描述
  6. 做视图的渲染。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    到这一步,我们可以看到。他和自定义视图解析器一样,都是继承了AbstractView调用renderMergedOutputModel。我们继续来看一下它的内部都干了什么:
    在这里插入图片描述
    在内部它真正的调用了我们原生Servlet的API,进行了请求的重定向。当然请求重定向流程也是一样的,但它对应的视图不是RedircetView

最后我们来通过一张图梳理一下,清楚我们这里详解的是哪一步:
在这里插入图片描述

如果文章中有描述不准确或者错误的地方,还望指正。您可以留言📫或者私信我。🙏
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~🙏🙏🙏

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

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

相关文章

springboot整合swagger

特别说明&#xff1a;本次项目整合基于idea进行的&#xff0c;如果使用Eclipse可能操作会略有不同&#xff0c;不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

node.js+uni计算机毕设项目儿童健康成长档案小程序(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

暂时性死区以及函数作用域

暂时性死区 暂时性死区也就是变量声明到声明完成的区块&#xff0c;这个区块是一个封闭的作用域&#xff0c;直到声明完成。 如果在变量声明之前使用该变量&#xff0c;那么该变量是不可用的&#xff0c;也就被称为暂时性死区。 var 没有暂时性死区&#xff0c;因为var存在变…

Python编程 递归函数

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.函数执行注意点 二.递归函数 1.递归的介绍 2.例子 前言 本章将会讲解…

新版H5微信网页JS-SDK自定义分享功能实现

1.先用 微信官方文档demo&#xff0c;下载下来去改就行&#xff0c; 概述 | 微信开放文档 2.&#xff08;后端&#xff09;填写上认证后的&#xff0c;公众号appid&#xff0c;appsecret。 3.&#xff08;前端代码&#xff09; 配置好需要的接口&#xff08;调试打开debug&a…

自研框架(Webx)整合Zuul网关工作总结

写在前面&#xff0c;最近被分配了一个技术任务&#xff0c;简单描述为自研框架&#xff08;类比Spring&#xff09;整合一个微服务网关&#xff0c;并且能用就行。 有人可能会问&#xff0c;想用微服务网关&#xff0c;不是直接引入zuul或者gateway相关的依赖&#xff0c;然后…

【Pandas入门教程】如何合并多个表中的数据

如何合并多个表中的数据 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 笔记托管&#xff1a;https://gitee.com/DingJiaxiong/machine-learning-study 文章目录如何合并多个表中的数据导包数据准备【1】…

Linux系统基础——文件子系统

title: Linux系统文件子系统 date: 2022-12-18 15:48:24 modify: 2022-12-18 16:48:43 author: wangjianfeng tags: 001-computer-technology, OS, Linux aliases: Linux系统文件子系统 特此说明: 刘超的趣谈linux操作系统是比较重要的参考资料&#xff0c;本文大部分内容和图…

腾讯云轻量应用服务器搭建LAMP 开发环境

LAMP&#xff08;LinuxApacheMySQLPHP&#xff09;是目前国际流行的 Web 应用框架&#xff0c;包括了 Linux 操作系统、Apache Web 服务器、MySQL/MariaDB 数据库和 PHP 编程语言环境以及相关组件支持。 说明 LAMP 应用镜像底层基于 CentOS 7.6 64位操作系统。 登录 轻量应用服…

做一个极简 UI 库之代码 lint

eslint, prettier, stylelint 的配置 这三个规则的配置思路&#xff1a;代码美化用 prettier&#xff0c;逻辑代码用 eslint 校验&#xff0c;样式代码用 stylelint 校验。有跟代码美化冲突的以 prettier 为主 为什么要用这么多呢&#xff0c;因为 eslint 不能解析样式代码&a…

数据结构---LRU算法

LRU算法哈希链表自己的JAVA实现LRU全称Least Recently Used&#xff0c;也就是 最近最少使用的意思&#xff0c;是一种内存管理算法&#xff0c;该算法最早应用于Linux操作系统。这个算法基于一种假设&#xff1a;长期不被使用的数据&#xff0c;在未来被用到的几率也不大。因此…

【LeetCode】1754. 构造字典序最大的合并字符串

构造字典序最大的合并字符串 题目描述 给你两个字符串 word1 和 word2 。你需要按下述方式构造一个新字符串 merge &#xff1a;如果 word1 或 word2 非空&#xff0c;选择 下面选项之一 继续操作&#xff1a; 如果 word1 非空&#xff0c;将 word1 中的第一个字符附加到 mer…

node.js+uni计算机毕设项目基于微信小程序校园生活管理LW(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

基于形态学处理的不规则形状图像的几何参数统计,包括输出面积,周长,圆度,矩形度,伸长度

up目录 一、理论基础 二、核心程序 三、测试结果 一、理论基础 形态学是图像处理中应用最为广泛的技术之一&#xff0c;主要用于从图像中提取对表达和描绘区域形状有意义的图像分量&#xff0c;使后续的识别工作能够抓住目标对象最为本质的形状特征&#xff0c;如边界和连通…

C#语言实例源码系列-实现文件分割和合并

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过程中…

腾讯云轻量应用服务器使用 WooCommerce 应用镜像搭建电商独立站

WooCommerce 是当前很受欢迎的电商独立站建站工具&#xff0c;具备开源、免费、使用简单且功能强大等特点&#xff0c;您可通过该镜像快速搭建基于 WordPress 的电商独立站。该镜像已预装 WordPress&#xff08;包含 WooCommerce 插件&#xff09;、Nginx、MariaDB、PHP 软件。…

数据结构之排序【直接选择排序和堆排序的实现及分析】内含动态演示图

文章目录引言&#xff1a;1.直接选择排序2.堆排序3.直接选择排序和堆排序的测试引言&#xff1a; 感觉今天更冷了&#xff0c;码字更加的不易&#xff0c;所以引言就简单的写一下啦&#xff01;今天我们就来了解一下什么是直接选择排序和堆排序。 1.直接选择排序 时间复杂度…

RabbitMQ 第一天 基础 4 RabbitMQ 的工作模式 4.1 Work queues 工作队列模式

RabbitMQ 【黑马程序员RabbitMQ全套教程&#xff0c;rabbitmq消息中间件到实战】 文章目录RabbitMQ第一天 基础4 RabbitMQ 的工作模式4.1 Work queues 工作队列模式4.1.1 模式说明4.1.2 代码编写4.1.3 小结第一天 基础 4 RabbitMQ 的工作模式 4.1 Work queues 工作队列模式 …

ELK第四讲之【docker安装Logstash8.4.3、集成springboot】

docker安装elasticsearch8.4.3 docker安装kibana8.4.3 一、docker安装logstash8.4.3 官方地址 https://github.com/elastic/logstash/releases 1、拉取镜像 docker pull elastic/logstash:8.4.3 2、启动容器 docker run -it -d --name logstash -p 9600:9600 -p 5044:…

十六、Docker Compose容器编排第一篇

1、概述 Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用 Compose&#xff0c;您可以使用 YAML 文件来配置应用程序的服务。然后&#xff0c;使用一个命令&#xff0c;您可以从您的配置中创建并启动所有服务。 Compose 适用于所有环境&#xff1a;生产、暂存、…