1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.cubby.filter;
17
18 import java.io.IOException;
19 import java.io.UnsupportedEncodingException;
20 import java.nio.charset.Charset;
21
22 import javax.servlet.Filter;
23 import javax.servlet.FilterChain;
24 import javax.servlet.FilterConfig;
25 import javax.servlet.ServletException;
26 import javax.servlet.ServletRequest;
27 import javax.servlet.ServletResponse;
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletRequestWrapper;
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 public class EncodingFilter implements Filter {
77
78 private static final String ALREADY_FILTERED_ATTRIBUTE_NAME = EncodingFilter.class
79 .getName()
80 + ".FILTERED";
81
82
83 private static final String ENCODING = "encoding";
84
85
86 private static final String FORCE_ENCODING = "forceEncoding";
87
88
89 private static final String URI_ENCODING = "URIEncoding";
90
91
92 private static final String URI_BYTES_ENCODING = "URIBytesEncoding";
93
94
95 private static final String DEFAULT_URI_BYTE_ENCODING = "ISO-8859-1";
96
97
98 private String encoding;
99
100
101 private boolean forceEncoding = false;
102
103
104 private String uriEncoding;
105
106
107 private String uriBytesEncoding;
108
109
110
111
112 public void init(final FilterConfig config) throws ServletException {
113 encoding = config.getInitParameter(ENCODING);
114 try {
115 validateEncoding(encoding);
116 } catch (final UnsupportedEncodingException e) {
117 throw new ServletException(e);
118 }
119
120 final String forceEncodingString = config
121 .getInitParameter(FORCE_ENCODING);
122 if (forceEncodingString != null) {
123 forceEncoding = Boolean.parseBoolean(forceEncodingString);
124 }
125
126 uriEncoding = config.getInitParameter(URI_ENCODING);
127 try {
128 validateEncoding(uriEncoding);
129 } catch (final UnsupportedEncodingException e) {
130 throw new ServletException(e);
131 }
132
133 uriBytesEncoding = config.getInitParameter(URI_BYTES_ENCODING);
134 if (uriBytesEncoding == null) {
135 uriBytesEncoding = DEFAULT_URI_BYTE_ENCODING;
136 }
137 try {
138 validateEncoding(uriBytesEncoding);
139 } catch (final UnsupportedEncodingException e) {
140 throw new ServletException(e);
141 }
142 }
143
144
145
146
147
148
149
150
151
152 private void validateEncoding(final String encoding)
153 throws UnsupportedEncodingException {
154 if (encoding != null && !Charset.isSupported(encoding)) {
155 throw new UnsupportedEncodingException(encoding);
156 }
157 }
158
159
160
161
162 public void destroy() {
163 }
164
165
166
167
168 public void doFilter(final ServletRequest request,
169 final ServletResponse response, final FilterChain chain)
170 throws IOException, ServletException {
171 if (request.getAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME) == null) {
172 request.setAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME, Boolean.TRUE);
173 if (request.getCharacterEncoding() == null || forceEncoding) {
174 request.setCharacterEncoding(encoding);
175 }
176 if (uriEncoding == null) {
177 chain.doFilter(request, response);
178 } else {
179 final ServletRequest wrapper = new EncodingHttpServletRequestWrapper(
180 HttpServletRequest.class.cast(request), uriEncoding,
181 uriBytesEncoding);
182 chain.doFilter(wrapper, response);
183 }
184 request.removeAttribute(ALREADY_FILTERED_ATTRIBUTE_NAME);
185 } else {
186 chain.doFilter(request, response);
187 }
188 }
189
190
191
192
193
194
195
196 private class EncodingHttpServletRequestWrapper extends
197 HttpServletRequestWrapper {
198
199
200 private final String uriEncoding;
201
202
203 private final String uriBytesEncoding;
204
205
206
207
208
209
210
211
212
213
214
215
216
217 public EncodingHttpServletRequestWrapper(
218 final HttpServletRequest request, final String uriEncoding,
219 final String uriBytesEncoding) throws IOException {
220 super(request);
221 this.uriEncoding = uriEncoding;
222 this.uriBytesEncoding = uriBytesEncoding;
223 }
224
225 @Override
226 public String getServletPath() {
227 return rebuild(super.getServletPath(), uriEncoding,
228 uriBytesEncoding);
229 }
230
231 @Override
232 public String getPathInfo() {
233 return rebuild(super.getPathInfo(), uriEncoding, uriBytesEncoding);
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248 private String rebuild(final String str, final String encoding,
249 final String bytesEncoding) {
250 if (str == null || encoding == null) {
251 return str;
252 }
253 try {
254 return new String(str.getBytes(bytesEncoding), encoding);
255 } catch (final UnsupportedEncodingException e) {
256 throw new IllegalStateException(e);
257 }
258 }
259
260 }
261
262 }