Sign in

E-mail *, (xx@domain.com)
Password *

Register | Forgot password

Blogs

  • Bram de Kruijff
  • Ivo Ladage
  • Mark van Cuijk
  • Martin van Mierloo
  • Martijn van Berkum
  • Michel Teunissen
  • Patrick Atoon

Recent blogs

RSS - Blogs
March 9, 2010
State of OSGi in the Java world
March 4, 2010
Reach more people with Google Translate
March 3, 2010
Get My Advice
February 26, 2010
What? Where!?!
February 11, 2010
Split it!

All Blogs...


5 Spring pittfalls - Answer issue 1

January 13, 2009

Originally, I planned to post all the 5 answers at the same time. But while writing the answer to the first issue, I figured this would become a very long post. And so I'll discuss only one issue at a time, starting with Fuzzy issue 1. Let's first recap the issue;

Fuzzy issue 1

Take a look at the following code snippet in the Form Backing Object of your panel. The Form Backing Object implements a toString(), just for logging purposes. That cannot possibly be wrong, can it?

public class MyFBO implements FormBackingObject {
  ...
  public String toString() {
    String bla = "";
      for (int i=0; i<5000; i++) {
        bla += "bla";
      }
    return bla;
  }
}

Question: what will happen here?

A. This large String somehow suddenly appears in the generated HTML of the panel.

B. An Exception is displayed in the Tomcat console and the panel doesn't open at all.

C. Initially the panel seems to works fine but after submitting once you get a blank page. No errors visible in Tomcat. The panel seems to have died.

The answer

Well, the answer to this question is B. Your panel will be broken and this error appears in the Tomcat console:

  java.lang.ArrayIndexOutOfBoundsException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.coyote.http11.InternalOutputBuffer.write(InternalOutputBuffer.java:689)
    ...
But why is that? To answer that one, we first have to explain some Spring theory. The key to the answer is the "POST and REDIRECT" pattern, used by WebManager.

The POST and REDIRECT pattern

The POST and REDIRECT pattern is about separation of handling updates versus building the view. When you open a panel, there are no updates to perform. The only thing that needs to be done is building the view; the HTML that makes up the panel. To open the panel a GET request is send to the Spring controller and the querystring of the URL contains information about the panel to open.
But when the user for example presses the 'create entity' button in the panel, we actually have to perform some updates to the underlying datamodel. We will have to perform the update based on what the user entered in the HTML form that was submitted. The form for example may contain the name of the new entity to be created. In this case a POST request is send containing all entered form values by the user.
However, besides handling this update action also the view of the panel has to be build up again, probably showing the newly created entity. The POST and REDIRECT pattern is about separation of these two concerns. The separation is done this way:

POST
If a POST request is send to a Spring controller, Spring will bind the values entered in the form to your Form Backing Object. So it will invoke the bind methods like onBind() and onBindAndValidate(). Finally, it invokes onSubmit(). In the onSubmit() you are supposed to handle the datamodel updates. The result of the onSubmit() method is a ModelAndView. And there is the trick; the view returned by the onSubmit() method is actually a redirect (302). The redirect now points to a URL that is very similar to the URL to open the panel and results in a GET request. The only difference is that it may contain some additional parameters in the query string.

GET

If a GET request is send to a Spring controller, Spring will NOT bind the values entered in the form to your Form Backing Object. It doesn't need to, there are no posted form values to handle. Instead it will directly invoke showForm() which in his turn invokes referenceData(). The showForm() returns the final view that builds up the panel.

Back to the issue

Now that we understand the POST and REDIRECT pattern, we can explain what happens here. The problem is caused when Spring builds up the redirect view. Note that the onSubmit() returns a ModelAndView object. The view will be a RedirectView, the model may contain all kind of information. You can put whatever you want onto the model. One of the stuff that is put on the model by default is the Form Backing Object. Spring figures that any values put on the model might also be relevant when building up the view after the redirect. So if you put a 'pageid' onto the model in the onSubmit(), you may need this value later on in the showForm(). The only way to do this is by appending the model values to the query string (the redirect will result in a GET request). So Spring loops over all values put on the model, performs a toString() and appends '&key=value.toString()' to the query string of the redirect URL. This is what causes the issue; it tries to pass the Form Backing Object by appending "&command=" + fbo.toString() to the query string of the redirect URL. When the toString() of the FBO is too large, the length of the URL exceeds the limits of the browser, your webserver or Tomcat causing the exception and the broken panel.

Conclusion

You might think the example is a little bit 'seeking for problems' but it really isn't. The problem comes from the field in a case that the toString() was used to generate an XML representation of something 'quite large'. In fact, the issue is always there but as long as you don't exceed the URL limit you probably won't even notice it. But now that you know this issue exists, take a good look at the URL in the address bar of your browser and see what happens after submitting your own custom panel. Notice that this 'weird' parameter is appended:

%40f9caf2&org.springframework.validation.BindingResult.command=org.springframework.validation.BeanPropertyBindingResult%3A+0+errors

The explanation is easy now; the binding result is put onto the model in the onSubmit()!


About the Author

Return to all blogs

Ivo Ladage

Ivo Ladage is product architect and is part of one of the SCRUM-teams. Ivo has special interests in Workflow and Authorization processes and Spring MVC.

Read all Ivo's blog entries

Other blog entries:

May 7, 2009
5 Spring pittfalls - Answer issue 3
May 7, 2009
5 Spring pittfalls - Answer issue 2
January 24, 2009
9.7: Pimped archetypes!
December 9, 2008
5 Spring pitfalls
October 22, 2008
New certification process
August 3, 2008
WebManager extensions
May 27, 2008
GX WebManager on SpringSource Application Platform
March 25, 2008
The day of the easter egg
March 19, 2008
Why Spring?
March 7, 2008
On the implementation of RBAC for Workflow and Authorization


Share:

del.icio.us
digg
Technorati
Slashdot
Reddit
YahooMyWeb
NewsVine
ekudos
© 2010 GX creative online development B.V.

Disclaimer

This website (GXdeveloperweb.com) may discuss or contain opinions, (sample) coding, software or other information that does not include GX official interfaces, instructions or guidelines and therefore is not supported by GX. Changes made based on this information are not supported.  GX will not be held liable for any damages caused by using or misusing the information, software, instructions, code or methods suggested on this website, and anyone using these methods does so at his/her own risk. GX offers no guarantees and assumes no responsibility or liability of any type with respect to the content of this website, including any liability resulting from incompatibility between the content of this website and the materials and services offered by GX. By using this website you will not hold, or seek to hold, GX responsible or liable with respect to the content of this website.