【问题标题】:Changing back the url to original if exception thrown and return back to form如果抛出异常并返回到表单,则将 url 更改回原始 URL
【发布时间】:2019-07-15 17:52:16
【问题描述】:

我有一个 thymeleaf 注册表单,如果我们提交它,则会调用位于“/signup_do”的控制器来验证用户并将其保存到数据库:

<form action="/signup_do" method="post">
    ...
</form>

“/signup_do”处的控制器将请求传递给 accountRegistration 服务方法,该方法进行验证:

@PostMapping("/signup_do")
public String register(Account account, HttpSession session) {

    session.setAttribute("accountToRegister", account);
    accountManagement.accountRegistration(account);

    return "Success";
}

账户注册方法可以抛出异常SignupFormException,由该控制器类中定义的@ExceptionHandler处理:

@ExceptionHandler(value=SignupFormException.class)
public String handle(HttpSession session, Model response) {

    Account returnDataToForm = (Account) session.getAttribute("accountToRegister");
    response.addAttribute("name", returnDataToForm.getFirstName());
    session.invalidate();

    return "signup";
}

现在问题是当异常发生时,在表单中输入的内容被传回注册表单,输入的数据保持不变,但url仍然保持为/ signup_do

我尝试使用 return "redirect:/signup" 代替,它确实改变了 url,但它最终向 /signup url 发出了一个 get 请求,例如

/signup?name=John...

但我的 /signup 控制器不是为处理获取请求而设计的,它只知道显示表单,因此信息丢失了。

@GetMapping("/signup")
public String signupPage() {return "signup";}

我也尝试过使用 forward:/signup,但最终抛出 405 错误。

【问题讨论】:

    标签: spring-boot thymeleaf


    【解决方案1】:

    在问了这个问题几个小时后,我想出了一个干净的解决方法。

    我所做的是将处理注册过程的控制器的名称也更改为 ("/signup")。由于显示页面的控制器是@GetMapping("/signup"),而处理注册过程的控制器是@PostMapping("/signup"),所以没有冲突。

    现在即使控制器发生变化,url 保持不变,因为它们都是注册...

    @GetMapping("/signup")
    public String signupPage() {return "signup";}
    
    @PostMapping("/signup")
    public String register(Account account, HttpSession session) {
    
        session.setAttribute("accountToRegister", account);
        accountManagement.accountRegistration(account);
    
        return "success";
    }
    

    这就像我想要的那样工作!

    【讨论】:

    • 如果它有效,它就有效!替代品越多越好。
    【解决方案2】:

    重定向将向控制器发出获取请求以寻找要显示的视图,在您的情况下,这意味着由于您给出的原因而丢失数据。我可以想到两种解决方法:

    1. 不要在每次进入此视图时使用 javascript 手动进行重定向和更改 URL。如果您不喜欢视图中有“错误”的 URL,手动编辑它看起来是最合理和最直接的方法。您可以查看如何执行此操作here,将其包含在每次页面加载/按下提交按钮时执行的脚本中。

    2. 执行重定向并避免丢失您的信息,方法是将其存储在会话中一段时间​​,以this 的方式在百里香中访问它,而不是从模型属性中获取它。这意味着您以后必须小心删除此会话属性。您对表单视图的获取请求包含用户信息也不是很“干净”,因此如果可以避免,我不会采用此解决方案。

    【讨论】:

    • 我想出了第三种方法,非常简洁,看看我的答案...
    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    相关资源
    最近更新 更多