View Javadoc

1   /*
2    * Copyright 2009-2012 Capgemini and others
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at 
7    * 
8    * http://www.apache.org/licenses/LICENSE-2.0 
9    * 
10   * Unless required by applicable law or agreed to in writing, software 
11   * distributed under the License is distributed on an "AS IS" BASIS, 
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License. 
15   * 
16   */
17  package net.sourceforge.statelessfilter.wrappers.headers;
18  
19  import java.io.IOException;
20  import java.io.PrintWriter;
21  
22  import javax.servlet.ServletOutputStream;
23  import javax.servlet.http.HttpServletResponse;
24  import javax.servlet.http.HttpServletResponseWrapper;
25  
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  import net.sourceforge.statelessfilter.wrappers.BufferedHttpResponseWrapper;
30  import net.sourceforge.statelessfilter.wrappers.StatelessRequestWrapper;
31  
32  /**
33   * A custom response wrapper that inject session data before sending content
34   * output.
35   * <p>
36   * Session data can no longer be modified after the application has started to
37   * write to output stream.
38   * <p>
39   * This changes slightly the behavior of the container since it would usually
40   * prevent session creation in this case, but not session data modifications.
41   * However, most frameworks ensure to have updated session and application data
42   * BEFORE doing any output. As a result, this wrapper is safe for most uses.
43   * 
44   * <p>
45   * This wrappers uses much less memory than {@link BufferedHttpResponseWrapper}
46   * since it does not cache the whole response data.
47   * 
48   * @author Nicolas Richeton
49   */
50  public class HeaderBufferedHttpResponseWrapper extends
51  		HttpServletResponseWrapper {
52  	Logger logger = LoggerFactory
53  			.getLogger(HeaderBufferedHttpResponseWrapper.class);
54  
55  	private StatelessRequestWrapper statelessRequest = null;
56  	HttpServletResponse origResponse = null;
57  
58  	public HeaderBufferedHttpResponseWrapper(StatelessRequestWrapper request,
59  			HttpServletResponse origResponse) {
60  		super(origResponse);
61  		this.origResponse = origResponse;
62  		this.statelessRequest = request;
63  		logger.debug("Init HeaderBufferedHttpResponseWrapper");
64  	}
65  
66  	/**
67  	 * Write session data if necessary (session not already written).
68  	 * 
69  	 * @throws IOException
70  	 */
71  	private void writeSession() throws IOException {
72  		if (!statelessRequest.isSessionWritten()) {
73  			logger.debug("writting session");
74  
75  			statelessRequest.writeSession(statelessRequest, origResponse);
76  		} else {
77  			logger.debug("session already written");
78  
79  		}
80  	}
81  
82  	/**
83  	 * {@inheritDoc} javax.servlet.ServletResponseWrapper#flushBuffer()
84  	 */
85  	@Override
86  	public void flushBuffer() throws IOException {
87  		logger.debug("flushBuffer()");
88  		// Write session before invoking the standard behavior
89  		writeSession();
90  		super.flushBuffer();
91  	}
92  
93  	/**
94  	 * {@inheritDoc} javax.servlet.ServletResponseWrapper#getOutputStream()
95  	 */
96  	@Override
97  	public ServletOutputStream getOutputStream() throws IOException {
98  		logger.debug("getOutputStream() has been called");
99  		// Write session before invoking the standard behavior
100 		writeSession();
101 		return super.getOutputStream();
102 	}
103 
104 	/**
105 	 * {@inheritDoc} javax.servlet.ServletResponseWrapper#getWriter()
106 	 */
107 	@Override
108 	public PrintWriter getWriter() throws IOException {
109 		logger.debug("getWriter() has been called");
110 		// Write session before invoking the standard behavior
111 		writeSession();
112 
113 		return super.getWriter();
114 	}
115 
116 	/**
117 	 * {@inheritDoc}
118 	 * javax.servlet.http.HttpServletResponseWrapper#sendError(int)
119 	 */
120 	@Override
121 	public void sendError(int sc) throws IOException {
122 		logger.debug("sendError() has been called");
123 		// Write session before invoking the standard behavior
124 		writeSession();
125 		super.sendError(sc);
126 	}
127 
128 	/**
129 	 * {@inheritDoc}
130 	 * javax.servlet.http.HttpServletResponseWrapper#sendError(int,
131 	 * java.lang.String)
132 	 */
133 	@Override
134 	public void sendError(int sc, String msg) throws IOException {
135 		logger.debug("sendError() has been called");
136 		// Write session before invoking the standard behavior
137 		writeSession();
138 		super.sendError(sc, msg);
139 	}
140 
141 	/**
142 	 * {@inheritDoc}
143 	 * javax.servlet.http.HttpServletResponseWrapper#sendRedirect(java.lang.
144 	 * String)
145 	 */
146 	@Override
147 	public void sendRedirect(String location) throws IOException {
148 		logger.debug("sendRedirect() has been called");
149 		// Write session before invoking the standard behavior
150 		writeSession();
151 		super.sendRedirect(location);
152 	}
153 
154 }