Thymeleaf 中的视图和重定向有啥区别?

Posted

技术标签:

【中文标题】Thymeleaf 中的视图和重定向有啥区别?【英文标题】:What is the difference between View and Redirection in Thymeleaf?Thymeleaf 中的视图和重定向有什么区别? 【发布时间】:2016-07-11 04:47:48 【问题描述】:

我知道这个问题对一些人来说可能听起来很愚蠢,但我是 Spring Boot 和 Thymeleaf 的新手。

假设我目前在page1.html。用户单击某个按钮,该按钮会向我的控制器 MyController.java 生成一个 POST/GET 请求,该请求使用 @RequestMapping 将此请求映射到某个函数。

处理完请求后,我会从控制器返回一个视图名称,例如 return "page2"

page1.html 的内容 更改,但 url 仍然保持不变,如 http://localhost:8080/page1 而不是更改为 http://localhost:8080/page2

我知道要转到不同的页面,我必须使用 redirection,但为什么 view 无法做到这一点?

谁能解释一下为什么会发生这种情况,我应该什么时候使用重定向或什么时候应该使用视图?

编辑 1:

这是我的控制器

@RequestMapping (value = "edit", method = RequestMethod.POST, params="action=ADD")

    public String saveUser(@ModelAttribute UserDto userDto) 
        try 
            User user = new User();
            if(userDto.getId() != null)    
                throw new UserExists();
            
            user.setName(userDto.getName());
            user.setEmail(userDto.getEmail());
            System.err.println("Request Recieved");
            userDao.save(user);
            return "success";
         catch (Exception e) 
            System.err.println("Error Saving User");
            e.printStackTrace();
            return "failure";
        
    

这是我的看法

<form id="manipulate-data-form"  th:object="$userobj" method="post" th:action="@/edit">
        <table id="manipulate" class="table table-bordered">
            <tr>
                <td>ID</td>
                <td><input type="text" class="form-control" th:if="$userobj != null" th:field="*id" ></input></td>
            </tr>
            <tr>
                <td>NAME</td>
                <td><input type="text" class="form-control" th:if="$userobj != null" th:field="*name" ></input></td>
            </tr>
            <tr>
                <td>EMAIL</td>
                <td><input type="text" class="form-control" th:if="$userobj != null" th:field="*email" ></input></td>
            </tr>
            <tr>
                <td><input name="action" value="ADD" type="submit" class="btn btn-success" ></input></td>
                <td>
                    <input name="action" value="DELETE" type="submit" class="btn btn-danger" ></input> 
                    <input style="margin-left: 30px" name="action" value="UPDATE" type="submit" class="btn btn-primary" ></input>
                </td>
            </tr>
        </table>
    </form>

所以基本上点击它调用 saveUser() 控制器的按钮,然后当我返回 failuresuccess 查看 URL 保持不变,但内容页面变化对应成功或失败。

【问题讨论】:

您的问题有什么更新吗? @Patrick 抱歉无法早点回复。我出去了一会儿。但我已经在 EDIT 1 中添加了代码。 查看我编辑的答案。 【参考方案1】:

让我试着回答你的一些问题:

page1.html 的内容发生了变化,但 url 仍然是 与http://localhost:8080/page1 相同,而不是更改为 http://localhost:8080/page2

您正在访问类似http://localhost:8080/page1 的网址。 /page1 并不意味着使用名称 page1.html 显示您的视图。它更多的是您的 @RequesteMapping 注释的 URL 以及应该为此请求执行的方法。

例如:

您正在点击网址:

http://localhost:8080/page1,你的映射是:@RequestMapping("/page1"),你想返回page1.html。所以你的看法是:return "page1";

现在您可以看到 page1.html 的内容。您提供的按钮现在应该有一个指向http://localhost:8080/page2 的链接,并且您的控制器应该有一个到它的映射@RequestMapping("/page2")。在这种方法中,您可以返回您的return "page2",您的网址将更改为http://localhost:8080/page2

如果按钮的链接确实有 another 值而不是 http://localhost:8080/page2 但您想显示 /page2 的特定 URL,则需要重定向:return "redirect:/page2" 在方法中特定的@RequestMapping("/anyOtherMapping")


谁能解释一下为什么会发生这种情况,我应该什么时候使用重定向或什么时候应该使用视图?

我不能 100% 确定这是否正确,但我认为这只是存在查看和重定向的规则。如果您想站在特定的 URL 上并想显示为此构建的视图,那就去做吧。如果您不想显示相同的 URL 或想切换到另一个页面,只需使用重定向。

重定向还会再次调用一个控制器,该控制器正确映射到您的重定向 URL 并返回一个视图。

使用重定向的一些示例如下:

成功登录后,您可以重定向到用户主页。 保存项目后(REST 方法),您可以重定向到该项目的特定 ID /item/1 并返回包含该项目信息的视图。

回答您的编辑问题:

尝试使用redirection 更改网址。

@RequestMapping (value = "edit", method = RequestMethod.POST, params="action=ADD")

    public String saveUser(@ModelAttribute UserDto userDto) 
        try 
            User user = new User();
            if(userDto.getId() != null)    
                throw new UserExists();
            
            user.setName(userDto.getName());
            user.setEmail(userDto.getEmail());
            System.err.println("Request Recieved");
            userDao.save(user);
            return "redirect:/success";
         catch (Exception e) 
            System.err.println("Error Saving User");
            e.printStackTrace();
            return "redirect:/failure";
        
    

@RequestMapping("/success")
public String successPage()
    return "success";


@RequestMapping("/failure")
public String failurePage()
    return "failure";

这应该会更改 URL,因为您将从 /edit 重定向到 /failure/success 页面。如果需要,您还可以在重定向中提供参数。

【讨论】:

“你显示 /page1 而不是 /page2 因为你想要通过返回视图来显示 /page1” - 我不确定我是否理解你的这句话。你能详细说明一下吗? @amitection 添加了一些内容。希望现在更清楚。 现在我明白你想说什么了。但就像你说的**“在这种方法中,你可以返回你的回报“page2”,你的网址将更改为localhost:8080/page2”** - 这不会发生。单击按钮时,URL 保持不变,即 localhost:8080/page1,但 page1 的内容被 page2 替换。 @amitection 能否为您提供控制器类和按钮的 html 部分。我认为这会有所帮助。 :)

以上是关于Thymeleaf 中的视图和重定向有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

请问重定向与请求转发有啥区别?

servlet如何重定向

http 301 302 303 307 308 傻傻分不清

关于Servlet中的转发和重定项

JSP转发和重定向之间的区别[重复]

SpringMVC框架如何实现请求转发和重定向呢?