TMa*_*Man 8 controller spring-mvc java-ee
Spring 3 MVC处理多个表单提交控制器.
我正在开发具有多种形式的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;
}
}
Run Code Online (Sandbox Code Playgroud)
上面肯定不会像我想象的那样工作.我得到例外说'请求方法'POST'不支持'.如果我在控制器上面只有一个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;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议正确的方法来实现上述?此外,任何对源材料或进一步阅读的参考将不胜感激.谢谢.
编辑#1:使用params ="pageAction = searchProduct"的上述方法可以完美地工作,只要您在JSP中获得隐藏参数(请参阅下面的注释).除此之外,@ Bozho和@Biju Kunjummen的答案也非常有帮助,并且是一个很好的(可能更好的?)替代方案来处理多个表单提交.
Bij*_*men 12
你的映射不完全正确@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>
Run Code Online (Sandbox Code Playgroud)
appServlet*.do所以现在任何以.do结尾的URI请求都将由Spring的DispatcherServlet处理
控制器可以有一个映射,就像你的情况一样:
@Controller @RequestMapping(value ="/ search.do")
但是你出错的地方是控制器的RequestMapping:
@Controller
@RequestMapping(value="/search")
Run Code Online (Sandbox Code Playgroud)
RequestMapping末尾的.do不应该存在,因为它纯粹是为了调用Dispatcher servlet,一旦被调用它将处理调度到正确的Controller方法,所以你对/search.do的调用最终会与控制器.
现在,每个方法都可以使用RequestMapping进行注释,就像你的情况一样,使用RequestMapping的RequestMethod属性,指定在POST或GET的情况下是否调度给方法:
@RequestMapping(method = RequestMethod.GET)
@RequestMapping(method = RequestMethod.POST)
Run Code Online (Sandbox Code Playgroud)因此,当对/search.do URI进行POST时,将调用适当的方法.
在您的情况下,有多个使用RequestMethod.POST属性注释的方法,因此AnnotationMethodHandlerAdapterSpring 的组件根本不知道要分派到哪个方法.
你可以做几件事:
为每个方法设置一个请求映射,方式由@Bozho建议:@RequestMapping(value ="/ customers"方法= Request.POST)@RequestMapping(value ="/ products"方法= Request.POST)所以现在你的请求URI了将会
/search/customers.do /search/products.do你应该做POST以获得正确的调度方法.
一起摆脱method = Request.POST并依赖于上面的@RequestMapping来找到正确的方法.
您可以将可选的params属性传递给RequestMapping,这也是一种帮助Spring找到正确的方法来分派的方法:
@RequestMapping(method = Request.POST,params ="customers")
请求中的客户参数或请求中的产品参数.
最简单的是选项1.
编辑1:添加对一个好的Spring文档的引用 - http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html
当您有多个表单时,为什么不将这三个表单映射到不同的URL?
@RequestMapping("/products")
public ModelAndView searchProducts(..)
@RequestMapping("/customers")
public ModelAndView searchCustomers(..)
Run Code Online (Sandbox Code Playgroud)
并指出你的表格行为/search/products和/search/customers(不需要.do)
我遇到了同样的问题:两个表单(注册和联系人)在同一页面上有两个提交按钮.每个表单都有自己的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 ---
}
Run Code Online (Sandbox Code Playgroud)
我需要创建一个新表单(联系人或注册表)并在验证失败时将其放入模型中,因为"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>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45976 次 |
| 最近记录: |