Spring Roo: Saving/Retreving BLOB object in Spring Roo

After reading the excellent article titled Saving/Retreving BLOB object in Spring MVC/Hibernate immediately came to my mind:

  1. How would it be the process of recreating the same example but using Spring Roo.
  2. What would it be the similarities/differences in the projects source code.

The article assumes the Reader is a Developer with some familiarity with Spring Roo. For introductory information about Spring Roo vist http://www.ibm.com/developerworks/java/library/os-springroo1/index.html?ca=drs-.

Project setup

Spring Roo brings alternatives for setting up a project: a) Entering project using a script file or b) Creating the database first and reverse engineering it using Roo DBRE commands.

For this article I am using option a), via an script file. Option b) is specially convenient for projects with an database already in place. I’ll vist Roo DBRE in a coming article in the near future.

Script File

project --topLevelPackage org.pragmatikroo.roodocman
persistence setup --provider HIBERNATE --database MYSQL --databaseName roodocman --userName <username> --password <password>
entity		--class ~.domain.Document
field string 	--fieldName name 		--notNull --sizeMax 30
field string 	--fieldName description 	--sizeMax 500
field string 	--fieldName filename 		--notNull 
//field blob 	--fieldName content		--notNull //Type not supported by Roo 
field string 	--fieldName contentType 	--notNull 
field numbert	--fieldName size -
controller all 	--package ~.web
perform clean
perform eclipse

Notice content field is of type blob. This field would have to be entered manually into the entity class. You can use the IDE of your choice. I use STS. Either you use STS or the native Roo shell, the project would need to be synced by Roo after the change. More on this later.

Generate Entity Class

package org.pragmatikroo.roodocman;

@RooJavaBean
@RooToString
@RooEntity
public class Document {

    @NotNull
    @Size(max = 30)
    private java.lang.String name;

    @NotNull
    @Size(max = 500)
    private java.lang.String description;

    private java.lang.String filename;

    @NotNull
    @Lob
    @Basic(fetch = FetchType.LAZY)
    private byte[] content;

    private java.lang.String contentType;

    private java.lang.Long size;
    
    @Transient
    @Size(max = 100)
    private String url ;
}

Please review the seminal article for more information about the example entity fields. All highlighted code is manually added to the original file created by Roo. Why I added field size and url directly into the entity class?. I could have entered referred fields using the shell too. Right?. I did it in purpose to mentioned that Spring Roo is a round-trip tool. There are two more fields not shown in the entity class. They are the id and version fields, Roo automatically handle them using an ITD. Details about round-trip capabilities and how Roo uses ITDs, please visit Spring Roo website at http://www.springsource.org/roo. One more thing about the blob field. DBMS have different type of blobs. Verify that your project database is using the right one for your purposes.

As mention before: always make sure that Roo synced your latest changes. That would save you a lot of confusion.

It is a good time to deploy the application and verify that everything is working find to this point.

Required Source code changes

Well, to this point Spring Roo has done a lot for us. Properly setup the project. Created a Maven pom.xml with all required dependencies -well, almost; more on this below-. Generate all the code necessary for having a working web app. If this not enough, Roo is there in the background monitoring the project against any possible change.

With exception of the blob field -content- all the other fields are ready to go. Roo took care of them. In order to save/retrieve data from the blob field, we need to modify code in the client and in the server side for allowing file uploads.

Server Side Changes

Basically we need code that allows us to save/retrieve documents that include a blob field. The documents are entered using a web form. Typically Roo by default, generates client and server side code for having CRUD operations for every entity. I am not allowing updates in this version of the application. So, I disabled it, by setting the update=false in the @RooWebScaffold annotation. Please make sure next code is included in the DocumentController project file.

@RooWebScaffold(path = "documents", formBackingObject = Document.class, update=false)
@InitBinder
protected void initBinder(HttpServletRequest request, 
    				   ServletRequestDataBinder binder)
				   throws ServletException {
	binder.registerCustomEditor(byte[].class,   	newByteArrayMultipartFileEditor());
    }
@RequestMapping(value="savedoc",  method = RequestMethod.POST)
public String createdoc(@Valid Document document,
    				BindingResult result, 
    				Model model,
    				@RequestParam("content") MultipartFile content,
    					 	HttpServletRequest request) {
    	
    	document.setContentType(content.getContentType());
    	document.setFilename(content.getOriginalFilename());
    	document.setSize(content.getSize());

    	log.debug("Document: ");
    	log.debug("Name: "+content.getOriginalFilename());
    	log.debug("Description: "+document.getDescription());
    	log.debug("File: " +content.getName());
    	log.debug("Type: "+content.getContentType());
    	log.debug("Size: "+content.getSize());
        if (result.hasErrors()) {
            model.addAttribute("document", document);
            return "documents/create";
        }
        document.persist();
        
        return "redirect:/documents?page=1&size=10" +   			encodeUrlPathSegment(document.getId().toString(), request);
    }
    
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String show(@PathVariable("id") Long id, Model model) {
    	Document doc = Document.findDocument(id);
    	doc.setU("/documents/showdoc/"+id);
        model.addAttribute("document", Document.findDocument(id));
        model.addAttribute("itemId", id);
        return "documents/show";
    }
    
@RequestMapping(value = "/showdoc/{id}", method = RequestMethod.GET)
public String showdoc(	@PathVariable("id") Long id,
    				HttpServletResponse response,
    				Model model) {
   Document doc = Document.findDocument(id);
    	        
   try {
          response.setHeader("Content-Disposition", "inline;filename=\"" +doc.getFilename()+ "\"");

          OutputStream out = response.getOutputStream();
          response.setContentType(doc.getContentType());
          IOUtils.copy( new ByteArrayInputStream(doc.getContent()),out);
            out.flush();
         
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

The code above allows CRUD operations with all the document fields including the blob. Very-very important: all this source code must be placed in the DocumentControler.java file to avoid been removed by Roo when the project is synced for changes.

Client Side Changes

On client side, I created a create custom form. Please replace the content of the create.jspx, with:

Create.jpsx Form

<form:multi id="fc_org_pragmatikroo_roodocman_domain_Document" modelAttribute="document" path="/documents/savedoc" render="${empty dependencies}" z="O7jiRGyhKQOUnBT8yJ9W4XU6VrQ=">
      <field:input field="name" id="c_org_pragmatikroo_roodocman_domain_Document_name" max="30" required="true" z="K3YncHn7F+HtBX/zgCZMYM6VO7k="/>
      <field:textarea field="description" id="c_org_pragmatikroo_roodocman_domain_Document_description" required="true" z="/RLpJWAf9zVjHtRapWIFve8JB8Y="/>
      <field:input field="filename" id="c_org_pragmatikroo_roodocman_domain_Document_filename" render="false" z="u4EclOEjQnID4g34VPv9zu9+qPo="/>
      <field:file field="content" id="c_org_pragmatikroo_roodocman_domain_Document_content" required="true" z="GZHlfc+o4h7EBA/SZ8/yXMVenOw="/>
      <field:input field="contentType" id="c_org_pragmatikroo_roodocman_domain_Document_contentType" render="false" z="jtq5/DHhBTgNImjac/d4AIfpCzA="/>
      <field:input field="size" id="c_org_pragmatikroo_roodocman_domain_Document_size" render="false" validationMessageCode="field_invalid_integer" z="ONDmhU5Eg5pw1j8LgTz9sXjOm6E="/>
      <field:textarea field="url" id="c_org_pragmatikroo_roodocman_domain_Document_url" render="false" z="bQ3FUVGL01nfWselK7WDPUD65Rw="/>
</form:multi>

As you can see, the form depends on two custom tagx files -multi.tagx and file.tagx- not included in the Spring Roo tag library. These two tags handle the blob field input.

spring-roo-blob-object

Create Form

Show.jpx Form

<page:show id="ps_org_pragmatikroo_roodocman_domain_Document" object="${document}" path="/documents" update="false" z="J8X2O2T06x6jYb3WAyaNiTPGVZ0=">
      <field:display field="name" id="s_org_pragmatikroo_roodocman_domain_Document_name" object="${document}" z="VZEPJgXqYkqaHpDDPTcYr6DAjsM="/>
      <field:display field="description" id="s_org_pragmatikroo_roodocman_domain_Document_description" object="${document}" z="CeXQhSyEDeLn1Iu2hblanNbVc+A="/>
      <field:display field="filename" id="s_org_pragmatikroo_roodocman_domain_Document_filename" object="${document}" z="2HT3+zT1+1ft5kN4KhvXFWT9QnM="/>
      <field:display field="contentType" id="s_org_pragmatikroo_roodocman_domain_Document_contentType" object="${document}" z="FgCNUQ2KCygzKpUbP06Nxyjyfd8="/>
      <field:display field="size" id="s_org_pragmatikroo_roodocman_domain_Document_size" object="${document}" z="WdQ4wob2LThzMpucODZRa275TBc="/>
      <field:frame field="url" id="s_org_pragmatikroo_roodocman_domain_Document_url" object="${document}" render="true" z="user-managed"/>
</page:show>

This form depends on a custom tag frame.tagx. Basically is a iframe html for rendering images.

spring-roo-blob-show-form

Show Form

spring-roo-blob-list-form

List Form

Little issue with a missed dependency: When you deploy the app -after the file upload changes- you will find a missing dependence error.

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.0.1</version>
</dependency>

This is it!.

Download Source

Click here to download source code (ZIP, 94kb).

Conclusion

Well, the Reader has been exposed to two pretty close but at the same time different ways of implementing a particular web application project. Both are using the same high quality open source code Java-based development stack: Spring 3.X. I believe both ways are good and valid. There is a significant difference in Spring Roo approach though. Roo advocates for removing the “unnecessary abstractions” from web development. So, you won’t find Daos or Services classes in a typical Roo project. This is totally fine with me. However, it is a subject still in revision by the community at large. Not to mention that nothing stops you for implementing them if you need/want them. If you allow me one final point, I like better Roo approach because it gives me more time for thinking and figuring our how to solve the problem.



66 Comments

  • Jochen Szostek 4 February, 2011, 1:41

    Thanks for sharing!

    Might merge this into my project(s) and if I might find useful stuff to be added, I’ll be back. :)

    grts

  • Jose Delgado 4 February, 2011, 2:11

    Jochen, publish the link when possible… It will be great to see it working on other projects.
    If you want to see it working now. Visit the WorldAlmanac on the Cities Menu.

    Cheers jD

  • Jose Delgado 4 February, 2011, 2:34

    Jochen,

    It is the Document Document showcase…

    Thx
    jD

  • Pedro Cavaléro 4 February, 2011, 7:30

    Thank you! I was looking for it for a while and I think your post is the only place to get this information! Thanks for sharing!

  • cblicious 15 February, 2011, 17:52

    Thanks very much fpr this great sample ! :D

  • Randy 28 February, 2011, 18:40

    Great tutorial. Thanks! One question though. Will the browser cache the image given that it doesn’t change?

  • Faroo 11 March, 2011, 17:06

    Web site is very useful for me but i want this application in struts
    can help me?

  • jD 11 March, 2011, 20:50

    Faroo,

    I suggest you review article in this link http://viralpatel.net/blogs/tutorial-save-get-blob-object-spring-3-mvc-hibernate/. It is closer to an struts implementation. Or just
    google “struts file uploads” you will tons of implementations out there.

    Thx
    jD

    • Faroo 12 March, 2011, 9:39

      Hi JD ,

      I saw u r message but i want retrive image from database and display in jsp using form,DAO,DO i am tring to display but some thing is wrong .i got the imgdata but how can i display in jsp ,i saw google they r using but they r also cant display img so please send me some source code to me plz help me?

      ThX&regards
      —————-
      faroo

  • Faroo 12 March, 2011, 9:43

    Hi Jd,
    the above application display the imgage from database how can i display in my jsp like above page i am also using same fields and same data but retriving data success but how can i display

  • jac 18 March, 2011, 18:09

    Good tutorial. When i try it , I have error with multi-tagx et file-tagx file , I don’t know the content of this file .

    Thanks for your help

    • Lifang 5 June, 2011, 16:05

      @ jac have you been able to s0lve this issue i am having internal error because of the multi tag for form too

  • jD 18 March, 2011, 20:17

    @ jac,

    What kind of error?…
    Many other readers have tried it without any problem. Check you development configuration.

    Thank you

  • Niklas Saers 24 March, 2011, 14:36

    Dear JD, thanks for a great article. Just one question: with this approach you load the entire BLOB up in RAM before sending it, right? While this works great for small images, larger files will be a problem. Do you have any recommendation on how to keep the memory footprint of the request low while keeping the simplicity you’re offering?

    Cheers

    Nik

    • jD 24 March, 2011, 19:18

      @Nik,

      Wow thank YOU. This is the best compliment you can give… Simplicity! I like it.
      On your question: You have to use the file system for the case you mention.
      I will publish such implementation on my website soon.
      http://pragmatikroo.blogspot.com/

      Thank you and b. roogards!
      jD

  • Diego 21 April, 2011, 20:55

    Hi Jose,

    I think Spring Roo in the intention is a very nice technology.
    What its pitfall is , in my opinion, is the fact that it tries to bring Rails concept to the Java world, something Grails has already done.
    I have also written about Roo: http://a-developer-life.blogspot.com/2011/03/spring-roo-what-disappointment.html

    • jD 25 April, 2011, 19:13

      Hi Diego,

      I understand your disappointment with Roo… I have my concerns too; but they are oftotally different nature: I am more concern on the human component of SR than in the software part.

      I bet you; you would have a 180 degrees opinion about SR-or at least much+much better- if there would be available sources and materials that show you how-to apply SR on solving real-world-java-web-development. BTW this is what I’ve been successfully doing with Roo.
      Please Google: “Spring Roo Jose Delgado” and you will see what I am taking about.

      I have the perception that SR Management believes that the community should and would self-satisfy the own requirements out of what they are delivering. The reality is: This not happening. Consequently Developers get disenchanted with Roo.

      On the other hand; I believe Rails, Grails and the Agile stuff are kind-of placebos: they don’t solve the problem but make you fell well -for sometime-.

      B. Roogards
      jD

  • N. Berntsen 10 May, 2011, 18:52

    Great that you share this stuff. A little feedback

    Your code sample:

    newByteArrayMultipartFileEditor());

    should have a space in it:

    new ByteArrayMultipartFileEditor());

    Moving the download link up in bit in the blog might help find it.

  • jD 11 May, 2011, 10:11

    Hello N. Berntsen ,

    Thank you for bringing it to my attention…
    The source code is coming from compiled/executable code. So the issue found happen when the article was out to my hands. I don’t want to sound defensive or blame others. I only say that is a weakness of the open source ecosystem and it shouldn’t be a big deal.

    B. Roogards
    jD

  • jD 11 May, 2011, 12:11

    @N. Berntsen,

    Your site is showing an error when I tried to submit following blob…

    Couple of question on the applicability of Model2Roo. Roo creates only scaffold-ed implementations which will be changed by the developer all the time. 1)Is Model2Roo able to reflect the introduced changes to the roo script and to uml project?

    2)Most of the time you use Roo DBRE tool to create the project entities from a legacy database. How do you apply Model2Roo in this case?

    B. Roogards
    jD

    • N. Berntsen 13 May, 2011, 2:01

      Hey jD,

      I am sorry that comments on my blog currently malfunctions. I tried to find out what the error meant, and found some indications it could be recaptcha. I think recaptcha has changed API, so I regenerated for my domain, but the error persisted. So for now I have disabled the recaptcha – hope I will not be spammed too much, otherwise I will have to disable it again until I have time to solve the problem.

      About Model2Roo, I don’t think you can roundtrip back. I think more of it as a nice thing to have if you have an existing EMF model, or if you prefer to use the EMF tools to get an initial shot at your model.

      For my projects currently I have staid with just. roo. The quality (of documentation) for generated GWT from roo is too low though, so currently I am just hooking up smartGWT widgets directly to the database created by roo. For prototyping this seems like the good compromise between getting help from tools and getting things done without focusing energy on the tools beyond the point where they are helpful.

      I agree your error in the blog was very minor :) just wanted to help you by pointing it out.

      Btw. I have now successfuly applied your image upload to a prototype of mine — thanks a lot for sharing. I wonder whether it would be easy to wrap it into a roo extension, but that will have to wait to be consider for next time I need i.

      Cheers,
      /)/ikolaj

  • Lifang 3 June, 2011, 0:08

    hello really nice workk i was wondering if i could use this example for uploading documents only ? is it possible ?

  • jD 3 June, 2011, 13:10

    @Lifang,

    Yes… not a problem.

    Roogards

  • jD 3 June, 2011, 13:37

    @Lifang,

    As it is, the implementation shown could handle small to medium size docs…
    In other to handle really big size docs it would have to be modified a little bit to use the filesystem instead the database to store it.

    i believe this is a better answer to your question.

    Thx and B. Roogards again
    jD

    • Lifang 4 June, 2011, 1:31

      Thanks for your reply yes i will try to change it a bit but i don’t need for big files so I think it may be suitable .
      Lifang

  • Lifang 4 June, 2011, 22:27

    Hello i have followw all the guidelines i am having this error:
    No tag “multi” defined in tag library associated with uri “urn:jsptagdir:/WEB-INF/tags/form”
    this is due to the multi tag :S

    • Yiannis 5 July, 2011, 1:51

      You need to include them from the source code provided in this tutorial

  • Alex 6 June, 2011, 12:03

    Great tutorial but what about the option B?
    Could you tell me how to do it? cuz i got a database schema and add a field named “picture” in one table but when I did reverse engineering it added that field on the form but can’t upload any pic.

    Thanks in advance

    Alex

  • jD 7 June, 2011, 11:45

    Alex,

    Your picture field is just a blob a datatype referred in the article as content…
    Just follow along the code for this field and make the correspondent modifications for your case.

    Roogards
    jD

  • Phil 26 July, 2011, 14:52

    Hey, Thanks for the Tutorial,

    One Question, why use IOUtils.copy() in the DocumentController (thowing error by the way) instead of simply out.write(doc.getContent());?

    Thanks

    Phil

    out.write(doc.getContent());

    @RequestMapping(value = "/showdoc/{id}", method = RequestMethod.GET)
        public String showdoc(	@PathVariable("id") Long id,
        						HttpServletResponse response,
        						Model model) {
        	
        	Document doc = Document.findDocument(id);
        	
    
            try {
                response.setHeader("Content-Disposition", "inline;filename=\"" +doc.getFilename()+ "\"");
    
                OutputStream out = response.getOutputStream();
                response.setContentType(doc.getContentType());
    
                // IOUtils.copy( new ByteArrayInputStream(doc.getContent()) , out);
                out.write(doc.getContent());
                out.flush();
             
     
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
  • jD 27 July, 2011, 19:02

    @Phil,

    The main purpose of my tutorial is to contrast traditional Spring web development vs. Roo development. In order to that I used the referred “original” tutorial referred at the top.
    I hope I met my purpose.

    At the time of upgrading the tutorial for handling big blog is will include your point.

    Please visit my blog at http://pragmatikroo.blogspot.com. where you will find “probably” the largest collection of Roo articles available at this point.

    Feedback is always welcome

    Thank you and B. Roogards
    jD

  • iar 31 July, 2011, 3:20

    This is a great article. You mention the commons-io dependency error at the end. My problem is that when I add this dependency (copy directly into the pom.xml or add from STS GUI context menu), nothing happens.

    How can I get STS to download and enlist the new dependency with the existing ones?
    Thanks.

  • iar 31 July, 2011, 4:36

    I found it: in STS, the Project context menu | Maven | Update Dependencies.
    However, STS does not copy it to Tomcat, which uses the workspace location.

  • jD 1 August, 2011, 0:24

    @ian,

    Thank you for you comment about my article…
    Add the dependency straight into the pom,xml.

    B. Roogards
    jD

  • jD 1 August, 2011, 0:25

    I meant @iar,

    Thank you for you comment about my article…
    Add the dependency straight into the pom,xml.

    B. Roogards
    jD
    Your

  • isaac fisher 11 August, 2011, 19:51

    it solved my problem. thanks a lot.

    • jD 12 August, 2011, 16:25

      @isaac fisher,

      You are welcome a lot…

      Roogards
      jD

  • feng 17 October, 2011, 13:13

    Hi, Thanks for the Tutorial.
    I run it successfully. Here I have question about update Blob in DB by Spring Roo. You disable the update in above code. Bu I am interested in how to update Blob in DB by Spring Roo. DO you have any investigation on update?

    Feng

    • jD 18 October, 2011, 9:47

      Hello Feng,

      Give it a shoot… It should work. I would appreciate you try it and report you results..
      I have my hands full right now.

      Thank you and B. Roogards
      jD

  • Bob 21 December, 2011, 8:32

    Hello,
    I think “out.flush();” should be changed to “out.close();”. Or else, “java.net.SocketException: Connection reset by peer: socket write error” will occur.
    Thanks for your sharing. It works well.

    Bob

  • jD 21 December, 2011, 10:06

    @Bob,
    I’ll clean it up…

    Thank you for the fix.
    jD

  • Robert 16 January, 2012, 15:07

    Great tutorial. :)

    • jD 16 January, 2012, 19:43

      @Robert,

      Thank you very much!
      jD

  • padesig 31 January, 2012, 16:37

    Hello all,

    I have implemented this solution in a project, using ROO 1.2.0.RC1 and all seems working (I have noticed a —ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error— but write and read worked well, anyway); now I have done the migration from ROO 1.2.0.RC1 to ROO 1.2.0.RELEASE (the current General Available) and I have noticed that I cannot write to or read from database; please, let me know if there are solutions to this…. the error is always —ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error— created by at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:358)…

    • jD 31 January, 2012, 17:34

      Hello u,
      Change “out.flush();” to “out.close();”…

  • Neo 15 February, 2012, 10:43

    Thanks for the tutorial, it works like a charm, i actually dont need the multipart tag as it is supported by roo now.

    But when I tried to do the same in update, I got some hibernate execption. Anyone did this for update as well ?

    • jD 15 February, 2012, 17:27

      You are welcome…
      1) Please explain “dont need the multipart tag as it is supported by roo now.”
      2) What is the exception thrown?

      Roogards
      jD

  • Miro 15 February, 2012, 22:44

    Can you please describe how to update image? In your tutorial you disabled, but I would like to know how to do update of image. What extra needs to be done? Thanks

    • jD 16 February, 2012, 18:40

      It was left intentionally undone for the Reader to practice…
      I should not be hard to get it.

      B. Roogards
      jD

  • Claus Guttesen 18 February, 2012, 3:30

    Thank you for the example. First I couldn’t display the image. After some trying (and failing) the following change to the controller was all I needed. In your example model.attribute() Document.findDocument(id) was the second argument.

    This is on os x lion, roo 1.1.5, I have changed the class from Document to File:

    @RequestMapping(value = “/{id}”, method = RequestMethod.GET)
    public String show(@PathVariable(“id”) Long id, Model model) {
    File file = File.findFile(id);
    file.setUrl(“http://localhost:8080/gloppen/files/showfile/” + id);
    model.addAttribute(“file”, file);
    model.addAttribute(“itemId”, id);
    return “files/show”;
    }

    regards
    Claus

  • Vito Meuli 23 February, 2012, 17:37

    Many thanks Jose for sharing with us!
    I really appreciate your efforts for the Roo community.

    Just tryed it and it works like a charm.
    I’m still having problems with the iframe…I don’t know it so I’ll need to study it a little bit. (the HTML code after the is not rendered from the browser, even if it is in the page).

    Cheers,
    Vito Meuli

    • Vito Meuli 23 February, 2012, 17:39

      the comment is missing a word:
      (the HTML code after the _iframe_ is not rendered from the browser, even if it is in the page).

    • jD 23 February, 2012, 19:49

      Vito,
      I am glad my code is working and helping you…
      Try different browsers to isolate iframe issue mentioned.

      B. Roogards
      jD

      • Vito Meuli 24 February, 2012, 13:49

        The issue is the same on any browser (Firefox 10, Chrome 17, IE 9), but I built another tagx file with an img and a dojo LightBoxNano, which suits my needs better.
        So I didn’t study the iframe yet :-)
        For your information, the issue was that every HTML markup that follows the iframe wan not visible: nor the other fields of Document (I showed them after the url-iframe) and the footer neither.
        Maybe I messed things somehow – I cut and paste your code into a sample project, to better follow your tutorial.
        B.Roogards to you
        Vito

        • jD 24 February, 2012, 19:42

          Vito,
          I am glad you find the way to fix your issue… You now can move on…
          BTW, I didn’t have such issue at all.

          Thx
          jD

        • Serge 24 August, 2012, 1:56

          I had the same issue with the iframe not rendering my images.
          A workaround is to prefix the src attribute value with the application name
          in frame.tagx:

          A better solution is to prefix the value of the Transient variable url
          with the context path coming from the request:

          @RequestMapping(value = “/{id}”, method = RequestMethod.GET)
          public String show(@PathVariable(“id”) Long id, Model model, HttpServletRequest request) {
          Document doc = Document.findDocument(id);
          doc.setUrl(request.getContextPath() +”/documents/showdoc/”+id);

          Thanks Jose, great tutorial !

  • John 20 May, 2012, 7:38

    Thanks for your tutorial. I almost bring it work in my Spring Roo project. However, when I click create New Document link, I got the following error.
    SEVERE: Servlet.service() for servlet turbops threw exception
    org.xml.sax.SAXException: No tag “multi” defined in tag library associated with uri “urn:jsptagdir:/WEB-INF/tags/form”

    How I can fix it. Thanks.

  • Oliver 21 September, 2012, 9:16

    Hi jD, thanks very much for your work. This solution looks very promising, and similar to others I’ve seen, but when I try to upload a file I consistently get the error “The request sent by the client was syntactically incorrect ().” I’m using Roo 1.2.2-RELEASE. Enabling TRACE logging on Spring yields an exception:

    TRACE org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod – Error resolving argument [3] [type=org.springframework.web.multipart.MultipartFile]

    org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter ‘content’ is not present

    It maps to the controller method well, but it seems something is wrong with the content parameter. It seems to be working behind the scenes however, since the log produces:

    2012-09-21 13:14:24,602 [tomcat-http--46] DEBUG org.springframework.web.multipart.commons.CommonsMultipartResolver – Found multipart file [content] of size 13567 bytes with original filename [alpacca.jpg], stored at [C:\Programming\springsource\vfabric-tc-server-developer-2.7.1.RELEASE\spring-insight-instance\work\Catalina\localhost\upload-project\upload_5cc40fc_139e6c87815__7ffb_00000005.tmp]

    Do you have any idea what might be going on?

    • Oliver 21 September, 2012, 9:38

      I think it was something to do with the following filters I added from another tutorial. Removing them seems to fix it (however PostgreSQL complains about auto-commit, but that’s DBMS-specific).

      multipartFilter
      org.springframework.web.filter.DelegatingFilterProxy

      multipartFilter
      /*

  • Dhruv 31 October, 2012, 11:23

    hi jD,
    i am a noob to spring roo. then i found your great tutorial to help me in my learning. Nice job with Roo :)
    could you help me out with the error i am getting [similar to the many others :) ]?
    the error message states ” No tag “multi” defined in tag library associated with uri “urn:jsptagdir:/WEB-INF/tags/form” ”
    how do i go about this?
    really appreciate any help on this
    thanks and roogards
    Dhruv

  • Dhruv 31 October, 2012, 11:31

    Ooops found out that it was my mistake in not going through the source code properly
    thanks
    Dhruv

  • karen85 17 July, 2013, 18:05

    Hi, Thanks for the Tutorial.
    I run it successfully. Here I have question about update Blob in DB by Spring Roo. You disable the update in above code. Bu I am interested in how to update Blob in DB by Spring Roo. DO you have any investigation on update?

  • Mahesh 7 November, 2013, 13:09

    Hi Jose,

    Thanks for the excellent work u have made many life’s easy .
    I am interested in second approach the Reverse engineering approach can u guide me to achieve the same functionality of file upload and view
    can u please provide me the link to the doc

  • Jeff 11 November, 2013, 22:07

    Is this a typo in your roo creation script?

    field numbert –fieldName size -

  • Jeff thurston 13 November, 2013, 2:19

    You have a typo in your roo sample creation script.

    field numbert –fieldName size -

    I like where are going with but you do provide enough details for someone new to Spring Roo, file names that have to modified and their locations would be a bonus.

Leave a Reply

Your email address will not be published. Required fields are marked *

Note

To post source code in comment, use [code language] [/code] tag, for example:

  • [code java] Java source code here [/code]
  • [code html] HTML here [/code]