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放入到request
    request.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_VALUE
   int 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 {
    @Override
    protected 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.jsp
        request.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()-----");
        // 这里返回自定义视图类在容器中的名字/id
        return "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.jsp
    return "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)跳转成功

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅谈线性化

浅谈线性化 原文&#xff1a;浅谈线性化 - 知乎 (zhihu.com) All comments and opinions expressed on Zhihu are mine alone and do not necessarily reflect those of my employers, past or present. 本文内容所有内容仅代表本人观点&#xff0c;和Mathworks无关 (这里所说…

视频汇聚EasyCVR视频监控云平台对接GA/T 1400视图库对象和对象集合XMLSchema描述

GA/T 1400协议主要应用于公安系统的视频图像信息应用系统&#xff0c;如警务综合平台、治安防控系统、交通管理系统等。在城市的治安监控、交通管理、案件侦查等方面&#xff0c;GA/T 1400协议都发挥着重要作用。 以视频汇聚EasyCVR视频监控资源管理平台为例&#xff0c;该平台…

探索UWB模块的多功能应用——UWB技术赋能智慧生活

超宽带&#xff08;Ultra-Wideband, UWB&#xff09;技术&#xff0c;凭借其高精度、低功耗和强抗干扰能力&#xff0c;正在成为智能家居领域的一项关键技术。UWB模块的应用不仅提高了智能家居设备的性能&#xff0c;还为家庭安全、设备管理和用户体验带来了显著的改善。 UWB模…

java基础-chapter15(io流)

io流&#xff1a;存储和读取数据的解决方案 I:input O:output io流的作用&#xff1a;用于读写数据&#xff08;本地文件,网络&#xff09; io流按照流向可以分为&#xff1a; 输出流&#xff1a;程序->文件 输入流&#xff1a;文件->程序 io流按照操作文件…

Qt Creator(Qt 6.6)拷贝一行

Edit - Preference - Environment&#xff1a; 可看到&#xff0c;拷贝一行的快捷键是&#xff1a; ctrl Ins

使用KEPServer连接欧姆龙PLC获取对应标签数据(标签值类型改为字符串型)

1.创建通道&#xff08;通道&#xff09;&#xff0c;&#xff08;选择对应的驱动&#xff0c;跟当前型号PLC型号对应&#xff09;。 2.创建设备&#xff0c;&#xff08;填入IP地址以及欧姆龙的默认端口号&#xff1a;44818&#xff09; 3.创建对应的标签。这里关键讲诉下字…

医院该如何应对网络安全?

在线医生咨询受到很多人的关注&#xff0c;互联网医疗行业的未来发展空间巨大&#xff0c;但随着医院信息化建设高速发展 医院积累了大量的患者基本信息、化验结果、电子处方、生产数据和运营信息等数据 这些数据涉及公民隐私、医院运作和发展等多因素&#xff0c;医疗行业办…

[C/C++]_[初级]_[在Windows平台上导出DLL函数接口的一些疑问]

场景 最近看了《COM本质论》里关于如何设计基于抽象基类作为二进制接口,把编译器和链接器的实现隐藏在这个二进制接口中,从而使用该DLL时不需要重新编译。在编译出C接口时,发现接口名直接是函数名,比如BindNativePort,怎么不是_BindNativePort?说明 VC++导出的函数默认是使…

Notepad++ 常用

File Edit search view Encoding Language Settings Tools Macro Run Plugins Window 文件 编辑 搜索 视图 编码 语言 设置 工具 宏 运行 插件 窗口 快捷方式 定位行 &#xff1a;CTRL g查找&#xff1a; CTRL F替换&am…

精准检测,安全无忧:安全阀检测实践指南

安全阀作为一种重要的安全装置&#xff0c;在各类工业系统和设备中发挥着举足轻重的作用。 它通过自动控制内部压力&#xff0c;有效防止因压力过高而引发的设备损坏和事故风险&#xff0c;因此&#xff0c;对安全阀进行定期检测&#xff0c;确保其性能完好、工作可靠&#xf…

Ubuntu安装GCC编译器

GCC编译器安装 GCC编译器安装切换软件源(换成国内的服务器)1 、创建一个文本文档并命名为“sources.list”2 、复制软件源列表清华源:阿里源:3 、把修改之后的.list 文件覆盖原有的文件4 、更新软件列表5 、安装6 、检查是否安装成功7、GCC 编译器:GCC编译器安装 这里演示…

HackTheBox-Machines--Nibbles

Nibbles 测试过程 1 信息收集 NMAP 80 端口 网站出了打印出“Hello world&#xff01;”外&#xff0c;无其他可利用信息&#xff0c;但是查看网页源代码时&#xff0c;发现存在一个 /nibbleblog 文件夹 检查了 http://10.129.140.63/nibbleblog/ &#xff0c;发现了 /index.p…

数据库开发-MySQL01

目录 前言 1. MySQL概述 1.1 安装 1.1.1 版本 1.1.2 安装 1.1.3 连接 1.1.4 企业使用方式(了解) 1.2 数据模型 1.3 SQL简介 1.3.1 SQL通用语法 1.3.2 分类 2. 数据库设计-DDL 2.1 项目开发流程 2.2 数据库操作 2.2.1 查询数据库 2.2.2 创建数据库 2.2.3 使用数…

开放式耳机怎么选?2024五款火爆全网品牌力荐!

​耳机如今已是生活必备品&#xff0c;但传统入耳式耳机长时间佩戴容易让耳朵受压、甚至引发健康问题。为了解决这些烦恼&#xff0c;开放式耳机应运而生。它不用塞进耳朵&#xff0c;不仅避免了耳道压力&#xff0c;还减少了耳道感染的风险&#xff0c;让人能尽情享受音乐。现…

Java18+ springboot+mysql +Thymeleaf 技术架构开发的全套同城服务家政上门系统源码(APP用户端+APP服务端+PC管理端)

Java springbootmysql Thymeleaf 技术架构开发的全套同城服务家政上门系统源码&#xff08;APP用户端APP服务端PC管理端&#xff09; 家政上门预约系统&#xff1a;该系统综合运用springboot、java1.8、vue移动支付、微信授权登录等技术&#xff0c;由用户小程序、站长小程序、…

C# try catch异常捕获

异常捕获 执行过程&#xff1a;try中的代码没有出现异常&#xff0c;则catch里面不会自行&#xff0c;如果try中代码出现异常&#xff0c;则后面的代码都不执行&#xff0c;直接跳到catch中的代码执行。 // try catch 可以捕获多个错误&#xff0c; try...catch...catch.... …

透明度技术在AI去衣中的双刃剑作用

引言&#xff1a; 在当今这个数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为我们生活中不可或缺的一部分。它不仅改变了我们的工作方式&#xff0c;还影响了我们的娱乐和社交活动。然而&#xff0c;随着AI技术的不断发展&#xff0c;一些伦理问题也逐渐浮出…

高并发项目-分布式Session解决方案

分布式Session解决方案 1.保存Session&#xff0c;进入商品列表页面 1.保存Session 1.编写工具类 1.MD5Util.java package com.sxs.seckill.utils;import org.apache.commons.codec.digest.DigestUtils;/*** Description: MD5加密工具类** Author sun* Create 2024/5/5 14…

【漏洞复现】WordPress Country State City Dropdown CF7插件 SQL注入漏洞(CVE-2024-3495)

0x01 产品简介 Country State City Dropdown CF7插件是一个功能强大、易于使用的 WordPress 插件&#xff0c;它为用户在联系表单中提供国家.州/省和城市的三级下拉菜单功能&#xff0c;帮助用户更准确地填写地区信息。同时&#xff0c;插件的团队和支持也非常出色&#xff0c…

启智CV机器人,ROS,ubuntu 20.04 【最后一步有问题】

资料&#xff1a; https://wiki.ros.org/kinetic/Installation/Ubuntu https://blog.csdn.net/qq_44339029/article/details/120579608 装VM。 装ubuntu20.04 desktop.iso系统。 装vm工具&#xff1a; sudo apt update sudo dpkg --configure -a sudo apt-get autoremove o…