Spring boot - ModelAndView 不调用另一个页面

Posted

技术标签:

【中文标题】Spring boot - ModelAndView 不调用另一个页面【英文标题】:Spring boot - ModelAndView doesn't call another page 【发布时间】:2021-11-04 11:28:00 【问题描述】:

我有一个 Spring Boot @Controller 在 ajax 调用后重定向页面。代码没有显示错误,但新页面没有出现。下面我分享了控制器的代码和 js 函数。有谁知道发生了什么?

控制器:

@RequestMapping(value = "/openNewPage", method = RequestMethod.GET)
public ModelAndView openNewPage(@RequestParam String id, Model model) 
    ModelAndView mav = new ModelAndView();
    mav.setViewName("/newPage");
    return mav;

JS:

function open() 
    var table = $('#dataList').DataTable();
    $('#dataList tbody').on('click', 'tr', function() 
        ligneSel = table.row(this).data();
        var id =  ligneSel[0];
    
        $.ajax(
            url : './openNewPage',
            type: 'get',
            dataType : 'html',
            data : 
                id: id
            ,
            success : function(data) 
                if (data != null) 
                    $("body").html(data);
                
            
        );
    );

【问题讨论】:

发生任何错误? 控制台中的任何错误。只有新页面没有出现。你能帮帮我吗? 提及newPage在你的项目中的位置,提供你的项目结构截图。 newPage.hltml 在 ./resources/template 中。太奇怪了,因为我用这种语法来调用其他页面,效果很好。不同之处在于我使用的是数据引导程序,当用户单击按钮时,我通过 J 获取行值并通过 ajax 将数据发送到控制器。 这是一个像我一样的问题:***.com/questions/42328846/…。但是,我认为该人不会转发到另一个页面。 【参考方案1】:

我的问题是对 spring boot 控制器的 ajax 调用没有重定向新视图。答案是我们需要调用控制器两次

这篇文章将更好地解释解决方案:Ajax call to spring boot controller to redirecting a view。

感谢所有帮助我解决这个问题的人。

下面的例子展示了解决方案:

1) 第一个控制器:

@RequestMapping(value = "/openNewPage", method = RequestMethod.GET)
public ModelAndView openNewPageController1(@RequestParam String id, Model model) 
    ModelAndView mav = new ModelAndView("/newPage");
    return mav;

2) 第二个控制器:

@RequestMapping(value = "/openNewPage", method = RequestMethod.GET)
public ModelAndView openNewPageController2(@RequestParam String id, Model model) 
    ModelAndView mav = new ModelAndView("/newPage");
    return mav;

3) javaScript:

function open() 
    var table = $('#dataList').DataTable();
    $('#dataList tbody').on('click', 'tr', function() 
        ligneSel = table.row(this).data();
        var id =  ligneSel[0];
    
        $.ajax(
            url : './openNewPage',
            type: 'get',
            dataType : 'html',
            data : 
                id: id
            ,
            success : function(data) 
                window.location.href = "/openNewPage?id="+id;
            
        );
    );

【讨论】:

【参考方案2】:

简单地命名视图不会重定向。尝试在创建 ModelAndView 时添加 redirect: 前缀:

@RequestMapping(value = "/openNewPage", method = RequestMethod.GET)
public ModelAndView openNewPage(@RequestParam String id, Model model) 
    ModelAndView mav = new ModelAndView("redirect:/newPage");
    return mav;

另外,在您的 JS 中,您正在发出一个 get 请求并获取一个 ModelAndView 对象。

这不会将页面重定向到 ModelAndView。

AJAX 通常用于与 RESTful 服务交互,您可以执行 GET 请求并以异步方式在页面上显示数据 - 无需离开页面。

Spring 在遵循 MVC 模式的 MVC(Model-View-Controller)框架中有 ModelAndView 类。 模型和视图在服务器端 (Java) 解析,然后提供给客户端,而不是从客户端(Web 浏览器、JS)获取数据。

如果你想重定向客户端(从浏览器,JS)然后添加到你的javascript

window.location.href = '/newPage';

您需要在控制器中定义 /newPage 端点才能使其工作。

试试这个:

@Controller
@RequestMapping("/")
public class RedirectController 
    
    @GetMapping("/redirectWithRedirectPrefix")
    public ModelAndView redirectWithUsingRedirectPrefix(ModelMap model) 
    
        model.addAttribute("attribute", "redirectWithRedirectPrefix");
        return new ModelAndView("redirect:/redirectedUrl", model);
    

【讨论】:

感谢回复,但我尝试使用“重定向”,但它不起作用。我使用简单模型,返回一个字符串,但它也不起作用。还有其他页面使用这种语法并且所有的作品。我不知道为什么这个特定页面不起作用? 您正在发出异步获取请求 - 不是重定向。您是要重定向还是要获取 html 字符串并在当前页面上设置数据? 我要转发到另一个页面。 您是否尝试将window.location.href = '/newPage'; 添加到您的javascript? 我对您的要求感到困惑。如果您重定向到新页面,则处理数据没有多大意义,除非您将处理后的数据发送到后端 - 但我在您的代码中看不到这一点。如果您需要在重定向中传递数据,您可以在控制器方法签名中使用 @PathVariable 并将数据放在重定向 URL /newPage?id=123 中。如果您需要一个示例来做到这一点,请告诉我,我会更新答案。【参考方案3】:

我有一个使用 Thymeleaf templates 的 Spring BOOT 应用程序。例如:

我有一个定义菜单的布局视图,它通过向 Spring 控制器发出请求来加载另一个页面。例如:

<a href="#" style="color: white" th:href="@/photo">Upload Photos</a>

当我点击上传照片时,它会调用/photo控制器:

 @GetMapping("/photo")
    public String photo() 
      return "upload";
    

返回 Spring BOOT 应用中的上传视图。使用 Thymeleaf 模板,您可以简单地引用控制器中模板下的 HTML 文件的名称,如本示例所示。您的问题看起来像是在使用 AJAX,而不是使用菜单项来引用控制器。

完整教程请参见此示例:

https://spring.io/guides/gs/serving-web-content/

【讨论】:

好的,我会努力的。我正在使用 Ajax,因为我有数据,并且在行中是一个按钮。当我单击时,我通过 JavaScript 获取行值,然后 ajax 将数据发送到控制器并在另一个页面中转发它们。 我一直使用菜单项来更改页面,然后使用 AJAX 操作来 POST 数据或 GET 数据,然后显示在同一页面中。它在 Spring 应用程序中运行良好。 我需要显示在其他页面。使用AJAX调用控制器,然后调用另一个页面,是不是不可能? 在我与最终用户的动态交互中,他们选择数据表引导程序中的项目,然后应用程序通过 javascrit 获取行的数据并通过 ajax 调用发送到控制器。控制器被调用。我看到用户的数据选择了。 spring boot 在重定向到另一个页面之前读取了所有参数,但是页面没有在浏览器中显示。

以上是关于Spring boot - ModelAndView 不调用另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》

spring-boot-quartz, 依赖spring-boot-parent

spring-boot系列:初试spring-boot

Spring-Boot Banner

Spring Boot:Spring Boot启动原理分析