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