Часто, при разработке веб-приложений на Spring возникает ситуация, когда приходится объеденять сразу несколько действий в один контроллер. Для этого Бог и создал MultiActionController. Однако, Бог не предусмотрел прямой возможности обрабатывать одним таким контроллером сразу несколько форм. Вот как раз о вмешательстве простого человека в дела Божьи и пойдет речь в этой статье.Итак, братья и сестры, нам понадобятся:
- SimpleFormController
- MethodNameResovler
Первое, что нужно сделать – это реализовать собственный GodMethodNameResovler, который будет имплементировать стандартный интерфейс MethodNameResolver и поместить туда примерно такой код:
1 public class GodMethodNameResolver implements MethodNameResolver { private Properties mapping; private String defaultMethodName; public void setMappings(Properties mappings) { this.mappings = mappings; } public void setDefaultMethodName(String defaultMethodName) { this.defaultMethodName = defaultMethodName; } public void afterPropertiesSet() { if (mapping == null) { throw new IllegalArgumentException("Methods mapping property required."); } } public String getHandlerMethodName(HttpServletRequest request) throws NoSuchRequestHandlingMethodException { for (Iterator it = this.mappings.keySet().iterator(); it.hasNext();) { String submitParamter = (String)it.next(); if (WebUtils.hasSubmitParameter(request, submitParamter)) { return (String)mapping.get(submitParamter); } } return defaultMethodName; }}
Когда с этим покончено, создадим абстрактный контроллер, который в последствии будут наследовать все остальные MultiActionController’ы:
1 public abstract class AbstractMultiActionFormController extends SimpleFormController { private MethodNameResolver methodNameResolver; protected ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception { if (errors.hasErrors() || isFormChangeRequest(request)) { return showForm(request, response, errors); } else { String methodName = getMethodNameResolver().getHandlerMethodName(request); Method m = (Method)this.getClass().getMethod(methodName, new Class[] {HttpServletRequest.class, Object.class, BindException.class}); if (m == null) { throw new NoSuchRequestHandlingMethodException(methodName, getClass()); } List params = new ArrayList(3); params.add(request); params.add(command); params.add(errors); return (ModelAndView) m.invoke(this, params.toArray(new Object[params.size()])); } } public void setMethodNameResolver(MethodNameResolver methodNameResolver) { methodNameResolver = methodNameResolver; } public MethodNameResolver getMethodNameResolver() { return methodNameResolver; }}
Также, потребуется описать все это в конфиге спринга:
1 <bean id="godMethodNameResolver" class="com.myapp.GodMethodNameResolver"> <property name="mappings"> <props> <prop key="testAction">testAction</prop> </props> </property> <property name="defaultMethodName"><value>testAction</value></property></bean><bean id="blessMultiFormController" class="com.myapp.BlessMultiFormController"> <property name="methodNameResolver"><ref bean="godMethodNameResolver"/></property> <property name="sessionForm"><value>true</value></property> <property name="successView"><value>someformview</value></property> <property name="commandName"><value>somecommand</value></property> <property name="formView"><value>someformview</value></property></bean>
И последний шаг – создание контроллера:
1 public class BlessMultiFormController extends AbstractMultiActionFormController { public ModelAndView testAction(HttpServletRequest request, Object command, BindException errors) throws Exception { // do something with form return showForm(request, errors, getFormView()); }}
Алилуя!
Не читаемые исходники: одной строкой
1. Вы, мне кажется, не понимаете назначение SimpleFormController и логику его работы.
2. … Итак, братья и сестры, нам понадобятся:
* SimpleFormController
* MethodNameResovler
Хотя MethodNameResovler здесь ни разу нет
3. Ваш GodMethodNameResolver не имеет смысла, т.к. есть куча других ресолверов, готовых удовлетворить даже извращенцев.
Ничего личного, но тема не раскрыта и уж совсем непонятно как вы собираетесь используя этот код реализовать <>. На эту тему много ресурсов, почитайте.
PS Соглашусь с Олегом.
Прошу меня извинить за 2 пункт.
Спутал с MultiActionController
=)))) Вместо <> – прямую возможность обрабатывать одним таким контроллером сразу несколько форм
2Oleg:
Сорри, сайт сейчас находится немного в запущенном состоянии. Я работаю над новой версией сейчас. Сайт будет на Grails и в HTML5
2Nitro:
Насчет множества резолверов не припомню, чтобы нашел подходящий в версии 2.0. Может в 3-й уже есть, не проверял.
Кроме того, не вижу смысла на сегодняшний день использовать Spring в чистом виде для веб-приложений. Так-как есть Spring Roo и Grails.