Page 3 of 7
The first two statements in Listing 2 enable JSP beans -- from different pages, but within the same HTTP session -- to communicate
with each other. Basically, each JSP will have two JavaBeans associated with it: a specific JSP JavaBean (for example, LoginJSPBean) and the common SharedSessionBean. Thus the SharedSessionBean is used as a common element to link all the pages; I'll explain it later in the article.
The next three statements from includeheader.jsp deal with implicit Servlet objects.
<% _abstractJSPBean.setRequest(request); %> <% _abstractJSPBean.setResponse(response); %> <% _abstractJSPBean.setServlet(this); %>
The JSP specification provides access to implicit objects that are part of the Java Servlet specification. Such objects as
request, response, and servlet are very often useful for page processing. Therefore they are passed to the JSP bean.
<% _abstractJSPBean.process(); %>
Finally, above is the statement that triggers the processing associated with the JSP page. As you can see, you are invoking
the method from the abstract JSP bean, not from the concrete LoginJSPBean. Why? I'll explain in the next section.
AbstractJSPBean is the main participant in the Template Method design pattern. Each concrete JSP JavaBean must extend that class.
Listing 3. AbstractJSPBean.java
package lbm.jsputil;
import java.util.*;
import javax.servlet.http.*;
import javax.servlet.*;
public abstract class AbstractJSPBean {
/* constants used for _state */
public static final int NEW = 0;
public static final int FIRSTPASS = 1;
public static final int PROC = 2;
public static final int ERR = -1;
private int _state; // current state
private String _errorMsg; // current message that is being appended during validation
private boolean _skipPageOutput; // should the page output be skipped
private SharedSessionBean _sharedSessionBean; // used for associating the JSP Bean with the HTTP Session
/* standard Servlet objects that need to be setup for each JSP Bean */
protected HttpServletRequest _request;
protected HttpServletResponse _response;
protected Servlet _servlet;
public AbstractJSPBean () {
setState(NEW);
}
protected abstract void beanProcess() throws java.io.IOException;
protected abstract void beanFirstPassProcess() throws java.io.IOException;
protected abstract void beanFooterProcess() throws java.io.IOException;
protected abstract String getJSPCode();
public void process() throws java.io.IOException {
setSkipPageOutput(false); // by default do not skip page output. Specific bean process
// methods can override it.
if (getState() == NEW) {
setState(FIRSTPASS);
beanFirstPassProcess();
} else {
resetErrorMsg();
setState(PROC);
beanProcess();
}
// validation that all common fields have been properly set by the application
// this is actually checking that the code has been written properly
String l_err = "";
if (_sharedSessionBean == null) l_err = l_err + "; SharedSessionBean must be set";
if (_request == null) l_err = l_err + "; Request must be set";
if (_response == null) l_err = l_err + "; Response must be set";
if (_servlet == null) l_err = l_err + "; Servlet must be set";
if ( ! l_err.equals("")) throw new IllegalStateException(l_err);
}
public void footerProcess() throws java.io.IOException {
beanFooterProcess();
}
protected void addErrorMsg (String addErrorMsg) {
if (_errorMsg == null) _errorMsg = addErrorMsg;
else _errorMsg = _errorMsg + " <br>\n" + addErrorMsg;
setState(ERR);
}
protected void resetErrorMsg () {
_errorMsg = null;
}
public String getErrorMsg () {
if (_errorMsg == null) return "";
else return _errorMsg;
}
protected void setState (int newState) {
_state = newState;
}
public int getState () {
return _state;
}
public void setSharedSessionBean (SharedSessionBean newSharedSessionBean) {
if (_sharedSessionBean == null) {
_sharedSessionBean = newSharedSessionBean;
_sharedSessionBean.putJSPBean(getJSPCode(), this);
} else {
if (_sharedSessionBean != newSharedSessionBean) {
throw new IllegalStateException("SharedSessionBean is not set properly. SharedSessionBean must be the same for all PageBeans within the session");
}
}
}
public SharedSessionBean getSharedSessionBean () {
return _sharedSessionBean;
}
public void setSkipPageOutput (boolean newSipPageOutput) {
_skipPageOutput = newSipPageOutput;
}
public boolean getSkipPageOutput () {
return _skipPageOutput;
}
protected void redirect (String redirectURL) throws java.io.IOException {
// skip the page output since we are redirecting
setSkipPageOutput(true);
_response.sendRedirect(redirectURL);
}
public void setRequest (HttpServletRequest newRequest) {
_request = newRequest;
}
public void setResponse (HttpServletResponse newResponse) {
_response = newResponse;
}
public void setServlet (Servlet newServlet) {
_servlet = newServlet;
}
}
The AbstractJSPBean contains the following abstract methods: beanFirstPassProcess(), beanProcess(), and beanFooterProcess(). Those methods are called the primitive methods. They are the stubs that you must implement in the concrete JSP JavaBeans subclasses. Each one is executed during
a particular phase of JSP processing.