Spring MVC使用Flash Attribute展现提示消息

Spring MVC使用Flash Attribute展现提示消息  由David发表在天码营 


Web应用中总是不可避免的需要通过表单POST请求向服务器提交数据,数据提交到服务器处理后也需要给用户必要的提示信息——成功、失败、失败原因等等。这些提示信息往往只需要短时间内的“闪现”(Flash),为了解决POST请求刷新重新发送的问题,Spring MVC引入了Flash Attributes用于存储POST请求重定向到GET请求这一小段时间内的信息。

表单提交

在Spring WebMvc应用中如果遇到这类问题,传统的做法是编写这样一个Controller


@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(Model model) {
    //Login Logic...
    String result = //Login Result
    model.addAttribute("message", result);

    return "LoginResult";
}

上例中的用户登录请求,提交表单后如果登录成功,POST请求直接返回200 OK以及一个登录成功的页面(失败也是如此)。但是这样做有一个非常明显的问题——在“登录成功”页面用户刷新浏览器,浏览器会提示用户是否继续提交表单数据。这样提示的原因是,这是一个POST请求,刷新相当于执行之前的一次表单提交操作,只不过这一次提交不再需要用户填写表单数据——浏览器已经将之前填写的表单数据缓存起来以便刷新。

POST/Redirect/GET模式

上一节中表单提交的用户体验非常不友好,为了解决这个问题,一种叫做Post/Redirect/GET的模式被提出并广泛应用在Web程序开发中。和传统的表单提交方法不同,这种模式在POST请求完成后,会重定向(HTTP状态码302)到另外一个页面。这样相当于浏览器重新加载了一个页面(使用GET请求),此时用户无论如何刷新浏览器,都是刷新当前GET请求对应的页面而不再是重复提交一次表单。

alter-text

上图描述了这种模式中浏览器与服务器之间的交互过程。

实例研究:用户登录

以用户登录表单为例,如果登录成功,那么应用应该重定向到一个新的页面,并给出一个提示信息:

alter-text

那么问题来了,在传统的方法中渲染一个提示页面只需要使用model.addAttribute("message", result);就可以在模板中显示消息,但是在这种新模式中,经过Redirect到的GET请求,如何能够获取到之前表单提交POST请求中的处理结果呢?

Flash Attribute

Spring MVC从3.1版本起,引入了Flash Attribute来解决这个问题。Spring MVC中的ModelAttribute的生命周期仅限于单个Web请求中,但是Flash Attributes则是针对于POST/Redirect/GET进行设计的——在Redirect之前的POST请求中加入Flash Attributes中的数据,会被短暂的存储下来(一般是Session中),直到Redirect后的GET请求完成,所以在GET请求中可以获取之前POST请求中放入Flash Attributes中的数据,这样也就完美的解决了之前提到的问题。

在Controller中使用Flash Attribute

在Spring MVC中,被@RequestMapping注解的方法,可以接收RedirectAttributes ra参数:

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(@RequestParam("username") String username,
                    @RequestParam("password") String password,
                    HttpSession session,
                    final RedirectAttributes redirectAttributes) {
    if (!verify(username, password)) {
        redirectAttributes.addFlashAttribute("message", "username/password invalid");
        return "redirect:/login";
    }

    session.setAttribute(SESSION_LOGGED_IN, true);
    redirectAttributes.addFlashAttribute("message", "Login Success");
    return "redirect:/";
}

可以看到,redirectAttributes.addFlashAttribute()方法就是向Flash Attributes中添加一条属性,在GET请求的处理方法中,获取它也非常简单——它被放在Model中:

@RequestMapping(method = RequestMethod.GET)
public String index(@ModelAttribute("message) String message) {
    logger.info("message={}", message);
    return "index";
}

在模板中访问Flash Attributes

因为对于GET请求,Flash Attributes已经被转化为Model中的数据,所以在模板中直接通过表达式访问它们即可,无需做任何新的配置:

<div class="flash"
     th:unless="${#strings.isEmpty(message)}"
     th:text="${message}"></div>

对于GET请求来说,如果并非重定向而来,message必定为空,这时不会显示提示消息。

运行效果

本文参考代码中的登录页面效果如下:

alter-text

如果登录成功会redirect:/,对应index页面:

alter-text

如果登录失败会redirect:/login,即还是跳转回登录页面,登录页面也需要对提示信息进行处理:

alter-text



更多文章请访问天码营网站






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值