操作系统  办公  实用知识  设计  开发  WEB开发  移动开发  数据库  软件工程  网管  安全  管理  信息化  答疑  渠道 

JSF和Struts框架的错误控制与封装处理

2007-9-12 网友评论 0 条 点击进入论坛

  在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:

  代码

  org.springframework.web.jsf.DelegatingVariableResolver

  resources.application

  en

  org.snailportal.webframework.listener.GlobalActionListener

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

已有 0 位对此文章感兴趣的网友发布了看法    
我来评两句 登录邮箱: 密码:
  匿名发表
今日推荐
技术文库(共有 46430 篇文章)
操作系统
办公软件
实用知识
网络管理
软件开发
WEB开发
软件工程
数据库
设计在线
信息安全
行业信息化
管理信息化
重点推荐
电子杂志订阅
点击电子杂志名称查看样刊
输入E-mail地址即可订阅
E-mail