Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc Spring3MVC使用单个控制器处理多表单提交_Spring Mvc_Jakarta Ee_Controller - Fatal编程技术网

Spring mvc Spring3MVC使用单个控制器处理多表单提交

Spring mvc Spring3MVC使用单个控制器处理多表单提交,spring-mvc,jakarta-ee,controller,Spring Mvc,Jakarta Ee,Controller,Spring3MVC使用控制器处理多表单提交 我正在开发具有多种表单的JSP页面。1) 搜索客户,2)搜索产品,3)打印东西等。我有一个不同的表单绑定对象绑定到每个表单,我的控制器代码如下所示 @Controller @RequestMapping(value="/search.do") public class SearchController { @RequestMapping(method = RequestMethod.GET) public String

Spring3MVC使用控制器处理多表单提交

我正在开发具有多种表单的JSP页面。1) 搜索客户,2)搜索产品,3)打印东西等。我有一个不同的表单绑定对象绑定到每个表单,我的控制器代码如下所示

  @Controller
  @RequestMapping(value="/search.do")
  public class SearchController {

    @RequestMapping(method = RequestMethod.GET)
    public String pageLoad(ModelMap modelMap) {
      modelMap.addAttribute("productSearch", new ProductSearchCriteria());
        modelMap.addAttribute("customerSearch", new CustomerSearchCriteria());
        modelMap.addAttribute("print", new PrintForm());
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView searchProducts(@ModelAttribute("productSearch") ProductSearchCriteria productSearchCriteria,
            BindingResult result, SessionStatus status) {
            //Do Product search
            return modelAndView;
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView searchCustomers(@ModelAttribute("customerSearch") CustomerSearchCriteria customerSearchCriteria,
            BindingResult result, SessionStatus status) {
            //Do Customer search
            return modelAndView;
    }

    @RequestMapping(method = RequestMethod.POST)
    public ModelAndView printSomething(@ModelAttribute("print") PrintForm printForm,
            BindingResult result, SessionStatus status) {
            //Print something
            return modelAndView;
    }
  }
上面所说的肯定不会像我想象的那样起作用。我得到一个异常,说“Request method”POST“not supported”。若我在上面的控制器中只有一个POST方法,那个么searchProducts工作得很好。但它不会与POST的多个方法一起使用。我还尝试在JSP中添加隐藏参数,并更改方法签名(类似于下面的内容),结果再次得到相同的异常

  @RequestMapping(method = RequestMethod.POST, params="pageAction=searchProduct")
    public ModelAndView searchProducts(@ModelAttribute("productSearch") ProductSearchCriteria productSearchCriteria,
            BindingResult result, SessionStatus status) {
            //Do Product search
            return modelAndView;
   }
有人能提出实现上述目标的正确方法吗?此外,任何参考资料或进一步阅读将不胜感激。谢谢


编辑#1:以上使用params=“pageAction=searchProduct”的方法非常有效,只要您在JSP中获得正确的隐藏参数(请参见下面的注释)。除此之外,@Bozho和@Biju Kunjummen的答案也非常有用,是解决多表单提交问题的一个很好(可能更好)的选择。

当您有多个表单时,为什么不将这三个表单映射到不同的URL

@RequestMapping("/products")
public ModelAndView searchProducts(..)

@RequestMapping("/customers")
public ModelAndView searchCustomers(..)

并将您的表单操作指向
/search/products
/search/customers
(不需要
.do

您的映射不完全正确@TMan:

  • web.xml中的映射用于获取Spring Dispatcher servlet来处理您的请求- 比如你的情况:

    <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/META-INF/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    
    RequestMapping末尾的.do不应该在那里,因为它纯粹是为了调用Dispatcher servlet,一旦调用它,它将处理到正确控制器方法的调度,因此对/search.do的调用将以控制器结束

  • 现在,可以使用RequestMapping对每个方法进行注释,就像在您的案例中一样,使用RequestMapping的RequestMethod atribute,指定在POST或GET情况下是分派给该方法:

    @RequestMapping(method = RequestMethod.GET)
    @RequestMapping(method = RequestMethod.POST)
    
  • 因此,当/search.do URI有帖子时,将调用相应的方法

    在您的例子中,有多个方法使用RequestMethod.POST属性进行了注释,因此Spring的
    AnnotationMethodHandlerAdapter
    组件根本不知道要分派给哪个方法

    您可以做以下几件事:

  • 按照@Bozho建议的方式,为每个方法放置一个请求映射: @RequestMapping(value=“/customers”method=Request.POST) @RequestMapping(value=“/products”method=Request.POST) 所以现在您的请求URI将是

    /搜索/customers.do /搜索/products.do 你应该做POST来获得正确的分派方法

  • 去掉method=Request.POST,然后依靠上面的@RequestMapping找到正确的方法

  • 您可以向RequestMapping传递一个可选的params属性,这也是帮助Spring找到要分派到的正确方法的一种方法:

    @RequestMapping(方法=Request.POST,params=“customers”)

  • 在请求中使用客户参数或在请求中使用产品参数

    但最简单的是选项1


    编辑1:添加对优秀Spring文档的引用-

    我遇到了相同的问题:在同一页面上有两个表单(注册和联系),两个提交按钮。 每个表单都有自己的Spring验证

    我在一个控制器中成功地做到了这一点:

    @RequestMapping(value = "/contactOrRegister.do", method = RequestMethod.GET)
    public void contactOrRegisterFormGet(@ModelAttribute("contactForm") ContactForm contactForm, @ModelAttribute("registerForm") RegisterForm registerForm) {
        //-----prepare forms for displaying here----
    }
    
    @RequestMapping(value = "/contact.do", method = RequestMethod.POST)
    public String contactFormPost(@ModelAttribute("contactForm") ContactForm contactForm, BindingResult result, final Model model) {        
        contactValidator.validate(contactForm, result);
        if (result.hasErrors()) {
            model.addAttribute("registerForm", new RegisterForm());
            return "contactOrRegister";
        }
        //--- validation is passed, do submit for contact form here ---
    }
    
    @RequestMapping(value = "/register.do", method = RequestMethod.POST)
    public String registerFormPost(@ModelAttribute("registerForm") RegisterForm registerForm, BindingResult result, final Model model) {        
        registerValidator.validate(registerForm, result);
        if (result.hasErrors()) {
            model.addAttribute("contactForm", new ContactForm());
            return "contactOrRegister";
        }
        //--- validation is passed, do submit for register form here ---
    }
    
    我需要创建一个新表单(contact或register),并在验证失败时将其放入模型中,因为“contactOrRegister”视图需要同时显示这两个表单。因此,当“联系人”表格提交并出现错误时,“注册”表格内容将被删除。这条路适合我

    contactOrRegister.jsp包含两种具有不同操作的表单:

     <form:form action="/register.do" modelAttribute="registerForm" method="POST">
        <!-- register form here -->
     </form:form>
    
     <form:form action="/contact.do" modelAttribute="contactForm" method="POST">
        <!-- contact form here -->
     </form:form>
    
    
    
    您可以编写

    @RequestMapping(method={RequestMethod.GET,RequestMethod.POST})


    在同一控制器上使用多个方法时。当用户希望使用GET提交数据时,或者当您使用
    返回“forward:url”时,这非常有用来自另一个控制器。

    您确定使用隐藏字段的方法不起作用吗?是的。我对它为什么不起作用感到困惑。我在这里发现了类似的问题,答案使用了相同的params=“name=value”技巧。很多人投了赞成票,这一定是解决这个问题的唯一办法。很奇怪,它应该会起作用。@axtavt让它起作用了。这显然是一个令人痛苦的错误,我真想让自己蒙羞。我的隐藏参数已按应有的方式定义。你所表达的怀疑让我反复考虑,直到它最终击中我。我没有足够的特权投票给你,但非常感谢你的帮助。谢谢,谢谢。我以前试过,但tomcat一直抱怨“请求的资源不可用”。我确信问题出在web.xml中,我的servlet URL映射只指向*.do。我正在为这项工作制定正确的配置。你的任何建议都很方便。干杯。@TMan-ah,如果您将DispatcherServlet映射到
    *。执行
    ,那么它将不起作用。另一种方法是将它映射到
    /
    ,这样一切都由spring处理。谢谢Bozho,我已经尝试过这种方法,但有些方法对我不起作用。虽然我找到了不同的工作解决方案,但我仍在调查这种方法哪里出了问题。如果这个技巧也能奏效,我会更新问题文本。干杯,嗯。。谢谢你非常详细和有益的解释。它确实澄清了一些困惑。不幸的是,我仍然面临同样的困境。我有一个名为search.JSP的JSP映射到URL>search.do。此页面有三个表单,根据您提交的表单,您可以在同一页面上看到不同的结果,即search.jsp>search.do。我从@Bozho和您的回复中了解到了这一点,并尝试提交m
     <form:form action="/register.do" modelAttribute="registerForm" method="POST">
        <!-- register form here -->
     </form:form>
    
     <form:form action="/contact.do" modelAttribute="contactForm" method="POST">
        <!-- contact form here -->
     </form:form>