Pinned topicFeature Focus Week: Servlet 3.0

‏2010-05-24T14:58:42Z
|Tags:

Answered question
This question has been answered.

Unanswered question
This question has not been answered yet.

There is a lot that is new and useful in Servlet 3.0. After a relatively minor update in Servlet 2.5, it is nice to see all the new features in Servlet 3.0 that will make development easier and make your applications more scalable. The following new features are currently available in the WebSphere Application Server 8.0 Alpha:

Annotations

@WebServlet, @WebFilter, and @WebListener will likely be the most often used of the new Servlet 3.0 annotations and they are supported in the Alpha. Instead of having to embed all of your configuration in the web.xml, you can use the annotations to declare your web components in your code. See an example of @WebServlet in the Asynchronous Servlets example.

Asynchronous Servlets

The simplest way to think of async servlets is to think of detaching a single request and response from the normal lifecycle of a single thread. You tell us when to complete the response. When the initial thread ends, your request, response, and the associated connection are still valid and open, but you're no longer consuming a webcontainer thread.

For example, if you have a bunch of clients that need to invoke an asynchronous EJB method, you may want to start a single worker thread to monitor the results of the Future objects returned from the method invocation. When you're done, you can dispatch to a Servlet or JSP to display the results or write directly to the response and call complete on the worker thread.

See the following outline for how this would work. (This is a representative example, not working code.)

@WebServlet (“/AsyncServletExample”)
public
class AsyncServletExample
extends HttpServlet
{ AsyncRunnable r =
new AsyncRunnable(); AtomicBoolean started =
new AtomicBoolean();
public
void service(HttpServletRequest request, HttpServletResponse response)
{
//Tell webcontainer not to close the response AsyncContext asyncContext = request.startAsync();
//Retrieve the future from EJB etc Future future = getFutureFromEJBMethodInvocation();
//Set the future on the request so it can be retrieved later request.setAttribute(“future”,future);
//Setup an object that contains everything the worker thread needs to know AsyncInfo asyncInfo =
new AsyncInfo(asyncContext, future);
//Add this object to a queue in the worker thread r.addAsyncInfo(asyncInfo);
//Startup the worker thread just once by utilizing an AtomicBoolean that can tell us if its started already. Every request will add to a single worker thread
if (!(this.started.getAndSet(
true)))
{
new Thread(r,
"AsyncServletWorkerThread").start();
}
}
}
//The runnable executing on the worker thread
public
class AsyncRunnable
implements Runnable
{ BlockingQueue<AsyncInfo> asyncInfoQueue =
new LinkedBlockingQueue();
public
void addAsyncInfo(AsyncInfo asyncInfo)
{ asyncInfoQueue.put(asyncInfo);
}
public
void run()
{
while (
true)
{
//get the next item on the queue AsyncInfo asyncInfo = (AsyncInfo)asyncInfoQueue.take(); Future future = asyncInfo.getFuture();
if (future.isDone())
//Dispatch to display the results if its done asyncInfo.getAsyncContext().dispatch(
"/DisplayResults");
else
//put the item back on the queue if its not done asyncInfoQueue.put(asyncInfo);
}
} @WebServlet (“/DisplayResults”)
public
class DisplayResults
extends HttpServlet
{
public
void service(HttpServletRequest request, HttpServletResponse response)
{ Future future = (Future)request.getAttribute(
"future"); response.getWriter().println(future.get());
}
}

Web Fragments

In addition to annotations, web fragments provide the ability to embed your configuration metadata in jar files that can be reused and copied across web modules. This is particularly useful for framework providers so that consumers of those frameworks don't have to define various controller servlets or content filters in their web.xml. Instead, everything is automatically configured when you drop in your framework jar.

All you have to do is create a web-fragment.xml file in the META-INF directory of a jar and drop the jar in the WEB-INF/lib of your web module. The format is essentially the same as the web.xml besides the different beginning and ending tags.

Programmatic Configuration

There are many new methods for programmatically adding servlets, filters, and listeners to an application. This can be done in the contextInitialized method of a ServletContextListener. See the Servlet 3.0 javadocs for the ServletContext interface for more details.

File upload/Multipart Config

Support has been added to the ServletRequest API to allow retrieval of parts for multipart form data. The following example writes out a file to the javax.servlet.context.tempdir directory.

Enjoy trying out these new features. We would love to have your feedback.

There is a lot that is new and useful in Servlet 3.0. After a relatively minor update in Servlet 2.5, it is nice to see all the new features in Servlet 3.0 that will make development easier and make your applications more scalable. The following new features are currently available in the WebSphere Application Server 8.0 Alpha:

Annotations

@WebServlet, @WebFilter, and @WebListener will likely be the most often used of the new Servlet 3.0 annotations and they are supported in the Alpha. Instead of having to embed all of your configuration in the web.xml, you can use the annotations to declare your web components in your code. See an example of @WebServlet in the Asynchronous Servlets example.

Asynchronous Servlets

The simplest way to think of async servlets is to think of detaching a single request and response from the normal lifecycle of a single thread. You tell us when to complete the response. When the initial thread ends, your request, response, and the associated connection are still valid and open, but you're no longer consuming a webcontainer thread.

For example, if you have a bunch of clients that need to invoke an asynchronous EJB method, you may want to start a single worker thread to monitor the results of the Future objects returned from the method invocation. When you're done, you can dispatch to a Servlet or JSP to display the results or write directly to the response and call complete on the worker thread.

See the following outline for how this would work. (This is a representative example, not working code.)
<pre class="jive-pre">
@WebServlet (“/AsyncServletExample”)
public
class AsyncServletExample
extends HttpServlet
{ AsyncRunnable r =
new AsyncRunnable(); AtomicBoolean started =
new AtomicBoolean();
public
void service(HttpServletRequest request, HttpServletResponse response)
{
//Tell webcontainer not to close the response AsyncContext asyncContext = request.startAsync();
//Retrieve the future from EJB etc Future future = getFutureFromEJBMethodInvocation();
//Set the future on the request so it can be retrieved later request.setAttribute(“future”,future);
//Setup an object that contains everything the worker thread needs to know AsyncInfo asyncInfo =
new AsyncInfo(asyncContext, future);
//Add this object to a queue in the worker thread r.addAsyncInfo(asyncInfo);
//Startup the worker thread just once by utilizing an AtomicBoolean that can tell us if its started already. Every request will add to a single worker thread
if (!(this.started.getAndSet(
true)))
{
new Thread(r,
"AsyncServletWorkerThread").start();
}
}
}
//The runnable executing on the worker thread
public
class AsyncRunnable
implements Runnable
{ BlockingQueue<AsyncInfo> asyncInfoQueue =
new LinkedBlockingQueue();
public
void addAsyncInfo(AsyncInfo asyncInfo)
{ asyncInfoQueue.put(asyncInfo);
}
public
void run()
{
while (
true)
{
//get the next item on the queue AsyncInfo asyncInfo = (AsyncInfo)asyncInfoQueue.take(); Future future = asyncInfo.getFuture();
if (future.isDone())
//Dispatch to display the results if its done asyncInfo.getAsyncContext().dispatch(
"/DisplayResults");
else
//put the item back on the queue if its not done asyncInfoQueue.put(asyncInfo);
}
} @WebServlet (“/DisplayResults”)
public
class DisplayResults
extends HttpServlet
{
public
void service(HttpServletRequest request, HttpServletResponse response)
{ Future future = (Future)request.getAttribute(
"future"); response.getWriter().println(future.get());
}
}
</pre>

Web Fragments

In addition to annotations, web fragments provide the ability to embed your configuration metadata in jar files that can be reused and copied across web modules. This is particularly useful for framework providers so that consumers of those frameworks don't have to define various controller servlets or content filters in their web.xml. Instead, everything is automatically configured when you drop in your framework jar.

All you have to do is create a web-fragment.xml file in the META-INF directory of a jar and drop the jar in the WEB-INF/lib of your web module. The format is essentially the same as the web.xml besides the different beginning and ending tags.

Programmatic Configuration

There are many new methods for programmatically adding servlets, filters, and listeners to an application. This can be done in the contextInitialized method of a ServletContextListener. See the Servlet 3.0 javadocs for the ServletContext interface for more details.

File upload/Multipart Config

Support has been added to the ServletRequest API to allow retrieval of parts for multipart form data. The following example writes out a file to the javax.servlet.context.tempdir directory.