1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.web.servlet.handler;
18 
19 import java.util.Collections;
20 import java.util.Properties;
21 import javax.servlet.http.HttpServletResponse;
22 
23 import static org.junit.Assert.*;
24 import org.junit.Before;
25 import org.junit.Test;
26 
27 import org.springframework.mock.web.MockHttpServletRequest;
28 import org.springframework.mock.web.MockHttpServletResponse;
29 import org.springframework.web.servlet.ModelAndView;
30 import org.springframework.web.util.WebUtils;
31 
32 /**
33  * @author Seth Ladd
34  * @author Juergen Hoeller
35  * @author Arjen Poutsma
36  */
37 public class SimpleMappingExceptionResolverTests {
38 
39 	private SimpleMappingExceptionResolver exceptionResolver;
40 	private MockHttpServletRequest request;
41 	private MockHttpServletResponse response;
42 	private Object handler1;
43 	private Object handler2;
44 	private Exception genericException;
45 
46 	@Before
setUp()47 	public void setUp() throws Exception {
48 		exceptionResolver = new SimpleMappingExceptionResolver();
49 		handler1 = new String();
50 		handler2 = new Object();
51 		request = new MockHttpServletRequest();
52 		response = new MockHttpServletResponse();
53 		request.setMethod("GET");
54 		genericException = new Exception();
55 	}
56 
57 	@Test
setOrder()58 	public void setOrder() {
59 		exceptionResolver.setOrder(2);
60 		assertEquals(2, exceptionResolver.getOrder());
61 	}
62 
63 	@Test
defaultErrorView()64 	public void defaultErrorView() {
65 		exceptionResolver.setDefaultErrorView("default-view");
66 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
67 		assertEquals("default-view", mav.getViewName());
68 		assertEquals(genericException, mav.getModel().get(SimpleMappingExceptionResolver.DEFAULT_EXCEPTION_ATTRIBUTE));
69 	}
70 
71 	@Test
defaultErrorViewDifferentHandler()72 	public void defaultErrorViewDifferentHandler() {
73 		exceptionResolver.setDefaultErrorView("default-view");
74 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
75 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler2, genericException);
76 		assertNull(mav);
77 	}
78 
79 	@Test
defaultErrorViewDifferentHandlerClass()80 	public void defaultErrorViewDifferentHandlerClass() {
81 		exceptionResolver.setDefaultErrorView("default-view");
82 		exceptionResolver.setMappedHandlerClasses(new Class[] {String.class});
83 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler2, genericException);
84 		assertNull(mav);
85 	}
86 
87 	@Test
nullExceptionAttribute()88 	public void nullExceptionAttribute() {
89 		exceptionResolver.setDefaultErrorView("default-view");
90 		exceptionResolver.setExceptionAttribute(null);
91 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
92 		assertEquals("default-view", mav.getViewName());
93 		assertNull(mav.getModel().get(SimpleMappingExceptionResolver.DEFAULT_EXCEPTION_ATTRIBUTE));
94 	}
95 
96 	@Test
nullExceptionMappings()97 	public void nullExceptionMappings() {
98 		exceptionResolver.setExceptionMappings(null);
99 		exceptionResolver.setDefaultErrorView("default-view");
100 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
101 		assertEquals("default-view", mav.getViewName());
102 	}
103 
104 	@Test
noDefaultStatusCode()105 	public void noDefaultStatusCode() {
106 		exceptionResolver.setDefaultErrorView("default-view");
107 		exceptionResolver.resolveException(request, response, handler1, genericException);
108 		assertEquals(HttpServletResponse.SC_OK, response.getStatus());
109 	}
110 
111 	@Test
setDefaultStatusCode()112 	public void setDefaultStatusCode() {
113 		exceptionResolver.setDefaultErrorView("default-view");
114 		exceptionResolver.setDefaultStatusCode(HttpServletResponse.SC_BAD_REQUEST);
115 		exceptionResolver.resolveException(request, response, handler1, genericException);
116 		assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
117 	}
118 
119 	@Test
noDefaultStatusCodeInInclude()120 	public void noDefaultStatusCodeInInclude() {
121 		exceptionResolver.setDefaultErrorView("default-view");
122 		exceptionResolver.setDefaultStatusCode(HttpServletResponse.SC_BAD_REQUEST);
123 		request.setAttribute(WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE, "some path");
124 		exceptionResolver.resolveException(request, response, handler1, genericException);
125 		assertEquals(HttpServletResponse.SC_OK, response.getStatus());
126 	}
127 
128 	@Test
specificStatusCode()129 	public void specificStatusCode() {
130 		exceptionResolver.setDefaultErrorView("default-view");
131 		exceptionResolver.setDefaultStatusCode(HttpServletResponse.SC_BAD_REQUEST);
132 		Properties statusCodes = new Properties();
133 		statusCodes.setProperty("default-view", "406");
134 		exceptionResolver.setStatusCodes(statusCodes);
135 		exceptionResolver.resolveException(request, response, handler1, genericException);
136 		assertEquals(HttpServletResponse.SC_NOT_ACCEPTABLE, response.getStatus());
137 	}
138 
139 	@Test
simpleExceptionMapping()140 	public void simpleExceptionMapping() {
141 		Properties props = new Properties();
142 		props.setProperty("Exception", "error");
143 		exceptionResolver.setWarnLogCategory("HANDLER_EXCEPTION");
144 		exceptionResolver.setExceptionMappings(props);
145 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
146 		assertEquals("error", mav.getViewName());
147 	}
148 
149 	@Test
exactExceptionMappingWithHandlerSpecified()150 	public void exactExceptionMappingWithHandlerSpecified() {
151 		Properties props = new Properties();
152 		props.setProperty("java.lang.Exception", "error");
153 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
154 		exceptionResolver.setExceptionMappings(props);
155 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
156 		assertEquals("error", mav.getViewName());
157 	}
158 
159 	@Test
exactExceptionMappingWithHandlerClassSpecified()160 	public void exactExceptionMappingWithHandlerClassSpecified() {
161 		Properties props = new Properties();
162 		props.setProperty("java.lang.Exception", "error");
163 		exceptionResolver.setMappedHandlerClasses(new Class[] {String.class});
164 		exceptionResolver.setExceptionMappings(props);
165 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
166 		assertEquals("error", mav.getViewName());
167 	}
168 
169 	@Test
exactExceptionMappingWithHandlerInterfaceSpecified()170 	public void exactExceptionMappingWithHandlerInterfaceSpecified() {
171 		Properties props = new Properties();
172 		props.setProperty("java.lang.Exception", "error");
173 		exceptionResolver.setMappedHandlerClasses(new Class[] {Comparable.class});
174 		exceptionResolver.setExceptionMappings(props);
175 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
176 		assertEquals("error", mav.getViewName());
177 	}
178 
179 	@Test
simpleExceptionMappingWithHandlerSpecifiedButWrongHandler()180 	public void simpleExceptionMappingWithHandlerSpecifiedButWrongHandler() {
181 		Properties props = new Properties();
182 		props.setProperty("Exception", "error");
183 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
184 		exceptionResolver.setExceptionMappings(props);
185 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler2, genericException);
186 		assertNull(mav);
187 	}
188 
189 	@Test
simpleExceptionMappingWithHandlerClassSpecifiedButWrongHandler()190 	public void simpleExceptionMappingWithHandlerClassSpecifiedButWrongHandler() {
191 		Properties props = new Properties();
192 		props.setProperty("Exception", "error");
193 		exceptionResolver.setMappedHandlerClasses(new Class[] {String.class});
194 		exceptionResolver.setExceptionMappings(props);
195 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler2, genericException);
196 		assertNull(mav);
197 	}
198 
199 	@Test
missingExceptionInMapping()200 	public void missingExceptionInMapping() {
201 		Properties props = new Properties();
202 		props.setProperty("SomeFooThrowable", "error");
203 		exceptionResolver.setWarnLogCategory("HANDLER_EXCEPTION");
204 		exceptionResolver.setExceptionMappings(props);
205 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
206 		assertNull(mav);
207 	}
208 
209 	@Test
twoMappings()210 	public void twoMappings() {
211 		Properties props = new Properties();
212 		props.setProperty("java.lang.Exception", "error");
213 		props.setProperty("AnotherException", "another-error");
214 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
215 		exceptionResolver.setExceptionMappings(props);
216 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
217 		assertEquals("error", mav.getViewName());
218 	}
219 
220 	@Test
twoMappingsOneShortOneLong()221 	public void twoMappingsOneShortOneLong() {
222 		Properties props = new Properties();
223 		props.setProperty("Exception", "error");
224 		props.setProperty("AnotherException", "another-error");
225 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
226 		exceptionResolver.setExceptionMappings(props);
227 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, genericException);
228 		assertEquals("error", mav.getViewName());
229 	}
230 
231 	@Test
twoMappingsOneShortOneLongThrowOddException()232 	public void twoMappingsOneShortOneLongThrowOddException() {
233 		Exception oddException = new SomeOddException();
234 		Properties props = new Properties();
235 		props.setProperty("Exception", "error");
236 		props.setProperty("SomeOddException", "another-error");
237 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
238 		exceptionResolver.setExceptionMappings(props);
239 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, oddException);
240 		assertEquals("error", mav.getViewName());
241 	}
242 
243 	@Test
twoMappingsThrowOddExceptionUseLongExceptionMapping()244 	public void twoMappingsThrowOddExceptionUseLongExceptionMapping() {
245 		Exception oddException = new SomeOddException();
246 		Properties props = new Properties();
247 		props.setProperty("java.lang.Exception", "error");
248 		props.setProperty("SomeOddException", "another-error");
249 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
250 		exceptionResolver.setExceptionMappings(props);
251 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, oddException);
252 		assertEquals("another-error", mav.getViewName());
253 	}
254 
255 	@Test
threeMappings()256 	public void threeMappings() {
257 		Exception oddException = new AnotherOddException();
258 		Properties props = new Properties();
259 		props.setProperty("java.lang.Exception", "error");
260 		props.setProperty("SomeOddException", "another-error");
261 		props.setProperty("AnotherOddException", "another-some-error");
262 		exceptionResolver.setMappedHandlers(Collections.singleton(handler1));
263 		exceptionResolver.setExceptionMappings(props);
264 		ModelAndView mav = exceptionResolver.resolveException(request, response, handler1, oddException);
265 		assertEquals("another-some-error", mav.getViewName());
266 	}
267 
268 
269 	private static class SomeOddException extends Exception {
270 
271 	}
272 
273 
274 	private static class AnotherOddException extends Exception {
275 
276 	}
277 
278 }
279