有时候需要在managed-bean的构造方法里执行一些逻辑代码,这时如果抛出了异常,该如何捕捉呢?


      JSF的事件被执行时,如果在事件处理方法中抛出了Exception,我们可以通过JSF提供的ActionListener机制catch到抛出的Exception,然后根据Exception类型执行不同的错误处理。

     但有时候需要在managed-bean的构造方法里执行一些逻辑代码,这时如果抛出了异常,该如何捕捉呢?
你可能会想到在Filter里加以捕捉处理,但不幸的是,你在Filter里只能捕捉到经过被加工了的Exception:ServletException,而且你也没办法将其还原成最初被抛出的Exception。

     要达到这个目的,我们可以利用JSF框架提供的variable-resolver切入点。因为JSF的managed-bean的instance,就是由variable-resolver所定义类所生成的。
所以我们可以借助JSF提供的机制,注册我们自己的variable-resolver类,从而就可以捕捉到managed-bean构造方法执行时抛出的异常了。

具体方法为:
     自定义一个VariableResolverImpl类,该类需要实现虚类javax.faces.el.VariableResolver,为了简便起见,我们可以根据情况,重载所使用的JSF实现里的相关类就可以了,比如MyFaces的情况下,重载org.apache.myfaces.el.VariableResolverImpl. resolveVariable方法就可以了。
代码如下:
package mypackage;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

public class VariableResolverImpl extends
        org.apache.myfaces.el.VariableResolverImpl {
    private static final String ERROR_FLAG = "error";
    private static final String EXCEPTION_TYPE = "exception";
    
    @Override
    public Object resolveVariable(FacesContext facesContext, String name) {
        try {
            return super.resolveVariable(facesContext, name);
        } catch (Throwable e) {
            HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
            
            request.setAttribute(ERROR_FLAG, Boolean.TRUE);
            request.setAttribute(EXCEPTION_TYPE, e);
            
            throw new RuntimeException(e);
        }
    }
    
}
  在faces-config.xml里注册刚才实现的类,让JSF使用我们提供的类解析变量
<faces-config>
<!--  Application Config -->
<application>
  <variable-resolver>mypackage.VariableResolverImpl</variable-resolver>
  <!-- other configuration here -->
</application>

<!-- other configuration here -->

</faces-config>
在其他地方处理异常,比如Filter里
public class AppFilter implements Filter {
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {

        try {
            chain.doFilter(request, response);
        } catch (ServletException e) {
            
            Boolean error =  (Boolean)request.getAttribute("error");
            if (Boolean.TRUE.equals(error)) {
                Throwable te = (Throwable)request.getAttribute("exception");
                
                if (te instanceof AppException) {
                    //TODO do business here
                    
                } else {
                    //TODO do business here
            }
            } else {
            //TODO do business here
        }

        }

}
 
评论
lfx2002 2008-07-04   回复
请问一下AppException是在哪个JAR下面
我编译通不过
谢谢
发表评论

您还没有登录,请登录后发表评论

vieri122
搜索本博客
最近加入圈子
最新评论