使用Spring 2.5.6,因此配置了SimpleMappingExceptionResolver
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="MismatchException">error/mismatch-error</prop>
<prop key="Exception">error/${module.render.error.logical.page}</prop>
<prop key="IllegalArgumentException">error/module-illegal-arg</prop>
<prop key="MissingServletRequestParameterException">error/module-illegal-arg</prop>
</props>
</property>
</bean>
这个想法是,对于IllegalArgumentException和MissingServletRequestParameterException,我想要一个略有不同的错误屏幕,并且还返回HTTP状态代码400。
IllegalArgumentException的工作原理很好,所引用的JSP将状态正确设置为400。MissingServletRequestParameterException不起作用,相反,我收到了通用的500错误。
最佳答案
几个小时后,以为可能在error / module-illegal-arg.jsp中存在错误,或者可能需要在web.xml中进行其他配置,我跳入调试器并追溯到SimpleMappingExceptionResolver.java中的getDepth()方法。 。
基本上,它是将Exception条目与MissingServletRequestParameterException相匹配。尽管Exception是超类,但人们会认为这种方法更喜欢直接匹配而不是几个级别的匹配。实际上,这就是getDepth()的全部目的。 366行给出了最终线索:
if (exceptionClass.getName().indexOf(exceptionMapping) != -1) {
因此,基本上,Exception可以在名称为work Exception的任何类中以0的深度级别进行匹配。
那么,为什么IllegalArgumentException起作用而MissingServletRequestParameterException不能起作用?基础存储是HashTable。 IllegalArgumentException散列到比Exception更早的值。将该异常散列到比MissingServletRequestParameterException更早的值。
最终解决方法:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="MismatchException">error/mismatch-error</prop>
<!--
The full path is here in order to prevent matches on every class with the word
'Exception' in its class name. The resolver will go up the class hierarchy and will
still match all derived classes from Exception.
-->
<prop key="java.lang.Exception">error/${module.render.error.logical.page}</prop>
<prop key="IllegalArgumentException">error/module-illegal-arg</prop>
<prop key="MissingServletRequestParameterException">error/module-illegal-arg</prop>
</props>
</property>
</bean>