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