如果说ActionServlet是Struts框架的入口,RequestProcessor是消化过滤系统,则org.apache.struts.action.Action类可以说是整个框架的心脏。他是客户请求和业务操作的连接桥,也可以将其看作是业务操作的客户代理。
在前面对ReqeustProcessor类的学习中,我们了解到一旦确定并得到了一个action实例,ReqeustProcessor会调用action的execute()方法处理客户请求,你需要扩展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类
从前面的介绍我们已经了解到,Action的execute( )方法返回一个ActionForward对象。ActionForward对象是JSP页面、Java servlet等web资源的抽象表现。
ActionForward的用途是为了减少应用和物理资源(JSP页面,Java servlet)的耦合,物理资源只需要在配置文件中指定(利用name,path属性和forward元素的redirect属性),而不是在代码中指定。RequestDispatcher利用ActionForward来执行重定向操作。
要在Action中返回一个ActionForward对象,你可以动态地创建一个ActionForward 对象,不过更为通用的解决方案是,通过在Struts配置文件中进行action映射,然后通过关键字去查找一个ActionForward 。下面是代码示例:
return mapping.findForward( "Success" );
上面的代码中,"Success"作为参数被传递到ActionMapping的findFoward( )方法中,findFoward( )方法在Struts配置文件的global-forwards区域,以及被调用的action的forward元素中查找名字和"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>
本文地址:http://com.8s8s.com/it/it16588.htm