首页 > 解决方案 > 如何在签名中没有 RedirectAttributes 的方法中访问 RedirectAttributes?

问题描述

在 Spring Boot 控制器中,是否可以在没有签名RedirectAttributes的情况下访问方法?RedirectAttributes换句话说,它可以作为“bean”或上下文变量从框架中访问吗?

我这样做的动机是能够重构几个请求映射方法(à la Clean Code)以将异常处理移出这些方法。因此,例如,我有几种方法,其中包含catch这样的块:

    @GetMapping("/security/user/{uid}")
    public String showEditUserForm(@PathVariable("uid") String uid, Model model, RedirectAttributes redirectAttributes) {
        try {
            model.addAttribute("userAccount", userAccountService.findByUsername(uid));
            return "/security/edituser";
        } catch(UserDoesntExistException e) {
            redirectAttributes.addFlashAttribute("flashstatus","danger");
            redirectAttributes.addFlashAttribute("flashmessage","User doesn't exist");
            return "redirect:/security";
        }
    }

相反,我想做这样的事情:

    @GetMapping("/security/user/{uid}")
    public String showEditUserForm(@PathVariable("uid") String uid, Model model) {
        try {
            model.addAttribute("userAccount", userAccountService.findByUsername(uid));
            return "/security/edituser";
        } catch(UserDoesntExistException e) {
            return redirectWithMessage("danger","User doesn't exist");
        }
    }

    // and several other mappings that also call redirectWithMessage()

    public String redirectWithMessage(String status, String message) {
        // obtain RedirectAttributes somehow!
        redirectAttributes.addFlashAttribute("flashstatus",status);
        redirectAttributes.addFlashAttribute("flashmessage",message);
        return "redirect:/security";
    }

所以问题是,实用方法(“ redirectWithMessage”)如何获得一个指针,RedirectAttributes而不需要类中的每个方法都必须在其签名中包含它并通过注入传递它?

标签: javaspring-bootspring-mvc

解决方案


你有几种方法RequestContextUtils

  1. 调用RequestContextUtils#getOutputFlashMap以访问 Flash 地图并更新它们(属性 + 目标重定向)

  2. 调用便捷方法RequestContextUtils#saveOutputFlashMap

  3. 你可以得到实例FlashMapManager

调用此方法写入 flash 属性:

将给定的 FlashMap 保存在一些底层存储中并设置其到期期限的开始。注意:在重定向之前调用此方法,以便允许在提交响应之前将 FlashMap 保存在 HTTP 会话或响应 cookie 中。

void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response)

您可以通过@Autowire它们访问 bean 中的当前请求/响应。

对于您的用例,坚持使用 #1 即可(只需添加属性,重定向位置已在您的返回字符串上设置)

例子:

@Autowired
HttpServletRequest request;

public String redirectWithMessage(String status, String message) {
   FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);

   flashMap.put("flashstatus",status);
   flashMap.put("flashmessage",message);

   return "redirect:/security";
}

推荐阅读