Announcement Announcement Module
Collapse
No announcement yet.
using PropertyEditor in JSTL Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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.

    Comment


    • #3
      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

      Comment


      • #4
        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.

        Comment


        • #5
          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.

          Comment


          • #6
            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.

            Comment


            • #7
              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)

              Comment


              • #8
                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());
                	  ..
                	}

                Comment


                • #9
                  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

                  Comment

                  Working...
                  X