服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

jsf和struts框架的错误控制与封装处理

在struts中,通常采用的全局错误控制模式是构建一个baseaction,在其execute方法中完成前台传回方法的dispatch操作,并由 try……catch……捕获程序错误,实现错误的控制和展示。一个典型的baseaction例子如下:

代码

public actionforward execute(actionmapping mapping, actionform form,
httpservletrequest request, httpservletresponse response) {

……

    actionforward forwardpage = null;

    try { 

        string parameter = mapping.getparameter();

        if (parameter == null) { 

        string message = messages.getmessage("dispatch.handler",mapping.getpath());

            response.senderror(500, message);

            return null;

        }

    string name = processreqcode(request.getparameter(parameter));

    forwardpage = dispatchmethod(mapping, form, request, response, name);

    } catch (baseexception ex) { 

        if (log.isdebugenabled())

            log.debug("发生错误:", ex);

        forwardpage = processbaseexception(request, mapping, ex);

        } catch (throwable ex) { 

            log.error("发生错误:", ex);

        actionmessages errors = new actionmessages();

        bytearrayoutputstream ostr = new bytearrayoutputstream();

        ex.printstacktrace(new printstream(ostr));

        errors.add("org.apache.struts.action.global_message", new actionmessage
(ostr.tostring()));

        saveerrors(request, errors);

        forwardpage = mapping.findforward("syserror");

        output.setstatus("fail");

        output.seterror(ex.getmessage());

    }

    ……

    }

由于jsf采用了managed bean,jsp页面直接通过调用managed bean中的方法完成数据交互,不能像struts一样通过捕获dispatch操作过程抛出的异常来完成错误的处理(因为根本就没有dispatch方法),似乎jsf根本就不支持全局的错误处理。

如果在managed bean中throw 一个exception(这里是appexception),观察一下控制台的日志,可以看到其实错误是从一个actionlistener的实现中抛出的(针对myfaces,这里是actionlistenerimpl),参考jsf的生命周期过程,方法出来了:

代码

public class globalactionlistener extends actionlistenerimpl {

    public void processaction(actionevent event) throws abortprocessingexception { 

        facescontext facescontext = facescontext.getcurrentinstance();

        application application = facescontext.getapplication();

        actionsource actionsource = (actionsource) event.getcomponent();

        methodbinding methodbinding = actionsource.getaction();

        string fromaction = null;string outcome = null;

        if (methodbinding != null) {

             fromaction = methodbinding.getexpressionstring();

            try { 

                outcome = (string) methodbinding.invoke(facescontext, null);

        } catch (evaluationexception e) { 

            throwable cause = e.getcause();

            if (cause != null && cause instanceof appexception) { 

        //这里需要根据框架的不同,判断实例是否是程序中手动抛出的错误        

        facesutils.adderrormessage(event.getcomponent().getclientid(facescontext),
cause.getmessage());}

         else { 

            throw (abortprocessingexception) cause;

        } 

    } catch (runtimeexception e) { 

        throw new facesexception("error calling action method of component with id " + 
event.getcomponent().getclientid(facescontext), e);

    }

    navigationhandler navigationhandler = application.getnavigationhandler();

    navigationhandler.handlenavigation(facescontext, fromaction, outcome);

    // render response if needed 

      facescontext.renderresponse();

        }

    }

监听器配置,faces-config-application.xml:

代码

<application>
        <variable-resolver>
           org.springframework.web.jsf.delegatingvariableresolver
        </variable-resolver> 
<message-bundle>resources.application</message-bundle> 
<locale-config> 
<default-locale>en</default-locale> 
</locale-config> 
<action-listener>
org.snailportal.webframework.listener.globalactionlistener
</action-listener> 
</application>

这样,开发人员只需要在action和managed bean里面根据业务的需要抛出指定基础类型的exception实例,由baseaction和actionlistener完成错误的封装处理,再传递给前台进行显示,从而减少开发的代码量,提高框架的可维护性。

扫描关注微信公众号