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

来源:互联网 发布:矩阵图怎么做 编辑:程序博客网 时间:2024/06/15 17:00

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必定为空,这时不会显示提示消息。

原创粉丝点击