Announcement Announcement Module
Collapse
No announcement yet.
Binding data with spring annotations Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Binding data with spring annotations

    Hi,
    I'm new to spring and I'm asked to do a project with spring annotations.
    I have a Form and I'm not able to binds its data. It's been a while now, that I'm looking on the internet but none of the answers I've found were applicable or worked.
    Here are the relevant lines of my code

    /******************JSP***********************/

    Code:
    <form:form method="post" action="upload.do" enctype="multipart/form-data" modelAttribute="myForm">
              <input type="file" name="file"/>    
               enabledBarcodeDecoding<form:checkbox path="myBool"/>
               <input type="submit"/>
    </form:form>

    /***************CONTROLLER*******************/
    Code:
    @Controller
    @RequestMapping("/upload.do" )
    public class MyController {
     @RequestMapping(method = RequestMethod.POST)
     public void onSubmit(
       @ModelAttribute("myForm" ) MyForm myForm,
       HttpServletResponse response) {
     
      //code using myForm.file & myForm.myBool
      //I return void because in this controller I use the HTTPServletResponse to download a file given by a web service
     }
     
     
     @InitBinder
     public void initBinder(WebDataBinder binder) {
      // to actually be able to convert Multipart instance to byte[]
      // we have to register a custom editor
      binder.registerCustomEditor(byte[].class,
        new ByteArrayMultipartFileEditor());
      // now Spring knows how to handle multipart object and convert them
     }
     
     @ModelAttribute("readerExtensionForm" )
     public ReaderExtensionForm getReaderExtensionForm() {
      return new ReaderExtensionForm();
     }
    }

    /***************MyForm*******************/

    Code:
    public class MyForm {
     
     private byte[] file;
     
     private boolean myBool=true;
     
     public MyForm() {
      super();
     }  
     
     public boolean isMyBool() {
      return myBool;
     }
     
     public void setMyBool(boolean myBool) {
      this.myBool = myBool;
     }
     
     public void setFile(byte[] file) {
             this.file = file;
     }
     
     public byte[] getFile() {
             return file;
     }
    }
    /*****************ERROR**************************/

    Code:
    2009-06-05 11:14:25,113 ERROR org.springframework.web.servlet.tags.form.CheckboxTag - Neither BindingResult nor plain target object for bean name 'myForm' available as request attribute
    java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'myForm' available as request attribute
     at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
     at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:172)
     at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:192)
     at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:158)
     at org.springframework.web.servlet.tags.form.AbstractCheckedElementTag.autogenerateId(AbstractCheckedElementTag.java:80)
     at org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.resolveId(AbstractDataBoundFormElementTag.java:136)
     at org.springframework.web.servlet.tags.form.AbstractSingleCheckedElementTag.writeTagContent(AbstractSingleCheckedElementTag.java:81)
     at org.springframework.web.servlet.tags.form.CheckboxTag.writeTagContent(CheckboxTag.java:51)
     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.fileUpload_jsp._jspx_meth_form_005fcheckbox_005f0(fileUpload_jsp.java:190)
     at org.apache.jsp.fileUpload_jsp._jspx_meth_form_005fform_005f0(fileUpload_jsp.java:112)
     at org.apache.jsp.fileUpload_jsp._jspService(fileUpload_jsp.java:70)
     at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
     at java.lang.Thread.run(Unknown Source)

    /************************************************** ***************/

    It's been a while now, and I don't know what else to do. It might be a really stupid error but I don't know spring enough to find it, and reading & re-reading the manual did not help me.
    Thanks for helping me !!!
    Last edited by Toinou87; Jun 8th, 2009, 04:24 AM.

  • #2
    Hi ,

    Could you post you servlet-xml file. You need to specify the codebas for your beans in the servlet-xml

    Thanks
    Manish

    Comment


    • #3
      I have solved my problem by using <input type="checkbox" instead of <spring:checkbox.

      Nonetheless I m interested in your answer as I'll probably have to use other spring forms

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
      	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
      	xmlns:p="http://www.springframework.org/schema/p"
      	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      
          <context:component-scan base-package="my.package" />
          
          <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
      
          <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
       
      	<bean id="viewResolver"
      		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      		<property name="order" value="1" />
      		<property name="prefix" value="/WEB-INF/views/" />
      		<property name="suffix" value=".jsp" />
      	</bean>
      	
        <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
          <property name="basename" value="classpath:ApplicationResources"/>
        </bean>
      
      	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!-- one of the properties available; the maximum file size in bytes -->
          <property name="maxUploadSize" value="1000000"/>
      	</bean>
      	
      </beans>

      Comment


      • #4
        Just one question, where is your GET method, displaying the form ?
        It's in this method you should prepare your backing object.
        This exception ususally happens when no backing object has been prepared for binding.

        Comment


        • #5
          I don't understand what you call "GET method, displaying the form"

          if thats the GET method that sends me to the jsp that contains the form it's

          Code:
          @Controller
          @RequestMapping("/fileUpload.htm")
          public class FileUpload {
          	@RequestMapping(method = RequestMethod.GET)
          	public void onSubmit(){
          	}
          }
          and with my view resolver it goes to /WEB-INF/views/fileUpload.jsp which contains the form.

          Is that what you ask for?

          Comment


          • #6
            Yes. With spring, any form submit with automatic binding is a two phases process :

            - User comes with a GET request => You have to prepare your backing object for future binding, then display the form
            - User comes with a POST request => Automatic binding occurs, then the populated backing object is available for validation (if you want to). If any error occurs during binding or validation, usually you use the same view as in step 1 to let the user correct his errors. If no error occurs, you do whatever you want with the backing object and redirect the user to another page.

            GET and POST requests should come at the same URL.
            Here is a complete example :

            Code:
            @Controller
            @RequestMapping("/upload.do")
            public class MyController {
            
              @RequestMapping(method = RequestMethod.GET)
              public String showForm(ModelMap model) {
                // Prepare backing object
                model.addAttribute("command", new MyForm());
                // Show form view
                return "form-view";
              }
            
              @RequestMapping(method = RequestMethod.POST)
              public String onSubmit(@ModelAttribute("command") MyForm myForm, BindingResult result) {
                  // Validate the form backing object, optional
                  validator.validate(myForm, result);
                  if(result.hasError()) {
                    // There are errors, going back to form
                    return "form-view";
                  }
            
                  // Do business with form backing object
                  ...
            
                  // Redirect user to another page (redirect after POST)
                  return "redirect:./another-page.html";
              }
            
            }
            Hope this makes you things clearer.

            Comment


            • #7
              Indeed it's clearer (I think)!

              So: the fact that I have 2 controllers:
              1 to go to the jsp
              1 to use the form
              is not good

              it would be better if I use your example to have:
              1 controller with 2 mappings (for example : by changing the action name in my form and in the controller to "/fileUpload.htm")

              Right now I'm working on other stuffs (as I had found a (bad) solution) but I shall come back on this soon and I'll post here again if I get any problem.

              Whatever thanks a lot for your explanations, it makes me understand a bit more Spring and MVC ^^

              Comment

              Working...
              X