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