Hiding Conversation Id in Cookie
mocha May 29, 2009 4:20 PMcid appended to urls are screwing with my application's beauty, particularly during login redirect which is the first page that new users hit (and therefore bookmark).
So I've come up with a possible solution which is to strip and store the cid in a cookie over a redirect. Seems to work, but would be interested in feedback on the approach and if there is a better place to handle the coding of this. I couldn't see an easy place to deal with this in the seam framework, hence the filter approach.
Worth pointing out that I have already disabled url based session identifiers for my app, so users can only login and use the system if they have cookies enabled.
@Startup @Scope(ScopeType.APPLICATION) @Name("hideSeamCidFilter") @BypassInterceptors @Filter @Install(value = false, precedence = Install.APPLICATION) public class HideSeamCidFilter extends AbstractFilter { private class ParamHttpServletRequestWrapper extends HttpServletRequestWrapper { Map<String, String[]> params = new HashMap<String, String[]>(); ParamHttpServletRequestWrapper(HttpServletRequest request) { super(request); } ParamHttpServletRequestWrapper(HttpServletRequest request, Map<String, String> overrideParams) { super(request); params.putAll(request.getParameterMap()); for (Map.Entry<String, String> param:overrideParams.entrySet()) { if (param.getValue()==null) { params.put(param.getKey(), null); } else { String values[] = {param.getValue()}; params.put(param.getKey(), values); } } } @Override public String getParameter(String name) { String[] value = params.get(name); return (value==null || value.length == 0) ? null : value[0]; } @Override public Map getParameterMap() { return params; } @Override public Enumeration getParameterNames() { return Collections.enumeration(params.keySet()); } @Override public String[] getParameterValues(String name) { return params.get(name); } } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { chain.doFilter(request, response); return; } HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // check for conversation id stored in cookie String cid = null; if (httpRequest.getCookies() != null) { for (Cookie cookie:httpRequest.getCookies()) { if ("cid".equals(cookie.getName())) { cid = cookie.getValue(); // now that we've got the cid we can clear it out of cookie - i.e. it's only valid for this request cookie.setMaxAge(0); httpResponse.addCookie(cookie); break; } } } // if found, add conversationid to url parameters passed down to seam HashMap params = new HashMap(); if (cid != null) { params.put("cid", cid); } HttpServletRequestWrapper wrappedRequest = new ParamHttpServletRequestWrapper(httpRequest, params); // override redirect requests from processing further down the line so that // conversation id can be stripped off redirect requests and stored in cookie HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse) { public void sendRedirect(String url) throws IOException { if (url.indexOf("cid=") > 0) { // grab the cid String cid = null; int cidParamIndex = url.indexOf("cid="); int nextParamIndex = url.indexOf("&", cidParamIndex); if (nextParamIndex > 0) { cid = url.substring(cidParamIndex+4, nextParamIndex); // remove cid param leaving ? or & in place for next param url = url.substring(0,cidParamIndex) + url.substring(nextParamIndex+1); } else { cid = url.substring(cidParamIndex+4, url.length()); url = url.substring(0,cidParamIndex-1); } // add cid to cookie Cookie cidCookie = new Cookie("cid", cid); this.addCookie(cidCookie); } super.sendRedirect(url); } }; chain.doFilter(wrappedRequest, wrappedResponse); } }