Introduction
I am faced with a problem currently where I have an application that was written before the J2EE specification was written. The application has its own application server, session, and state management. I am in the process of modernizing this application and transforming it into a standard Java EE application. However, there is a lot of code over 1.5m LOC. That makes this process very intensive.One of the issues I have been wrestling with is session management. As I previously noted, the application has its own session and state management mechanisms. The session object is not too vastly different from a standard
HttpSession
object. This has given rise to an idea that I could wrap a standard HttpSession
object with a decorator similar to HttpServletRequestWrapper
and perhaps a implementation of the old session mechanism.Currently there is no HttpSessionWrapper like
HttpServletRequestWrapper
, or HttpServletResponseWrapper
so I wrote my own. It was simple to do and I hope others who may need a HttpSessionWrapper will use it. Once I wrote the wrapper, implementing it was the harder part.Implementation
Implementation requires a little knowledge of how HTTP requests are handled by servlets, and request and response handling in general. The most important thing to remember is: theHttpSession
is created from the HttpServletRequest
object. This important fact can help determine how to implement our HttpSessionWrapper. I think that the easiest mechanism is to use an HttpServletRequestWrapper
in a @WebFilter
. Filters are the first items that a request will pass through to reach the servlet, and the last thing it will pass through in the response.If you use this mechanism, for implementing your HttpSessionWrapper, you must ensure that this is the first filter that the request will pass through. If it is the only filter, that should be very easy to implement. If you are using multiple filters with annotations, you will need to use a
web.xml
file to place them in the order you want them applied.The example code I have below takes advantage of the fact that I can use a filter and that once I pass in my
HttpServletRequestWrapper
with its modified getSession()
methods that return my HttpSessionWrapper. The HttpSessionWrapper can be downloaded here: session-wrapperCode
The code below includes theHttpSessionWrapper
and an example implementation of how to use it.
HttpSessionWrapper.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | package com.bluelotussoftware.session; import java.util.Enumeration; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionContext; /** * A Wrapper (decorator) for the {@link HttpSession} object. * * @author John Yeary * @version 1.0 */ public class HttpSessionWrapper implements HttpSession { private HttpSession session; /** * Constructor that takes an {@link HttpSession} object to wrap. * * @param session */ public HttpSessionWrapper(HttpSession session) { this .session = session; } /** * {@inheritDoc} */ @Override public long getCreationTime() { return session.getCreationTime(); } /** * {@inheritDoc} */ @Override public String getId() { return session.getId(); } /** * {@inheritDoc} */ @Override public long getLastAccessedTime() { return session.getLastAccessedTime(); } /** * {@inheritDoc} */ @Override public ServletContext getServletContext() { return session.getServletContext(); } /** * {@inheritDoc} */ @Override public void setMaxInactiveInterval( int interval) { session.setMaxInactiveInterval(interval); } /** * {@inheritDoc} */ @Override public int getMaxInactiveInterval() { return session.getMaxInactiveInterval(); } /** * {@inheritDoc} */ @Override public HttpSessionContext getSessionContext() { return session.getSessionContext(); } /** * {@inheritDoc} */ @Override public Object getAttribute(String name) { return session.getAttribute(name); } /** * {@inheritDoc} */ @Override public Object getValue(String name) { return session.getValue(name); } /** * {@inheritDoc} */ @Override public Enumeration<string> getAttributeNames() { return session.getAttributeNames(); } /** * {@inheritDoc} */ @Override public String[] getValueNames() { return session.getValueNames(); } /** * {@inheritDoc} */ @Override public void setAttribute(String name, Object value) { session.setAttribute(name, value); } /** * {@inheritDoc} */ @Override public void putValue(String name, Object value) { session.putValue(name, value); } /** * {@inheritDoc} */ @Override public void removeAttribute(String name) { session.removeAttribute(name); } /** * {@inheritDoc} */ @Override public void removeValue(String name) { session.removeValue(name); } /** * {@inheritDoc} */ @Override public void invalidate() { session.invalidate(); } /** * {@inheritDoc} */ @Override public boolean isNew() { return session.isNew(); } } |
HttpSessionWrapperImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | package com.bluelotussoftware.session.impl; import com.bluelotussoftware.session.HttpSessionWrapper; import java.util.Collections; import java.util.Enumeration; import java.util.List; import javax.servlet.http.HttpSession; /** * * @author John Yeary * @version 1.0 */ public class HttpSessionWrapperImpl extends HttpSessionWrapper { public static final String INFO = "HttpSessionWrapperImpl/1.0" ; public HttpSessionWrapperImpl(HttpSession session) { super (session); } public List<string> getAttributesNames() { Enumeration<string> names = getAttributeNames(); return Collections.list(names); } } |
HttpServletRequestWrapperImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package com.bluelotussoftware.session.impl; import com.bluelotussoftware.session.HttpSessionWrapper; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpSession; /** * * @author John Yeary * @version 1.0 */ public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper { public HttpServletRequestWrapperImpl(HttpServletRequest request) { super (request); } /** * {@inheritDoc}<p> This method will return an instance of * {@link HttpSessionWrapper}</p> */ @Override public HttpSession getSession() { return getSession( true ); } /** * {@inheritDoc} <p> This method will return an instance of * {@link HttpSessionWrapper}</p> */ @Override public HttpSession getSession( boolean create) { HttpSession session = super .getSession(create); if (session != null ) { return new HttpSessionWrapperImpl(session); } else { return session; } } } |
WrappingFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | package com.bluelotussoftware.example; import com.bluelotussoftware.session.HttpSessionWrapper; import com.bluelotussoftware.session.impl.HttpServletRequestWrapperImpl; import java.io.IOException; import javax.servlet.DispatcherType; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * {@link Filter} used for wrapping the {@link HttpServletRequest} with an * implementation of the {@link HttpServletRequestWrapper} that provides a * custom {@link HttpSessionWrapper}. * * @author John Yeary * @version 1.0 */ @WebFilter (filterName = "WrappingFilter" , urlPatterns = { "/*" }, dispatcherTypes = { DispatcherType.FORWARD, DispatcherType.ERROR, DispatcherType.REQUEST, DispatcherType.INCLUDE }) public class WrappingFilter implements Filter { /** * Default Constructor */ public WrappingFilter() { } /** * {@inheritDoc} */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest hsr = (HttpServletRequest) request; HttpServletRequestWrapperImpl hsrwi = new HttpServletRequestWrapperImpl(hsr); chain.doFilter(hsrwi, response); } /** * {@inheritDoc} */ @Override public void destroy() { //NO-OP } /** * {@inheritDoc} */ @Override public void init(FilterConfig filterConfig) { //NO-OP } } |
Conclusion
Implementing aHttpSessionWrapper
can be done very easily with a little thought, and perhaps a good blog article on it.
The session-wrapper and session-wrapper-example code is available on BitBucket as Mercurial projects.. The projects were developed using NetBeans 7.2.1 and Apache Maven and was tested using Glassfish 3.1.2.
0 comments :
Post a Comment