`

struts2常用的基类

阅读更多

在编写SSH的项目中通常会获取request,response,sessinon对象或者需要需要从表单中获取参数值,如果项目中

 

包含上百个Action或者更多,那么我们就会编写许多类似的代码,可以通过编写一个通用的基类从而减少了重复的代码,提

 

高了编码的效率。

 

package com.wuhen.struts2.hello;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class BaseAction extends ActionSupport implements ServletRequestAware,
  ServletResponseAware, Preparable, SessionAware {

 private static final long serialVersionUID = -4871815191368438694L;

 protected HttpServletRequest request;

 protected HttpServletResponse response;

 protected PrintWriter printWriter;

 protected ActionContext actionContext;

 protected Map<String, Object> session;

 @Override
 public void prepare() throws Exception {
 }

 @Override
 public void setServletResponse(HttpServletResponse response) {
  this.response = response;
 }

 @Override
 public void setServletRequest(HttpServletRequest request) {
  this.request = request;
 }

 public PrintWriter getPrintWriter() throws IOException {
  return response.getWriter();
 }

 protected void initUTF8() {
  response.setContentType("text/html");
  response.setCharacterEncoding("UTF-8");
 }

 @Override
 public void setSession(Map<String, Object> session) {
  this.session = session;
 }

 public Object getSession(String key) {
  return session.get(key);
 }

 public void setSession(String name, Object value) {
  session.put(name, value);
 }

 protected ActionContext getActionContext() {
  return ActionContext.getContext();
 }

 protected Object getAttribute(String name) {
  return request.getAttribute(name);
 }

 public void setAttribute(String name, Object value) {
  request.setAttribute(name, value);
 }

 public String getParameter(String name) {
  return request.getParameter(name);
 }

 public String[] getParameterValues(String name) {
  return request.getParameterValues(name);
 }

 public String ajax(String content, String type) throws IOException {
  if (StringUtils.isEmpty(type)) {
   initUTF8();
  } else {
   response.setContentType(type + ";charset=UTF-8");
  }
  response.setHeader("Pragma", "No-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setDateHeader("Expires", 0);
  getPrintWriter().write(content);
  getPrintWriter().flush();
  return null;
 }

}

 

获取request,response,session都是通过实现对应的接口,在struts2中的ServletConfigInterceptor中拦截器中

进行了相关代码的封装。其部分源码如下:

 

   /**
     * Sets action properties based on the interfaces an action implements. Things like application properties,
     * parameters, session attributes, etc are set based on the implementing interface.
     *
     * @param invocation an encapsulation of the action execution state.
     * @throws Exception if an error occurs when setting action properties.
     */

 public String intercept(ActionInvocation invocation) throws Exception {
        final Object action = invocation.getAction();
        final ActionContext context = invocation.getInvocationContext();

 

        if (action instanceof ServletRequestAware) {

        //从contex对象中获取com.opensymphony.xwork2.dispatcher.HttpServletRequest对象
            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);

             //进行对象设置
            ((ServletRequestAware) action).setServletRequest(request);
        }

        if (action instanceof ServletResponseAware) {
            HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE);
            ((ServletResponseAware) action).setServletResponse(response);
        }

        if (action instanceof ParameterAware) {
            ((ParameterAware) action).setParameters((Map)context.getParameters());
        }

        if (action instanceof ApplicationAware) {
            ((ApplicationAware) action).setApplication(context.getApplication());
        }
       
        if (action instanceof SessionAware) {
            ((SessionAware) action).setSession(context.getSession());
        }
       
        if (action instanceof RequestAware) {
            ((RequestAware) action).setRequest((Map) context.get("request"));
        }

        if (action instanceof PrincipalAware) {
            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
            if(request != null) {
                // We are in servtlet environment, so principal information resides in HttpServletRequest
                ((PrincipalAware) action).setPrincipalProxy(new ServletPrincipalProxy(request));
            }
        }
        if (action instanceof ServletContextAware) {
            ServletContext servletContext = (ServletContext) context.get(SERVLET_CONTEXT);
            ((ServletContextAware) action).setServletContext(servletContext);
        }
        return invocation.invoke();
    }

 

 

对于这段代码是从context对象中获取的

 

 (HttpServletRequest) context.get(HTTP_REQUEST);

 

那么struts2是从何时将这些对象设置到context对象中的呢?

 

 

我们可以从struts2中的StrutsPrepareAndExecuteFilter中的接口入口进行分析

 

 

  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        try {
            prepare.setEncodingAndLocale(request, response);

            //设置相关的request和respon对象
            prepare.createActionContext(request, response);
            prepare.assignDispatcherToThread();
   if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
    chain.doFilter(request, response);
   } else {
    request = prepare.wrapRequest(request);
    ActionMapping mapping = prepare.findActionMapping(request, response, true);
    if (mapping == null) {
     boolean handled = execute.executeStaticResourceRequest(request, response);
     if (!handled) {
      chain.doFilter(request, response);
     }
    } else {
     execute.executeAction(request, response, mapping);
    }
   }
        } finally {
            prepare.cleanupRequest(request);
        }
    }

 

 

从上述的代码可知,在 prepare.createActionContext(request, response);对request,response对象进行了设置

 

该方法的源码如下:

 

public ActionContext createActionContext(HttpServletRequest request, HttpServletResponse response) {
        ActionContext ctx;
        Integer counter = 1;
        Integer oldCounter = (Integer) request.getAttribute(CLEANUP_RECURSION_COUNTER);
        if (oldCounter != null) {
            counter = oldCounter + 1;
        }
       
        ActionContext oldContext = ActionContext.getContext();

        

              if (oldContext != null) {
            // detected existing context, so we are probably in a forward
            ctx = new ActionContext(new HashMap<String, Object>(oldContext.getContextMap()));
        } else {
            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
            stack.getContext().putAll(dispatcher.createContextMap(request, response, null, servletContext));
            ctx = new ActionContext(stack.getContext());
        }
        request.setAttribute(CLEANUP_RECURSION_COUNTER, counter);
        ActionContext.setContext(ctx);
        return ctx;
    }

 

 

  //如果旧ActionContext 对象不为空,就oldContext.getContextMap()直接获取,否则获取ValueStack对象,将其

 

相关对象信息putAll(),该方法源码如下:

 public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
            ActionMapping mapping, ServletContext context) {

        // request map wrapping the http request objects
        Map requestMap = new RequestMap(request);

        // parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately
        Map params = new HashMap(request.getParameterMap());

        // session map wrapping the http session
        Map session = new SessionMap(request);

        // application map wrapping the ServletContext
        Map application = new ApplicationMap(context);

        Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);

        if (mapping != null) {
            extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
        }
        return extraContext;
    }

 

其中createContextMap方法是将request和response对象放入到map中。

 

public HashMap<String,Object> createContextMap(Map requestMap,
                                    Map parameterMap,
                                    Map sessionMap,
                                    Map applicationMap,
                                    HttpServletRequest request,
                                    HttpServletResponse response,
                                    ServletContext servletContext) {
        HashMap<String,Object> extraContext = new HashMap<String,Object>();
        extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
        extraContext.put(ActionContext.SESSION, sessionMap);
        extraContext.put(ActionContext.APPLICATION, applicationMap);

        Locale locale;
        if (defaultLocale != null) {
            locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
        } else {
            locale = request.getLocale();
        }

        extraContext.put(ActionContext.LOCALE, locale);
        //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode));

        extraContext.put(StrutsStatics.HTTP_REQUEST, request);
        extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
        extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);

        // helpers to get access to request/session/application scope
        extraContext.put("request", requestMap);
        extraContext.put("session", sessionMap);
        extraContext.put("application", applicationMap);
        extraContext.put("parameters", parameterMap);

        AttributeMap attrMap = new AttributeMap(extraContext);
        extraContext.put("attr", attrMap);

        return extraContext;
    }

 

通过对源码简单的分析,相信大家应该有所了解,如果需要深入的了解可以查看struts2相关的文档和源码。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1
0
分享到:
评论

相关推荐

    Web开发学习8Struts2基类封装

    在“Web开发学习8Struts2基类封装”这一主题中,我们将深入探讨Struts2框架的核心概念、基类封装以及如何通过源码分析来提升开发效率。 首先,Struts2框架的核心在于Action类,它是处理用户请求的入口点。在传统的...

    Struts2框架及注释和用法

    Struts2是一个强大的Java web开发框架,它基于MVC(Model-View-Controller)设计模式,为构建可维护性高、结构清晰的Web应用程序提供了一种解决方案。这个框架旨在简化开发过程,提高代码的可测试性和可重用性。下面...

    struts2常用包

    下面我们将深入探讨Struts2的常用包及其在开发中的作用。 1. **核心包(core)**: - `struts2-core`: 这是Struts2的基础包,包含核心的控制器、拦截器、结果类型等。它定义了`Action`接口和`ActionSupport`基类,...

    struts2常用jar包

    这个"struts2常用jar包"包含了Struts2框架的核心组件,使得开发者能够快速搭建基于Struts2的Web应用。下面我们将深入探讨Struts2框架的关键知识点。 1. **Struts2框架结构**:Struts2框架由多个模块组成,包括核心...

    Struts2教学视频

    Action类需要继承自Struts2提供的基类或实现特定接口,如`ActionSupport`。 **六、路径问题的说明** Struts2通过Action和Namespace来决定URL路径。Action的全名由Namespace和ActionName组成,例如`/admin/save`,...

    Struts2接口文档

    Struts2是一个强大的Java web应用程序开发框架,它基于Model-View-Controller(MVC)设计模式,旨在简化创建用户交互式、数据驱动的web应用的过程。这个“Struts2接口文档”是开发者的重要参考资料,提供了关于...

    struts1和struts2的区别

    Struts2提供了ActionSupport基类来简化Action的实现。Action本身可以是任何实现了特定接口的Java对象,甚至是普通的POJO。这种设计使得Struts2更加灵活,易于维护。 #### 架构模式 - **Struts1**: 在Struts1架构中...

    Struts2的视频学习代码

    Action类可以继承自Struts2提供的基类或实现特定的接口,如`com.opensymphony.xwork2.ActionSupport`。 3. **Result**:Result是Action执行后的一个状态,用于定义如何展示响应。Struts2支持多种Result类型,如JSP...

    struts2 ,struts2 demo

    开发者可以自定义Action类,通常会继承`org.struts2.interceptor.ActionSupport`,这个基类提供了错误处理、国际化等基础功能。 **5. Interceptors(拦截器)** 拦截器是Struts2的一个强大特性,可以在Action执行...

    Struts2与Struts1区别

    ActionSupport 类则提供了常用功能的实现,但 Action 接口并非强制,任何包含 execute 方法的普通 Java 对象(POJO)都能作为 Struts2 的 Action。 2. **线程模型**: - Struts1 的 Action 实例是单例的,这意味着...

    struts2核心文件

    Struts2是一个基于MVC(Model-View-Controller)设计模式的开源Java Web框架,它在Web应用开发中被广泛使用。Struts2的核心在于提供一个强大的、灵活的、可扩展的架构,使得开发者能够更方便地实现业务逻辑与表现层...

    struts2面试题

    Struts2 提供一个 ActionSupport 基类去实现常用的接口。Action 接口不是必须的,任何有 execute 标识的 POJO 对象都可以用作 Struts2 的 Action 对象。 4. Struts2 的线程模式: Struts2 Action 对象为每一个请求...

    struts2 与 struts1的区别

    此外,Struts2提供了一个预设的`ActionSupport`基类,该基类已经实现了常用的接口,如`Validateable`,这进一步简化了Action的开发过程。值得注意的是,在Struts2中,Action接口并不是强制性的,任何包含`execute`...

    Struts2-API+Struts2中文帮助文档

    Struts2是一个强大的Java web应用程序框架,用于构建和维护可扩展、高效且易于管理的Web应用。它基于Model-View-Controller(MVC)架构模式,提供了丰富的特性,包括动作调度、拦截器、结果类型、国际化支持以及与...

    struts1.0和struts2

    此外,Struts2的ActionSupport基类提供了对常用接口的实现,使得Action对象的创建更加灵活,不再局限于Action接口,任何具有execute方法的POJO对象都可以作为Struts2的Action对象。 线程模型方面,Struts1采用单例...

    Struts2+技术内幕——深入解析Struts2架构设计与实现原理

    本书《Struts2技术内幕——深入解析Struts2架构设计与实现原理》结合提供的《struts2基础.chm》资料,为我们提供了深入理解Struts2内部机制的机会。 首先,Struts2的核心在于它的拦截器(Interceptor)机制。拦截器...

    struts1和struts2区别

    - **Struts2**:Action类可以实现Action接口或者直接使用ActionSupport基类,也可以是任何具有`execute`方法的普通Java对象(POJO),这增加了代码的可定制性和可扩展性。 2. **线程模式**: - **Struts1**:...

    Struts2和Struts1的区别,详细点,主要说说Struts2

    - **Struts1**采用ActionForm模式来封装用户输入的数据,它通常继承自ActionForm基类,并且可以通过JavaBean的属性进行数据绑定。 - **Struts2**虽然不再强制要求使用ActionForm模式,但仍然支持类似的功能,例如...

Global site tag (gtag.js) - Google Analytics