Spring-MVC 3.1:将请求从一个控制器函数转发到另一个函数

11

我正在使用Spring 3.1。我有一个控制器函数,它接受通过表单提交的命令对象(数据持有者)并进行一些处理:

@RequestMapping(value = "/results", method = RequestMethod.POST)
public String toResultsScreen(@ModelAttribute("ssdh") SearchScreenDataHolder ssdh,
                                  BindingResult bindingResult,    
                                  ModelMap model,                
                                  HttpSession session) {

    if (bindingResult.hasErrors()) {
        logger.debug("Error returning to /search screen");
        return "search";
    }

    netView = "results";

    // do stuff

    return nextView;         

} // end function

有一些用户希望通过编程方式使用GET链接从我们的站点获取信息,我想设置另一个处理程序来处理该请求。 它将创建该命令对象(ssdh)的新安装,并使用通过GET请求发送的参数填充它。 然后它将把它传递给上面的处理程序。 大致如下:

@RequestMapping(value = "/pubresult")
public String toPublicResultsScreen(ModelMap model,    
                                   HttpSession session,             
                                   @RequestParam (required=true) String LNAME,   
                                   @RequestParam (required=false)String FNAME){

    Search search = new Search(usertype);

    // Capture the search parameters sent by HTTP
    ssdh.setLast_name(LNAME);
    ssdh.setFirst_name(FNAME);

    // To Do:  "forward this data holder, ssdh to the controller function quoted first

    return nextView;         

} // end function

我的问题是,如何将我的命令/数据持有对象转发到第一个控制器函数,以便我无需以任何方式修改第一个控制器函数的代码?

3个回答

18

你可以使用在Spring MVC 3.1中引入的RedirectAttributes对象,并将想要保留用于重定向的数据填充到该对象中。这被称为PRG (POST/Redirect/GET)模式。

@RequestMapping(value="/saveUserDetails.action", method=RequestMethod.POST)
public String greetingsAction(@Validated User user,RedirectAttributes redirectAttributes){
    //setting attributes 
    redirectAttributes.addFlashAttribute("firstName", user.getFirstName());
    redirectAttributes.addFlashAttribute("lastName", user.getLastName())
    return "redirect:success.html";
} 

我撰写了一些技术文章,介绍如何使用它。我相信这将给您带来更多细节:

http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31


1
@danny.lesnik,您提供的链接http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31已经失效。您能否更新一个可用的链接? - OO7
为什么我需要使用forward来处理这个事件? - FelipeKunzler

7

您应该能够在ModelAttribute中设置ssdh并简单地将其转发回来,这样,RequestDispatcher就可以将其映射回/results处理程序:

@RequestMapping(value = "/pubresult")
public String toPublicResultsScreen(ModelMap model,    
                                   HttpSession session,             
                                   @RequestParam (required=true) String LNAME,   
                                   @RequestParam (required=false)String FNAME, Model model){

  Search search = new Search(usertype);
  // Capture the search parameters sent by HTTP
  ssdh.setLast_name(LNAME);
  ssdh.setFirst_name(FNAME);
  model.addAttribute("ssdh", ssdh);

  return "forward:/results";         

}

我试过这个。我想要转发的控制器函数处理POST请求。当我尝试从上面的示例函数转发时,它只能处理GET请求,会出现一个错误消息,提示不支持GET请求。我猜想我不能将GET请求转发到一个POST函数中。有没有办法在转发之前改变请求类型,以便最终达到相同的URL? - Steve
是的,你说得对,我稍微了解了一下转发时的请求方法 - 它将继续保持与原始请求相同的请求方法,因此在这种情况下,由于您正在通过HTTP GET调用/pubresult,这也将在转发请求中保持不变 - http://stackoverflow.com/questions/4374548/does-jspforward-or-requestdispatcher-forward-use-get-or-post。不确定是否有解决方法,如果可行,请为两者使用相同的RequestMethod。 - Biju Kunjummen

0

使用

org.springframework.web.servlet.view.RedirectView

使用Spring包中的类在Spring MVC控制器中重定向到不同页面。 Baeldung博客页面有更多细节

示例代码:

@RequestMapping(value = "/", method = RequestMethod.GET)
public RedirectView mainMethod() {
    return new RedirectView("/login");
}

@RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView mainLogin() {
    ModelAndView model = new ModelAndView("login");
    return model;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接