1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.servlet;
15
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import javax.servlet.ServletContext;
22 import javax.servlet.ServletException;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.eclipse.jetty.http.HttpMethods;
27 import org.eclipse.jetty.server.Dispatcher;
28 import org.eclipse.jetty.server.HttpConnection;
29 import org.eclipse.jetty.server.Request;
30 import org.eclipse.jetty.server.handler.ContextHandler;
31 import org.eclipse.jetty.server.handler.ErrorHandler;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34
35
36
37
38
39
40
41
42 public class ErrorPageErrorHandler extends ErrorHandler
43 {
44 private static final Logger LOG = Log.getLogger(ErrorPageErrorHandler.class);
45
46 public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
47
48 protected ServletContext _servletContext;
49 private final Map<String,String> _errorPages= new HashMap<String,String>();
50 private final List<ErrorCodeRange> _errorPageList=new ArrayList<ErrorCodeRange>();
51
52
53 public ErrorPageErrorHandler()
54 {}
55
56
57
58
59
60 @Override
61 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
62 {
63 String method = request.getMethod();
64 if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
65 {
66 HttpConnection.getCurrentConnection().getRequest().setHandled(true);
67 return;
68 }
69 if (_errorPages!=null)
70 {
71 String error_page= null;
72 Class<?> exClass= (Class<?>)request.getAttribute(Dispatcher.ERROR_EXCEPTION_TYPE);
73
74 if (ServletException.class.equals(exClass))
75 {
76 error_page= (String)_errorPages.get(exClass.getName());
77 if (error_page == null)
78 {
79 Throwable th= (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION);
80 while (th instanceof ServletException)
81 th= ((ServletException)th).getRootCause();
82 if (th != null)
83 exClass= th.getClass();
84 }
85 }
86
87 while (error_page == null && exClass != null )
88 {
89 error_page= (String)_errorPages.get(exClass.getName());
90 exClass= exClass.getSuperclass();
91 }
92
93 if (error_page == null)
94 {
95
96 Integer code=(Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE);
97 if (code!=null)
98 {
99 error_page= (String)_errorPages.get(Integer.toString(code));
100
101
102 if ((error_page == null) && (_errorPageList != null))
103 {
104
105 for (int i = 0; i < _errorPageList.size(); i++)
106 {
107 ErrorCodeRange errCode = (ErrorCodeRange) _errorPageList.get(i);
108 if (errCode.isInRange(code))
109 {
110 error_page = errCode.getUri();
111 break;
112 }
113 }
114 }
115 }
116 }
117
118 if (error_page!=null)
119 {
120 String old_error_page=(String)request.getAttribute(ERROR_PAGE);
121 if (old_error_page==null || !old_error_page.equals(error_page))
122 {
123 request.setAttribute(ERROR_PAGE, error_page);
124
125 Dispatcher dispatcher = (Dispatcher) _servletContext.getRequestDispatcher(error_page);
126 try
127 {
128 if(dispatcher!=null)
129 {
130 dispatcher.error(request, response);
131 return;
132 }
133 else
134 {
135 LOG.warn("No error page "+error_page);
136 }
137 }
138 catch (ServletException e)
139 {
140 LOG.warn(Log.EXCEPTION, e);
141 return;
142 }
143 }
144 }
145 }
146
147 super.handle(target, baseRequest, request, response);
148 }
149
150
151
152
153
154 public Map<String,String> getErrorPages()
155 {
156 return _errorPages;
157 }
158
159
160
161
162
163 public void setErrorPages(Map<String,String> errorPages)
164 {
165 _errorPages.clear();
166 if (errorPages!=null)
167 _errorPages.putAll(errorPages);
168 }
169
170
171
172
173
174
175
176
177 public void addErrorPage(Class<? extends Throwable> exception,String uri)
178 {
179 _errorPages.put(exception.getName(),uri);
180 }
181
182
183
184
185
186
187
188
189 public void addErrorPage(String exceptionClassName,String uri)
190 {
191 _errorPages.put(exceptionClassName,uri);
192 }
193
194
195
196
197
198
199
200
201 public void addErrorPage(int code,String uri)
202 {
203 _errorPages.put(Integer.toString(code),uri);
204 }
205
206
207
208
209
210
211
212
213
214 public void addErrorPage(int from, int to, String uri)
215 {
216 _errorPageList.add(new ErrorCodeRange(from, to, uri));
217 }
218
219
220 @Override
221 protected void doStart() throws Exception
222 {
223 super.doStart();
224 _servletContext=ContextHandler.getCurrentContext();
225 }
226
227
228 @Override
229 protected void doStop() throws Exception
230 {
231
232 super.doStop();
233 }
234
235
236
237 private class ErrorCodeRange
238 {
239 private int _from;
240 private int _to;
241 private String _uri;
242
243 ErrorCodeRange(int from, int to, String uri)
244 throws IllegalArgumentException
245 {
246 if (from > to)
247 throw new IllegalArgumentException("from>to");
248
249 _from = from;
250 _to = to;
251 _uri = uri;
252 }
253
254 boolean isInRange(int value)
255 {
256 if ((value >= _from) && (value <= _to))
257 {
258 return true;
259 }
260
261 return false;
262 }
263
264 String getUri()
265 {
266 return _uri;
267 }
268
269 @Override
270 public String toString()
271 {
272 return "from: " + _from + ",to: " + _to + ",uri: " + _uri;
273 }
274 }
275 }