@@ -48,6 +48,8 @@ public class ContentCachingResponseWrapper extends HttpServletResponseWrapper {
48
48
49
49
private int statusCode = HttpServletResponse .SC_OK ;
50
50
51
+ private Integer contentLength ;
52
+
51
53
52
54
/**
53
55
* Create a new ContentCachingResponseWrapper for the given servlet response.
@@ -73,21 +75,34 @@ public void setStatus(int sc, String sm) {
73
75
74
76
@ Override
75
77
public void sendError (int sc ) throws IOException {
76
- copyBodyToResponse ();
77
- super .sendError (sc );
78
+ copyBodyToResponse (false );
79
+ try {
80
+ super .sendError (sc );
81
+ }
82
+ catch (IllegalStateException ex ) {
83
+ // Possibly on Tomcat when called too late: fall back to silent setStatus
84
+ super .setStatus (sc );
85
+ }
78
86
this .statusCode = sc ;
79
87
}
80
88
81
89
@ Override
90
+ @ SuppressWarnings ("deprecation" )
82
91
public void sendError (int sc , String msg ) throws IOException {
83
- copyBodyToResponse ();
84
- super .sendError (sc , msg );
92
+ copyBodyToResponse (false );
93
+ try {
94
+ super .sendError (sc , msg );
95
+ }
96
+ catch (IllegalStateException ex ) {
97
+ // Possibly on Tomcat when called too late: fall back to silent setStatus
98
+ super .setStatus (sc , msg );
99
+ }
85
100
this .statusCode = sc ;
86
101
}
87
102
88
103
@ Override
89
104
public void sendRedirect (String location ) throws IOException {
90
- copyBodyToResponse ();
105
+ copyBodyToResponse (false );
91
106
super .sendRedirect (location );
92
107
}
93
108
@@ -109,6 +124,7 @@ public PrintWriter getWriter() throws IOException {
109
124
@ Override
110
125
public void setContentLength (int len ) {
111
126
this .content .resize (len );
127
+ this .contentLength = len ;
112
128
}
113
129
114
130
// Overrides Servlet 3.1 setContentLengthLong(long) at runtime
@@ -117,7 +133,9 @@ public void setContentLengthLong(long len) {
117
133
throw new IllegalArgumentException ("Content-Length exceeds ShallowEtagHeaderFilter's maximum (" +
118
134
Integer .MAX_VALUE + "): " + len );
119
135
}
120
- this .content .resize ((int ) len );
136
+ int lenInt = (int ) len ;
137
+ this .content .resize (lenInt );
138
+ this .contentLength = lenInt ;
121
139
}
122
140
123
141
@ Override
@@ -150,24 +168,44 @@ public byte[] getContentAsByteArray() {
150
168
return this .content .toByteArray ();
151
169
}
152
170
171
+ /**
172
+ * Return an {@link InputStream} to the cached content.
173
+ */
174
+ public InputStream getContentInputStream (){
175
+ return this .content .getInputStream ();
176
+ }
177
+
178
+ /**
179
+ * Return the current size of the cached content.
180
+ */
181
+ public int getContentSize (){
182
+ return this .content .size ();
183
+ }
184
+
185
+ /**
186
+ * Copy the complete cached body content to the response.
187
+ */
153
188
public void copyBodyToResponse () throws IOException {
189
+ copyBodyToResponse (true );
190
+ }
191
+
192
+ /**
193
+ * Copy the cached body content to the response.
194
+ * @param complete whether to set a corresponding content length
195
+ * for the complete cached body content
196
+ */
197
+ protected void copyBodyToResponse (boolean complete ) throws IOException {
154
198
if (this .content .size () > 0 ) {
155
199
HttpServletResponse rawResponse = (HttpServletResponse ) getResponse ();
156
- if (! rawResponse .isCommitted ()){
157
- rawResponse .setContentLength (this .content .size ());
200
+ if ((complete || this .contentLength != null ) && !rawResponse .isCommitted ()){
201
+ rawResponse .setContentLength (complete ? this .content .size () : this .contentLength );
202
+ this .contentLength = null ;
158
203
}
159
204
this .content .writeTo (rawResponse .getOutputStream ());
160
205
this .content .reset ();
161
206
}
162
207
}
163
208
164
- public int getContentSize (){
165
- return this .content .size ();
166
- }
167
-
168
- public InputStream getContentInputStream (){
169
- return this .content .getInputStream ();
170
- }
171
209
172
210
private class ResponseServletOutputStream extends ServletOutputStream {
173
211
0 commit comments