我有一个SimpleMappingExceptionResolver
来重定向每个未处理的异常。
@Bean public SimpleMappingExceptionResolver exceptionResolver() {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
resolver.setDefaultErrorView("general-error");
resolver.setWarnLogCategory(TamponException.class.getName());
return resolver;
}
我一实施Spring安全性,就意识到我需要排除AccessDeniedException
:
resolver.setExcludedExceptions(AccessDeniedException.class);
现在我正在实施Spring Web Flow。 SWF正在AccessDeniedException
中包含那些重要的FlowExecutionException
。这种组合破坏了Spring Security,因为SimpleMappingExceptionResolver
现在捕获了这些包装的异常。我也可以排除FlowExecutionException
,但这不是我想要的。
如何正确解决此问题?
我的下一步应该是实现一个HandlerExceptionResolver
,只有在解包的异常不是resolveException()
时委托AccessDeniedException
。但是我想知道是否存在可以用于组合SWF,Security和HandlerExceptionResolver的东西。
答案 0 :(得分:2)
我正在使用类似于你的配置,具有Spring webflow和Spring安全性。为了处理异常,我使用webflow处理而不是SimpleMappingExceptionResolver,这对我来说非常有用。
作为一个开始,您需要一个处理异常的全局xml流,此流将用作所有其他流的“父”。或者您也可以直接在流程中包含全局转换和视图状态:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
abstract="true">
<persistence-context/>
<view-state id="generalException" view="../views/exception/generalException.xhtml">
<on-entry>
<evaluate expression="exceptionManager.extractMessages(flowExecutionException, rootCauseException)" result="viewScope.exc"/>
</on-entry>
</view-state>
<global-transitions>
<transition on-exception="java.lang.Exception" to="generalException"/>
</global-transitions>
</flow>
类ExceptionManager仅用于以可读的方式格式化异常,特别是在我的情况下,BatchUpdateException需要调用next()方法来了解异常的来源:
@Service("exceptionManager")
public class ExceptionManagerImpl {
public Map<String, String> extractMessages(Exception e, Exception root)
{
Map<String, String> out = new HashMap<String, String>();
out.put("exc_message", e.getClass().toString() + ": " + e.getMessage());
out.put("exc_details", formatStackTrace(e.getStackTrace()));
out.put("root_message", root.getClass().toString() + ": " + root.getMessage());
out.put("root_details", formatStackTrace(root.getStackTrace()));
if (root instanceof BatchUpdateException)
{
out.put("batch_message", ((BatchUpdateException)root).getNextException().getClass().toString() + ": " + ((BatchUpdateException)root).getNextException().getMessage());
}
return out;
}
public String formatStackTrace(StackTraceElement[] elements)
{
String out = "";
for (StackTraceElement ste: elements)
out += ste.toString() + "<br/>";
return out;
}
}
以这种方式,所有未处理的异常将显示在JSF页面或您用于视图的任何内容中。 AccessDeniedException通常通过此实现在我的系统中通过Spring安全性。您还可以为不同的异常指定不同的行为。
我希望它有所帮助,祝你有个美好的一天,
马蒂亚