1 16 17 package org.springframework.web.context.request; 18 19 import java.io.Serializable ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 24 import javax.servlet.http.HttpServletRequest ; 25 import javax.servlet.http.HttpSession ; 26 import javax.servlet.http.HttpSessionBindingEvent ; 27 import javax.servlet.http.HttpSessionBindingListener ; 28 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 32 import org.springframework.util.Assert; 33 import org.springframework.util.ClassUtils; 34 import org.springframework.web.util.WebUtils; 35 36 46 public class ServletRequestAttributes extends AbstractRequestAttributes { 47 48 52 public static final String DESTRUCTION_CALLBACK_NAME_PREFIX = 53 ServletRequestAttributes.class.getName() + ".DESTRUCTION_CALLBACK."; 54 55 private static final Log logger = LogFactory.getLog(ServletRequestAttributes.class); 57 58 private final static boolean bindingListenerAvailable = 60 ClassUtils.isPresent( 61 "javax.servlet.http.HttpSessionBindingListener", ServletRequestAttributes.class.getClassLoader()); 62 63 64 private final HttpServletRequest request; 65 66 private HttpSession session; 67 68 private final Map sessionAttributesToUpdate = new HashMap (); 69 70 71 75 public ServletRequestAttributes(HttpServletRequest request) { 76 Assert.notNull(request, "Request must not be null"); 77 this.request = request; 78 this.session = request.getSession(false); 81 } 82 83 84 87 protected final HttpServletRequest getRequest() { 88 return this.request; 89 } 90 91 95 protected final HttpSession getSession(boolean allowCreate) { 96 try { 97 this.session = this.request.getSession(allowCreate); 98 return this.session; 99 } 100 catch (IllegalStateException ex) { 101 if (this.session == null) { 103 throw ex; 105 } 106 if (allowCreate) { 109 boolean canAskForExistingSession = false; 110 try { 111 this.session = this.request.getSession(false); 112 canAskForExistingSession = true; 113 } 114 catch (IllegalStateException ex2) { 115 } 116 if (canAskForExistingSession) { 117 throw ex; 120 } 121 } 122 return this.session; 126 } 127 } 128 129 130 public Object getAttribute(String name, int scope) { 131 if (scope == SCOPE_REQUEST) { 132 return this.request.getAttribute(name); 133 } 134 else { 135 HttpSession session = getSession(false); 136 if (session != null) { 137 Object value = session.getAttribute(name); 138 if (value != null) { 139 this.sessionAttributesToUpdate.put(name, value); 140 } 141 return value; 142 } 143 else { 144 return null; 145 } 146 } 147 } 148 149 public void setAttribute(String name, Object value, int scope) { 150 if (scope == SCOPE_REQUEST) { 151 this.request.setAttribute(name, value); 152 } 153 else { 154 HttpSession session = getSession(true); 155 session.setAttribute(name, value); 156 this.sessionAttributesToUpdate.remove(name); 157 } 158 } 159 160 public void removeAttribute(String name, int scope) { 161 if (scope == SCOPE_REQUEST) { 162 this.request.removeAttribute(name); 163 removeRequestDestructionCallback(name); 164 } 165 else { 166 HttpSession session = getSession(false); 167 if (session != null) { 168 session.removeAttribute(name); 169 this.sessionAttributesToUpdate.remove(name); 170 session.removeAttribute(DESTRUCTION_CALLBACK_NAME_PREFIX + name); 172 } 173 } 174 } 175 176 public void registerDestructionCallback(String name, Runnable callback, int scope) { 177 if (scope == SCOPE_REQUEST) { 178 registerRequestDestructionCallback(name, callback); 179 } 180 else { 181 registerSessionDestructionCallback(name, callback); 182 } 183 } 184 185 public String getSessionId() { 186 return getSession(true).getId(); 187 } 188 189 public Object getSessionMutex() { 190 return WebUtils.getSessionMutex(getSession(true)); 191 } 192 193 194 198 protected void updateAccessedSessionAttributes() { 199 HttpSession session = getSession(false); 200 if (session != null) { 201 for (Iterator it = this.sessionAttributesToUpdate.entrySet().iterator(); it.hasNext();) { 202 Map.Entry entry = (Map.Entry ) it.next(); 203 String name = (String ) entry.getKey(); 204 Object newValue = entry.getValue(); 205 Object oldValue = session.getAttribute(name); 206 if (oldValue == newValue) { 207 session.setAttribute(name, newValue); 208 } 209 } 210 } 211 this.sessionAttributesToUpdate.clear(); 212 } 213 214 219 private void registerSessionDestructionCallback(String name, Runnable callback) { 220 if (bindingListenerAvailable) { 221 HttpSession session = getSession(true); 222 session.setAttribute(DESTRUCTION_CALLBACK_NAME_PREFIX + name, 223 new DestructionCallbackBindingListener(callback)); 224 } 225 else { 226 if (logger.isWarnEnabled()) { 227 logger.warn("Could not register destruction callback [" + callback + "] for attribute '" + 228 name + "' in session scope because Servlet 2.3 API is not available"); 229 } 230 } 231 } 232 233 234 238 private static class DestructionCallbackBindingListener implements HttpSessionBindingListener , Serializable { 239 240 private final Runnable destructionCallback; 241 242 public DestructionCallbackBindingListener(Runnable destructionCallback) { 243 this.destructionCallback = destructionCallback; 244 } 245 246 public void valueBound(HttpSessionBindingEvent event) { 247 } 248 249 public void valueUnbound(HttpSessionBindingEvent event) { 250 this.destructionCallback.run(); 251 } 252 } 253 254 } 255 | Popular Tags |