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