Spring MVC Flash Attribute 的讲解与使用示例

1.

Spring MVC 3.1版本加了一个很有用的特性,Flash属性,它能解决一个长久以来缺少解决的问题,一个POST/Redirect/GET模式问题。

正常的MVC Web应用程序在每次提交都会POST数据到服务器。一个正常的Controller (被注解 @Controller标记)从请求获取数据和处理它 (保存或更新数据库)。一旦操作成功,用户就会被带到(forward)一个操作成功的页面。传统上来说,这样的POST/Forward/GET模式,有时候会导致多次提交问题. 例如用户按F5刷新页面,这时同样的数据会再提交一次。

为了解决这问题, POST/Redirect/GET 模式被用在MVC应用程序上. 一旦用户表单被提交成功, 我们重定向(Redirect)请求到另一个成功页面。这样能够令浏览器创建新的GET请求和加载新页面。这样用户按下F5,是直接GET请求而不是再提交一次表单。

 

虽然这一方法看起来很完美,并且解决了表单多次提交的问题,但是它又引入了一个获取请求参数和属性的难题. 通常当我们生成一次http重定向请求的时候,被存储到请求数据会丢失,使得下一次GET请求不可能访问到这次请求中的一些有用的信息.

Flash attributes  的到来就是为了处理这一情况. Flash attributes 为一个请求存储意图为另外一个请求所使用的属性提供了一条途径. Flash  attributes 在对请求的重定向生效之前被临时存储(通常是在session)中,并且在重定向之后被立即移除.

为了这样做, Flash 特性使用了两个集合. FlashMap 被用来管理 flash attributes 而 FlashMapManager 则被用来存储,获取和管理 FlashMap 实体.

对于每一次请求一个 “input” flash map 会被创建,来存储来自任何之前请求的 flash attribute 还有一个 “output” flash map 会被创建,来存储任何我们存储在这个请求中的,之后的请求参数.

使用

要想在你的 Spring MVC 应用中使用 Flash attribute,要用 3.1 版本或以上。并且要在 spring-servlet.xml 文件中加入 mvc:annotation-driven。

1
<mvc:annotation-driven />

这些都完成之后,Flash attribute 就会自动设为“开启”,以供使用了。只需在你的 Spring controller 方法中加入RedirectAttributes redirectAttributes。

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
//...
 
    @RequestMapping(value="addcustomer", method=RequestMethod.POST)
    public String addCustomer(@ModelAttribute("customer") Customer customer,
            final RedirectAttributes redirectAttributes) {
    //...
        redirectAttributes.addFlashAttribute("message", "Successfully added..");
    //...
 
        return "redirect:some_other_request_name";
    }

addFlashAttribute 方法会自动向 output flash map 中添加给定的参数,并将它传递给后续的请求。

我们来看看一个使用 Flash attribute 来完成 POST/Redirect/GET 并传递一些信息的完整实例吧。

Flash Attribute 实例

下面的应用向用户显示一个表单。当用户填完数据,并提交表单之后,页面会重定向到另一个显示成功信息的页面。在这个重定向的新页面中,会显示用户刚才输入的信息。

第1步: 需要的 JAR 和项目结构

如果你用 Maven 来做依赖管理,用下面的 dependencies 来添加 Spring 3.1 MVC 的支持。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencies>
    <!-- Spring 3.1 MVC  -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>3.1.2.RELEASE</version>
    </dependency>
    <!-- JSTL for c: tag -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
</dependencies>

或者,你可以下载以下 JAR 文件,然后把它们放在 /WEB-INF/lib 文件夹下。

第2步: Spring 配置

要为 web 项目添加 Spring 支持,需要在 web.xml 中添加 DispatcherServlet 。 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
 
 
    id="WebApp_ID" version="2.5">
     
    <display-name>Spring MVC Flash attribute example</display-name>
    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/index.html</url-pattern>
    </servlet-mapping>   
    <servlet-mapping>
        <servlet-name>spring</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>
</web-app>

然后,spring-servlet 使用 mvc:annotation-driven 来支持 mvc ,并且会扫描项目中的 context:component-scan 标签。

spring-servlet.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml  version="1.0" encoding="UTF-8"?>
         
     
    <bean id="jspViewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
     </bean>
     
    <context:component-scan base-package="net.viralpatel.controller" />
    <mvc:annotation-driven />
  
</beans>

第3步: Spring Controller – RedirectAttributes

Controller 的代码使用 Customer.java 对象作为 bean 来保存客户信息。

Customer.java

1
2
3
4
5
6
7
8
9
10
package net.viralpatel.spring;
 
public class Customer {
    private String firstname;
    private String lastname;
    private int age;
    private String email;
 
    //getter, setter methods
}

CustomerController 类有3个方法。showForm 方法对应 URL /form ,用来显示 Add New Customer 表单。addCustomer 方法对应 URL /addcustomer ,用来处理 POST 请求。

CustomerController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package net.viralpatel.controller;
 
import net.viralpatel.spring.Customer;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
@Controller
public class CustomerController {
 
     
     
    @RequestMapping(value="showform", method=RequestMethod.GET)
    public String showForm(@ModelAttribute("customer") Customer customer) {
        return "add_customer";
    }
     
    @RequestMapping(value="addcustomer", method=RequestMethod.POST)
    public String addCustomer(@ModelAttribute("customer") Customer customer,
            final RedirectAttributes redirectAttributes) {
 
        redirectAttributes.addFlashAttribute("customer", customer);
        redirectAttributes.addFlashAttribute("message","Added successfully.");
 
        return "redirect:showcustomer.html";  
    }
 
     
    @RequestMapping(value="showcustomer", method=RequestMethod.GET)
    public String showCustomer(@ModelAttribute("customer") Customer customer) {
        System.out.println("cust:" + customer.getFirstname());
        return "show_customer";
    }
}

注意我们在 addCustomer 方法中是如何使用 redirectAttributes 参数来添加 flash attribute 的。并且,我们是用 addFlashAttribute 方法来设置新的参数为 flash attribute。

第4步: View 层

add customer.JSP 文件显示一个 Add New Customer(添加新客户)表单。 add_customer.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<body>
    <h1>Add New Customer</h1>
    <form:form action="addcustomer.html" method="post" commandName="customer">
    <table>
        <tr>
            <td><form:label path="firstname">Firstname</form:label></td>
            <td><form:input path="firstname" /> </td>
        </tr>
        <tr>
            <td><form:label path="lastname">Lastname</form:label></td>
            <td><form:input path="lastname" /> </td>
        </tr>
        <tr>
            <td><form:label path="age">Age</form:label></td>
            <td><form:input path="age" /> </td>
        </tr>
        <tr>
            <td><form:label path="email">Email</form:label>
            <td><form:input path="email" /> </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Add Customer" />
            </td>
        </tr>
    </table>
    </form:form>
</body>
</html>

show_customer.jsp 简单地显示客户的名和姓,以及用 flash attributes 设置的成功信息。

show_customer.jsp

1
2
3
4
5
6
7
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<body>
<h1>${message}</h1>
    ${customer.lastname}, ${customer.firstname} added successfully..
</body>
</html>

Demo:

执行这个 web 项目即可。 URL: http://localhost:8080/SpringMVC_Flash_Attribute_Maven_example/form.html

转 :  https://www.cnblogs.com/sharpest/p/6151239.html

Spring 梳理-跨重定向请求传递数据-Flash的更多相关文章

  1. Spring之跨重定向请求传递数据

    摘要 在开发场景中,大部分数据都是使用请求转发(forward)进行传递,而使用重定向(redirect)传递数据可能比较少. 那么问题来了:请求中的数据生命周期存活时间只在一个请求转发(reques ...

  2. Spring 跨重定向请求传递数据

    在处理完POST请求后, 通常来讲一个最佳实践就是执行一下重定向.除了其他的一些因素外,这样做能够防止用户点击浏览器的刷新按钮或后退箭头时,客户端重新执行危险的POST请求. 在控制器方法返回的视图名 ...

  3. SpringMVC跨重定向请求传递数据

    (1)使用URL模板以路径变量和查询参数的形式传递数据(一些简单的数据) @GetMapping("/home/index") public String index(Model ...

  4. Jquery跨域请求php数据(jsonp)

    Jquery跨域请求php数据 我们一般用到ajax的时候是在同服务器下,一般情况下不会跨域,但有时候需要调用其他域名或ip下的数据的时候,遇到跨域请求数据的时候. 今天在工作中碰到javascrip ...

  5. jQuery使用ajax跨域请求获取数据

    jQuery使用ajax跨域请求获取数据  跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的 ...

  6. 本地主机作服务器解决AJAX跨域请求访问数据的方法

    近几天学到ajax,想测试一下ajax样例,由于之前在阿里租用的服务器过期了,于是想着让本地主机既做服务器又做客户端,只是简单地测试,应该还行. 于是,下载了xampp,下载网址http://www. ...

  7. AJAX跨域请求json数据的实现方法

    这篇文章介绍了AJAX跨域请求json数据的实现方法,有需要的朋友可以参考一下 我们都知道,AJAX的一大限制是不允许跨域请求. 不过通过使用JSONP来实现.JSONP是一种通过脚本标记注入的方式, ...

  8. 关于ajax跨域请求API数据的一些问题

    一般来说我们使用jquery的ajax来跨域请求API数据的时候每次请求,就只能请求一组数据,而且当我们再次点击发送ajax请求的时候,新请求的数据会覆盖掉原来的数据,那么如何每次在请求的数据的时候, ...

  9. Spring系列 SpringMVC的请求与数据响应

    Spring系列 SpringMVC的请求与数据响应 SpringMVC的数据响应 数据响应的方式 y以下案例均部署在Tomcat上,使用浏览器来访问一个简单的success.jsp页面来实现 Suc ...

随机推荐

  1. Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves)

    Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves) 深度优先搜索的解题详细介绍,点击 ...

  2. (五十三)c#Winform自定义控件-滚动文字

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  3. Mac下搭建go和beego开发环境

     go安装 首先到golang的官网下载 直接双击安装包,安装 ,下一步,下一步....完成既可 验证安装是否成功 打开终端执行 输出 go version go1.11.5 darwin/amd64 ...

  4. 微信小程序获取手机号码看这篇文章就够了

    前言 微信小程序获取手机号码,从官方文档到其他博主的文档 零零散散的 (我就是这样看过来 没有一篇满意的 也许是我搜索姿势不对) 依旧是前人栽树 后人乘凉 系列.保证看完 就可以实现获取手机号码功能 ...

  5. poj 3660Cow Contest

    题目链接:http://poj.org/problem?id=3660 有n头奶牛还有m种关系a,b表示a牛逼b彩笔,所以a排名比b高 最后问你给出的关系最多能确定多少头奶牛的排名,而且给出的数据不会 ...

  6. 对TD tree系统评价及改进

    该系统是由石家庄铁道大学2017级信息学院的同学研发并改进,分享给我们18级新生的一份体验,这项app可安装在任意一个智能手机上,当听到学长们像我们介绍这款app的时候,着实让我惊呆了,惊叹学长们的编 ...

  7. ubuntu命令行配置静态IP

    (1)首先我们使用ifconfig命令查询一下网卡名称 提示:如果提示没有ifconfig命令,首先应该下载一个net-tools 仅需执行命令:apt install net-tools (2)编辑 ...

  8. docker-将自己的Linux打包为镜像

    基于原始文件和目录从0开始制作镜像: 1).基于CentOS7 Linux纯净系统(初始化安装完成),将Linux整个系统打包成tar文件即可: cd /root/ tar --numeric-own ...

  9. HashMap和ConcurrentHashMap的区别,HashMap的底层源码

    HashMap本质是数组加链表,根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap在HashMap的基础 ...

  10. 阿里mysql规范

    (一)建表规约 1.[强制]表达是与否概念的字段,必须使用 is_xxx的方式命名,数据类型是 unsigned tinyint( 1表示是,0表示否),此规则同样适用于 odps建表. 说明:任何字 ...