Thursday, 2 September 2010

Calling JSP directly

Calling a JSP directly, (from for example within another jsp) in order to redirect its input and output to, for example, a PDF writer, can be done using the following:

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

/**
 * Response wrapper, that creates its own readable buffer.
 * @author Turbo
 */

public class WebResponseWrapper extends HttpServletResponseWrapper 
{
    
    private StringWriter output;

    public WebResponseWrapper (HttpServletResponse response){
    super(response);
    output = new StringWriter();
    }

    public String getBufferContents()
    {
        return output.toString();
    }

    @Override
    public void flushBuffer() throws IOException {
    }
    
    @Override
    public PrintWriter getWriter() throws java.io.IOException
    {
        return new PrintWriter(output, true);
    }

    @Override
    public void reset() 
    {
    }

    @Override
    public void resetBuffer()
    {
    }

}
/**
 * Class that makes it possible to add some parameters to the existing
 * http request, useful for redirecting.
 */
 
class MyRequestHelper extends HttpServletRequestWrapper
{
    Map<String,String> theMap = null;
    
    public void set(String param, String value)
    {
        theMap.put(param, value);
    }
    
    public MyRequestHelper(HttpServletRequest request)                
    {
        super(request);
        theMap = new HashMap<String,String>();
    }
    
    @Override
    public String getParameter(String param)
    {
        if (theMap.containsKey(param))
        {
            return theMap.get(param);
        }
        return super.getParameter(param);
    }
}

Using these two classes, redirecting a jsp page becomes as simple as:

/* setup wrappers */
WebResponseWrapper resWrapper = new WebResponseWrapper(response);
RequestDispatcher rd = context.getRequestDispatcher("/some/jsp/thing/myJsp.jsp");
MyRequestHelper mrh = new MyRequestHelper(request);

/* change/add some parameters */
mrh.set("forEmail""true");
mrh.set("key", correctKey);
mrh.set("user", userName);

/* issue include to the requestdispatcher */
rd.include(mrh, resWrapper);

/* retrieve output */
String email = resWrapper.getBufferContents();

NullPointerException - Most Common Java Bug In Existence

Unless you are what is called "the Perfect Java Programmer", it is likely that you've perpetrated the NullPointerException at least once (and probably a lot more) in your life.

A lot of the time, I see code like the following:
if (propertyValue.equals("filename.txt"))
{
    // do stuff
}
When it should really be more like this:
if ("filename.txt".equals(propertyValue))
{
    // do stuff
}

Now, as you can see when you try this (with propertyValue = null;), a NullPointerException does not take place.

The reason is in the equals method. Contract states that x.equals(null) == false.

If you're new at Java, you might be rather surprised that something like "somestring".equals() works. Remember that Strings are immutable objects, and therefore there's really no reason not to try something like this.

With that said, let's try and find a common implementation for the equals method. Eclipse seems to do a pretty good job of it:

public class MyObject
{

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            // it is the same object
            return true;
        }
        if (obj == null)
        {
            // oh dear
            return false;
        }
        if (getClass() != obj.getClass())
        {
            // not the same class
            return false;
        }
        MyObject other = (myObject) obj;
        if (!this.field().equals(obj.field())
        {
            // (one of) the fields is not the same!
            return false;
        }
        // couldn't find any differences!
        return true;
    }

    @Override
    public int hashCode() 
    {
        return field();
    }

}
The link to http://community.jboss.org/wiki/EqualsandHashCode might be a good one.