`

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics