Results 1 to 9 of 9

Thread: using PropertyEditor in JSTL

  1. #1
    Join Date
    Feb 2008
    Posts
    4

    Default using PropertyEditor in JSTL

    hi all,



    I'm new to Springframework and have a problem regarding PropertyEditor.

    I have an application with JSP as frontend and MultiActionController at the other end. Having registered a CustomDateEditor at the controller I can convert well formatted date strings as java.util.Date object successfully, but when I dump the value to JSP (using JSTL tags, as below), the date format is messed up.


    my controller:
    public Map doSomething(req, res, commandObj) {
    ...
    Map map = new Map();
    map.put("commandObj", commandObj);
    return map;
    }


    my JSP:
    ....
    <form:form commandName="commandObj">
    <form:input path="dateField" />
    </form:form>
    ....


    When I look into the InputTag I find it has in fact called for getPropertyEditor() to do the conversion, just that an suitable propertyEditor cannot be found.


    So my question is, is it true that some other component, not MultiActionController, is responsible for the JSP output? If any, how can I register the propertyEditors to it?


    (I've surfed on the web and can only find solutions for SimpleFormController, but no one mention about MultiActionController)



    thx
    george

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    First of all you aren't using JSTL, but the Spring Tag Library (JSTL is the stuff from sun).

    A Controller isn't responsible for the output (MVC Pattern remember?). Just register your PropertyEditors correctly and they should be picked up. Implement the initBind method as documented.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Feb 2008
    Posts
    4

    Default

    Thanks for your prompt response, mdeinum.

    I'm sure it's somewhere else other than controller that should take care of this, but I have no idea what it is. I just can't find it from the document.

    FYI, I am using org.springframework.web.servlet.view.JstlView, not sure if it's related but can't see anything related to PropertyEditor in it.


    thx
    george

  4. #4
    Join Date
    Dec 2005
    Location
    California
    Posts
    63

    Default In the controller

    If you register the property editor in the controller, it looks like this:
    Code:
    @Override
    	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
        throws ServletException {
    	    binder.registerCustomEditor(MyObject.class, new MyObjectEditor());
    	  ..
    	}
    and then the editor
    Code:
    public class MyObjectEditor extends PropertyEditorSupport {
    	
    
    	@Override
    	public String getAsText() {
    		if(getValue() instanceof MyObject) {
    			MyObject d = (MyObject)getValue();
    			return d.getId().toString(); 
    		} else if(getValue() instanceof Long) {
    			return getValue().toString();
    		}
    		return "-";
    	}
    
    	@Override
    	public void setAsText(String text) throws IllegalArgumentException {
    		MyObject cat = null;
    		if(!text.equals("-")) {
    			..
    		}
    		setValue(cat);
    	}
    }
    Your actual implementation depends on your needs.
    I hope this helps.
    Janos

  5. #5
    Join Date
    Feb 2008
    Posts
    4

    Default

    thanks mucsij.

    Yes that's exactly what I've done, and it works perfectly when a date is input and read from JSP. Just that the format got messed up when it's get from serverside and displayed on the JSP page.

  6. #6
    Join Date
    Dec 2005
    Location
    California
    Posts
    63

    Default Formatting dates

    Have you tried formatting the date back and forth:
    Code:
    public class MyObjectEditor extends PropertyEditorSupport {
    	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    
    	@Override
    	public String getAsText() {
    		if(getValue() instanceof Date) {
    		   return dateFormat.format(getValue());
    		}
    		return ""; 
    	}
    
    	@Override
    	public void setAsText(String text) throws IllegalArgumentException {
    		
    		if(text!=null && !text.equals("")) {
    		   setValue(statementFormat.parse(text));
    		} else {
                       setValue(null);
    		}
    	}
    }
    I hope this helps.
    I am not sure if you can accomplish the same with the JSTL <fmt> tags.
    Janos

  7. #7
    Join Date
    Feb 2008
    Posts
    4

    Default

    It doesn't seem to be problem of the propertyEditor itself. It's the tag not having reference to the propertyEditor I registered in controller.

    FYI, in order to see how the <form:input> tag is invoked, I've overridden it and show some debug message and the stackTrace. From there you can see, getPropertyEditor() in fact returns a null inside InputTag. And, along the stackTrace, I cannot find any component that I can register propertyEditor to.

    thx
    george



    Code:
    [InputTag.writeValue.getPropertyEditor].................................. null
    [InputTag.writeValue.getBindStatus].................................. BindStatus: expression=[holiday.description]; value=[New Year Day]
    
    
    java.lang.Throwable
    	at org.springframework.web.servlet.tags.form.InputTag.writeValue(InputTag.java:166)
    	at org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
    	at org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:90)
    	at org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:77)
    	at org.apache.jsp.masterData.holiday_005fform_jsp._jspx_meth_form_005finput_005f1(holiday_005fform_jsp.java:617)
    	at org.apache.jsp.masterData.holiday_005fform_jsp._jspService(holiday_005fform_jsp.java:217)
    	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
    	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
    	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
    	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:594)
    	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:505)
    	at org.apache.taglibs.standard.tag.common.core.ImportSupport.acquireString(ImportSupport.java:296)
    	at org.apache.taglibs.standard.tag.common.core.ImportSupport.doEndTag(ImportSupport.java:161)
    	at org.apache.jsp.masterData.holidayDetails_jsp._jspx_meth_c_005fimport_005f1(holidayDetails_jsp.java:355)
    	at org.apache.jsp.masterData.holidayDetails_jsp._jspx_meth_form_005fform_005f0(holidayDetails_jsp.java:193)
    	at org.apache.jsp.masterData.holidayDetails_jsp._jspService(holidayDetails_jsp.java:127)
    	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
    	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
    	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:691)
    	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:469)
    	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:403)
    	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
    	at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:111)
    	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:255)
    	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1142)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:879)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:792)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
    	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:119)
    	at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:55)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:111)
    	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:265)
    	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
    	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:166)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter(BasicProcessingFilter.java:173)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:271)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:249)
    	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
    	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)
    	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
    	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
    	at java.lang.Thread.run(Thread.java:595)

  8. #8
    Join Date
    Dec 2005
    Location
    California
    Posts
    63

    Default Code please

    Hello,
    Can you please post the relevant code (HTML, controller, editor, command class) so I can reproduce this.
    Since you register the property editor for Date, the registration should look like this:
    Code:
    @Override
    	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
        throws ServletException {
    	    binder.registerCustomEditor(java.util.Date.class, new MyDateEditor());
    	  ..
    	}
    Janos

  9. #9
    Join Date
    Jun 2008
    Posts
    1

    Default

    Hello,

    same problem with me (like the one described) above. Attached a short outline:

    After having noticed that java.util.Date doesn't have a default PropertyEditor attached, I added one to "initBinder" of my controller:

    binder.registerCustomEditor(java.util.Date.class, new DateEditor());

    Works basically as desired when parsing the form data, but didn't change anything when using form:input for rendering the date (to String). The date is simply rendered using Date.toString() (which is the fallback method of ValueFormatter). Looks like this:

    <form:input path="heatingPeriod1Begin" id="heatingPeriod1Begin" />

    and renders to

    Mon Jan 01 00:00:00 CET 2007

    After that I had a look at the source and discovered that the InputTag uses ValueFormatter.getDisplayString for rendering. The InputTag relies on AbstractDataBoundFormElementTag for "getPropertyEditor", which bases on getBindStatus for providing the editor. BindStatus doesn't set the editor in normal case ( this.errors == null), so the "this.editor" field must be null.

    Greetings,
    Helmut

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •