Showing posts with label JSP/Servlet. Show all posts
Showing posts with label JSP/Servlet. Show all posts

Wednesday, October 1, 2008

Spawn a Thread in a Servlet

When I search this topic on Google, the first impression is that, 'Stop! Just Don't Do It'. Threading code is error prone, not mentioning in a managed container. Additionally there are alternatives like Message Driven Beans or Java Message System, which are specially designed for this purpose. However, you may have a specific situation where threading in Servlet seems to be the only viable solution, for example the JSP page kicks off a long running process at the backend. What can you do? Fortunately it's totally doable if you are careful enough.

First, let's evaluate the risks. Obviously if your servlet is going to spawn multiple threads, this servlet cannot serve many concurrent users at the same time. Otherwise the thread pool will easily dry up and brings the server down to its knees. Concurrent access may cause race conditions and subtle synchronization problems too, especially in a load-balanced or clustered environment. Thread leak may be another risk. If not cleaned up appropriately, each leaked thread will have a reference to its classloader and prevent this classloader from being garbage collected. After enough reload of the application, you may run into out of PermGen space memory errors.

If the risks mentioned above do not apply to your particular situation or didn't scare you off, let's continue. The solution is as the following:
1. Instantiate your thread object as a daemon in your Servlet or ServletContextListener and call yourThread.start();
2. Store it as an attribute in your application context;
3. Return the HttpServletResponse;
4. Clean up the thread when the servlet or the application context is destroyed
5. Don't pass HttpservletRequest/Response/Session objects to the thread

Tuesday, August 12, 2008

Tag Libraries: JSTL, NetUI, Spring MVC, or Struts Tag Library

Not occasionally JSP developers need to iterate through collections and evaluate conditions before presenting the data. Tag libraries come in handy to provide a solution. However, there are quite a few Tag Libraries available, for example, the JSTL, NetUI, Spring MVC, and Struts tag libraries. Which one to choose? The quick answer is to use JSTL whenever possible. Use other tag libraries only when absolutely necessary.

Tag Libraries are not much different than any other utility libraries. Different vendors provide different features. JavaServer Pages Standard Tag Library (JSTL) is the most-accepted one and still powerful enough for common usages. If a non-standard tag library is chosen for additional features and convenience, other developers may have to climb a learning curve before being productive.

Additionally JSTL is designed to complement the HTML tags with 'logic control'
capabilities. This is in contrast to NetUI tag libraries, who replaces the HTML tags. Another example is Spring MVC's tag library. It is tightly integrated ONLY with the Spring MVC framework for convenient data binding. Tag libraries competing with HTML tags may create further compatibility issues. Sometimes JSP pages are touched by both developers and UI design artists. The UI design artists do not want to see any specialized tags by all means. Struts Tag Library used to gain a lot of popularity due to the success of the legend Struts framework. Now its document website has comments like, 'Some of the features in this taglib are also available in the JavaServer Pages Standard Tag Library (JSTL). The Struts team encourages the use of the standard tags over the Struts specific tags when possible.'

In a conclusion, JSTL tag library is the standard way to provides common logic processing features, such as to iterate through collections and to evaluate conditions. It complements the HTML tags. It will be the best choice for most common situations. Alternative ones, like NetUI, Spring MVC, or Struts Tag Library, may be chosen for additional functionalities.

Wednesday, August 6, 2008

Alternative Ways to Define JSP/Servlet Attribute Scopes

As we know, there are four types of scopes that a JSP/Servlet attribute can use:
Application: The attribute lasts the lifetime of an application instance.
Session: The attribute survives throughout the conversation session.
Request: The attribute will be discarded after the request is serviced.
Page: The attribute is only visible within a particular JSP page.

To keep data integrity, it's important to put attributes into the right scope. Most of the time developers will retrieve attributes from requests and put them into appropriate scopes thereafter. There are alternative ways.

1. Set application scope attributes in a ServletContextListener.
Sometimes "static" information should be loaded once and visible throughout the lifetime of an application. For example,

web.xml
<listener>
<listener-class>
com.denistek.SampleListener
</listener-class>
</listener>

Java
public class SampleListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
//... get your attributes
event.getServletContext().setAttribute("attributes", attributes);
}

@Override
public void contextDestroyed(ServletContextEvent event) {
}
}

2. Set application scope attributes in a Servlet with <load-on-startup> features.
This is very similar to the above approach. For example,

web.xml
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>com.denistek.servlet.SampleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

Java
@Override
public void init() throws ServletException {
super.init();
//... get your attributes
getServletContext().setAttribute("attributes", attributes);
}


3. Use filters to define session attributes.
Sometimes there are multiple entry points where a session attribute can be updated. In this case we'd better use a filter to watch for this kind of update instead of scattering the logic across various JSP's/Servlets. For example,

web.xml
<filter>
<filter-name>SampleFilter</filter-name>
<filter-class>com.denistek.SampleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SampleFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Java
public class SampleFilter implements Filter {

private SampleAttribute[] attributes = null;

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException{
HttpServletRequest rq = (HttpServletRequest) request;
//... populate attributes from request here
rq.getSession().setAttribute("sampleAttributes", attributes);
chain.doFilter(request, response);
}

@Override
public void init(FilterConfig config) {
//... populate attributes from context here
attributes = config.getServletContext().getAttribute("sampleAttributes");
}

@Override
public void destroy() {
}
}