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