1.1.1.1    Action类

如果说ActionServletStruts框架的入口,RequestProcessor是消化过滤系统,则org.apache.struts.action.Action类可以说是整个框架的心脏。他是客户请求和业务操作的连接桥,也可以将其看作是业务操作的客户代理。

在前面对ReqeustProcessor的学习中,我们了解到一旦确定并得到了一个action实例,ReqeustProcessor会调用actionexecute()方法处理客户请求,你需要扩展action类,并实现它的execute()方法,在此方法中添加你自己的处理代码。下面给出是一个示例,这个action用来处理用户的登录请求:

package com.oreilly.struts.storefront.security;
 
import java.util.Locale;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import com.oreilly.struts.storefront.customer.view.UserView;
import com.oreilly.struts.storefront.framework.exceptions.BaseException;
import com.oreilly.struts.storefront.framework.UserContainer;
import com.oreilly.struts.storefront.framework.StorefrontBaseAction;
import com.oreilly.struts.storefront.framework.util.IConstants;
import com.oreilly.struts.storefront.service.IStorefrontService;
 
/**
 * Implements the logic to authenticate a user for the Storefront application.
 */
public class LoginAction extends StorefrontBaseAction {
  /**
   * Called by the controller when the user attempts to log in to the
   * Storefront application.
   */
  public ActionForward execute( ActionMapping mapping,
                                ActionForm form,
                                HttpServletRequest request,
                                HttpServletResponse response )
  throws Exception{
 
    // The email and password should have already been validated by the ActionForm
    String email = ((LoginForm)form).getEmail(  );
    String password = ((LoginForm)form).getPassword(  );
 
    // Log in through the security service
    IStorefrontService serviceImpl = getStorefrontService(  );
    UserView userView = serviceImpl.authenticate(email, password);
 
    // Create a single container object to store user data
    UserContainer existingContainer = null;
    HttpSession session = request.getSession(false);
    if ( session != null ){
      existingContainer = getUserContainer(request);
      session.invalidate(  );
    }else{
      existingContainer = new UserContainer(  );
    }
 
    // Create a new session for the user
    session = request.getSession(true);
 
    // Store the UserView in the container and store the container in the session
    existingContainer.setUserView(userView);
    session.setAttribute(IConstants.USER_CONTAINER_KEY, existingContainer);
 
    // Return a Success forward
    return mapping.findForward(IConstants.SUCCESS_KEY);
  }
}

 

1.1.1.1.1      Action类缓冲

Action类被设计为线程安全的,在每个应用中每个Action类只会被实例化一次,供所有线程共享。RequestProcessor利用一个HashMap用来保存Action实例。

思考题?

所有线程共享一个Action类实例意味着什么?我们在编程中需要注意些什么呢?

 

1.1.1.2    ActionForward类

从前面的介绍我们已经了解到,Actionexecute( )方法返回一个ActionForward对象。ActionForward对象是JSP页面、Java servletweb资源的抽象表现。

ActionForward的用途是为了减少应用和物理资源(JSP页面,Java servlet)的耦合,物理资源只需要在配置文件中指定(利用name,path属性和forward元素的redirect属性),而不是在代码中指定。RequestDispatcher利用ActionForward来执行重定向操作。

要在Action中返回一个ActionForward对象,你可以动态地创建一个ActionForward 对象,不过更为通用的解决方案是,通过在Struts配置文件中进行action映射,然后通过关键字去查找一个ActionForward 。下面是代码示例:

  return mapping.findForward( "Success" );

上面的代码中,"Success"作为参数被传递到ActionMappingfindFoward( )方法中,findFoward( )方法在Struts配置文件的global-forwards区域,以及被调用的actionforward元素中查找名字和"Success"相匹配的元素。下面是action元素中的forward示例:

<action

   input="/security/signin.jsp"

   name="loginForm"

   path="/signin"

   scope="request"

   type="com.oreilly.struts.storefront.security.LoginAction"

   validate="true">

   <forward name="Success" path="/index.jsp" redirect="true"/>

   <forward name="Failure" path="/security/signin.jsp" redirect="true"/>

 </action>


posted on 2004-06-23 17:21  Johnny  阅读(759)  评论(0编辑  收藏  举报