qammm
Oct 5th, 2005, 10:00 AM
Hello everybody,
I need something like dynamic forms (remotely similar to Apache Cocoon Forms or serverside Xforms): I am trying to develop a very simple data-entry-application based on multiple different forms. But it should be extensible by users without programming (that means only html/xml editing).
My idea was something along these line:
- Use form definition (a freemarker template with spring bind tags)
- Write a generic form controller that subclasses SimpleFormController but uses a HashMap instead of a JavaBean for input values that can take the input of every form. I can not use JavaBeans because they are static and I need to be able to process different forms inside one controller which may have different input fields (number and id of input fields).
- Build an xml file out of all the input (that is the easy part, since the user will be required to enter an xml input value mapping template also)
- Save that xml file
However the notion of the Bean seems to be spread all over Spring MVC.
And every exception seams to be leading me deeper into the MVC core.
Let me say that I am just learning Spring. Please forgive me if I ask something that should be obvious for the professional Spring developer, but for me it is not (even after extensive searches and documentation reading).
I would be very grateful for every hint or suggestion you can give me.
Thanks in advance.
My current experiments are:
action-servlet.xml:
<bean id="genericFormController" class="qammm.GenericFormController">
<property name="commandName"><value>hashMap</value></property>
<property name="commandClass"><value>java.util.HashMap</value></property>
<!-- <property name="validator"><ref bean="beanValidator"/></property> -->
<property name="formView"><value>genericForm</value></property>
<property name="successView"><value>redirect:genericForm.html</value></property>
<property name="userManager"><ref bean="userManager"/></property>
</bean>
excerpt from GenericFormController:
protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
return new HashMap();
}
protected ServletRequestDataBinder createBinder(HttpServletRequest request, Object command)
throws Exception {
ServletRequestDataBinder binder = new GenericBinder(command, getCommandName());
initBinder(request, binder);
return binder;
}
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command,
BindException errors)
throws Exception {
if (log.isDebugEnabled()) {
log.debug("entering 'onSubmit' method...");
}
HashMap genericData = (HashMap) command;
Iterator it = genericData.values().iterator();
for(String s = (String)it.next();it.hasNext();s =(String) it.next()) {
log.info(s);
}
return new ModelAndView(getSuccessView());
}
GenericBinder:
public class GenericBinder extends ServletRequestDataBinder {
public GenericBinder(Object arg0, String arg1) {
super(arg0, arg1);
// TODO Auto-generated constructor stub
}
protected void applyPropertyValues(MutablePropertyValues mpvs) {
try {
PropertyValue[] pva = mpvs.getPropertyValues();
HashMap target = (HashMap) this.getTarget();
for(int i = 0; i < pva.length; i++){
target.put(pva[i].getName(), pva[i].getValue());
}
}
catch (PropertyAccessExceptionsException ex) {
// TODO: log out exception
}
}
}
genericForm.ftl (Freemarker template):
<#import "/spring.ftl" as spring/>
<#assign xhtmlCompliant = true in spring>
<title>generic form</title>
<form method="post" action="genericForm.html">
<@spring.formInput 'hashMap["first"]', 'id="first"'/>
<@spring.showErrors "<br>", "fieldError"/>
</form>
Now I am stuck here getting an exception:
Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: MethodgetBindStatus on org.springframework.web.servlet.support.RequestCon text
at freemarker.ext.beans.OverloadedMethodModel.exec(Ov erloadedMethodModel.java:112)
at freemarker.core.MethodCall._getAsTemplateModel(Met hodCall.java:93)
at freemarker.core.Expression.getAsTemplateModel(Expr ession.java:89)
at freemarker.core.Assignment.accept(Assignment.java: 91)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.IfBlock.accept(IfBlock.java:82)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Macro$Context.runMacro(Macro.java: 164)
at freemarker.core.Environment.visit(Environment.java :470)
at freemarker.core.UnifiedCall.accept(UnifiedCall.jav a:128)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Macro$Context.runMacro(Macro.java: 164)
at freemarker.core.Environment.visit(Environment.java :470)
at freemarker.core.UnifiedCall.accept(UnifiedCall.jav a:128)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Environment.process(Environment.ja va:156)
at freemarker.template.Template.process(Template.java :219)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.processTemplate(FreeMarkerView.java:2 67)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.doRender(FreeMarkerView.java:221)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.renderMergedTemplateModel(FreeMarkerV iew.java:180)
at org.springframework.web.servlet.view.AbstractTempl ateView.renderMergedOutputModel(AbstractTemplateVi ew.java:160)
at org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:247)
at org.springframework.web.servlet.DispatcherServlet. render(DispatcherServlet.java:839)
at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:616)
at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:543)
at org.springframework.web.servlet.FrameworkServlet.s erviceWrapper(FrameworkServlet.java:390)
at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:341)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter .doFilter(UrlRewriteFilter.java:311)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at com.opensymphony.module.sitemesh.filter.PageFilter .parsePage(PageFilter.java:118)
at com.opensymphony.module.sitemesh.filter.PageFilter .doFilter(PageFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.appfuse.web.MessageFilter.doFilter(MessageFilt er.java:36)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invo keInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(Cont ainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(Co yoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11Conn ectionHandler.processConnection(Http11Protocol.jav a:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(P oolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlR unnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at freemarker.ext.beans.BeansWrapper.invokeMethod(Bea nsWrapper.java:457)
at freemarker.ext.beans.OverloadedMethodModel.exec(Ov erloadedMethodModel.java:108)
... 68 more
Caused by: java.lang.IllegalStateException: Neither Errors instance nor plain target object for bean name 'hashMap["first"]' available as request attribute
at org.springframework.web.servlet.support.BindStatus .<init>(BindStatus.java:138)
at org.springframework.web.servlet.support.RequestCon text.getBindStatus(RequestContext.java:655)
... 74 more[/list]
I need something like dynamic forms (remotely similar to Apache Cocoon Forms or serverside Xforms): I am trying to develop a very simple data-entry-application based on multiple different forms. But it should be extensible by users without programming (that means only html/xml editing).
My idea was something along these line:
- Use form definition (a freemarker template with spring bind tags)
- Write a generic form controller that subclasses SimpleFormController but uses a HashMap instead of a JavaBean for input values that can take the input of every form. I can not use JavaBeans because they are static and I need to be able to process different forms inside one controller which may have different input fields (number and id of input fields).
- Build an xml file out of all the input (that is the easy part, since the user will be required to enter an xml input value mapping template also)
- Save that xml file
However the notion of the Bean seems to be spread all over Spring MVC.
And every exception seams to be leading me deeper into the MVC core.
Let me say that I am just learning Spring. Please forgive me if I ask something that should be obvious for the professional Spring developer, but for me it is not (even after extensive searches and documentation reading).
I would be very grateful for every hint or suggestion you can give me.
Thanks in advance.
My current experiments are:
action-servlet.xml:
<bean id="genericFormController" class="qammm.GenericFormController">
<property name="commandName"><value>hashMap</value></property>
<property name="commandClass"><value>java.util.HashMap</value></property>
<!-- <property name="validator"><ref bean="beanValidator"/></property> -->
<property name="formView"><value>genericForm</value></property>
<property name="successView"><value>redirect:genericForm.html</value></property>
<property name="userManager"><ref bean="userManager"/></property>
</bean>
excerpt from GenericFormController:
protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
return new HashMap();
}
protected ServletRequestDataBinder createBinder(HttpServletRequest request, Object command)
throws Exception {
ServletRequestDataBinder binder = new GenericBinder(command, getCommandName());
initBinder(request, binder);
return binder;
}
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command,
BindException errors)
throws Exception {
if (log.isDebugEnabled()) {
log.debug("entering 'onSubmit' method...");
}
HashMap genericData = (HashMap) command;
Iterator it = genericData.values().iterator();
for(String s = (String)it.next();it.hasNext();s =(String) it.next()) {
log.info(s);
}
return new ModelAndView(getSuccessView());
}
GenericBinder:
public class GenericBinder extends ServletRequestDataBinder {
public GenericBinder(Object arg0, String arg1) {
super(arg0, arg1);
// TODO Auto-generated constructor stub
}
protected void applyPropertyValues(MutablePropertyValues mpvs) {
try {
PropertyValue[] pva = mpvs.getPropertyValues();
HashMap target = (HashMap) this.getTarget();
for(int i = 0; i < pva.length; i++){
target.put(pva[i].getName(), pva[i].getValue());
}
}
catch (PropertyAccessExceptionsException ex) {
// TODO: log out exception
}
}
}
genericForm.ftl (Freemarker template):
<#import "/spring.ftl" as spring/>
<#assign xhtmlCompliant = true in spring>
<title>generic form</title>
<form method="post" action="genericForm.html">
<@spring.formInput 'hashMap["first"]', 'id="first"'/>
<@spring.showErrors "<br>", "fieldError"/>
</form>
Now I am stuck here getting an exception:
Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: MethodgetBindStatus on org.springframework.web.servlet.support.RequestCon text
at freemarker.ext.beans.OverloadedMethodModel.exec(Ov erloadedMethodModel.java:112)
at freemarker.core.MethodCall._getAsTemplateModel(Met hodCall.java:93)
at freemarker.core.Expression.getAsTemplateModel(Expr ession.java:89)
at freemarker.core.Assignment.accept(Assignment.java: 91)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.IfBlock.accept(IfBlock.java:82)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Macro$Context.runMacro(Macro.java: 164)
at freemarker.core.Environment.visit(Environment.java :470)
at freemarker.core.UnifiedCall.accept(UnifiedCall.jav a:128)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Macro$Context.runMacro(Macro.java: 164)
at freemarker.core.Environment.visit(Environment.java :470)
at freemarker.core.UnifiedCall.accept(UnifiedCall.jav a:128)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.MixedContent.accept(MixedContent.j ava:92)
at freemarker.core.Environment.visit(Environment.java :171)
at freemarker.core.Environment.process(Environment.ja va:156)
at freemarker.template.Template.process(Template.java :219)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.processTemplate(FreeMarkerView.java:2 67)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.doRender(FreeMarkerView.java:221)
at org.springframework.web.servlet.view.freemarker.Fr eeMarkerView.renderMergedTemplateModel(FreeMarkerV iew.java:180)
at org.springframework.web.servlet.view.AbstractTempl ateView.renderMergedOutputModel(AbstractTemplateVi ew.java:160)
at org.springframework.web.servlet.view.AbstractView. render(AbstractView.java:247)
at org.springframework.web.servlet.DispatcherServlet. render(DispatcherServlet.java:839)
at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:616)
at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:543)
at org.springframework.web.servlet.FrameworkServlet.s erviceWrapper(FrameworkServlet.java:390)
at org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:341)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:802)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter .doFilter(UrlRewriteFilter.java:311)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at com.opensymphony.module.sitemesh.filter.PageFilter .parsePage(PageFilter.java:118)
at com.opensymphony.module.sitemesh.filter.PageFilter .doFilter(PageFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.appfuse.web.MessageFilter.doFilter(MessageFilt er.java:36)
at org.apache.catalina.core.ApplicationFilterChain.in ternalDoFilter(ApplicationFilterChain.java:186)
at org.apache.catalina.core.ApplicationFilterChain.do Filter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invo ke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invo keInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invo ke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke( StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:118)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invok e(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invo keNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(S tandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(Cont ainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(Co yoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(H ttp11Processor.java:799)
at org.apache.coyote.http11.Http11Protocol$Http11Conn ectionHandler.processConnection(Http11Protocol.jav a:705)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(P oolTcpEndpoint.java:577)
at org.apache.tomcat.util.threads.ThreadPool$ControlR unnable.run(ThreadPool.java:683)
at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at freemarker.ext.beans.BeansWrapper.invokeMethod(Bea nsWrapper.java:457)
at freemarker.ext.beans.OverloadedMethodModel.exec(Ov erloadedMethodModel.java:108)
... 68 more
Caused by: java.lang.IllegalStateException: Neither Errors instance nor plain target object for bean name 'hashMap["first"]' available as request attribute
at org.springframework.web.servlet.support.BindStatus .<init>(BindStatus.java:138)
at org.springframework.web.servlet.support.RequestCon text.getBindStatus(RequestContext.java:655)
... 74 more[/list]