struts2中的BaseAction作用等相关问题

来源:互联网 发布:淘宝账期延长十五天 编辑:程序博客网 时间:2024/06/03 15:16
@ParentPackage("default")@Namespace("/")@Scope("prototype")public class BaseAction extends ActionSupport {    private static final long serialVersionUID = 5468737591027540687L;    /**     * 将对象转换成JSON字符串,并响应回前台()     *      * @param object     * @throws IOException     */    public void writeJson(Object object) {        try {            String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm");            ServletActionContext.getRequest().getSession();            ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");            ServletActionContext.getResponse().getWriter().write(json);            ServletActionContext.getResponse().getWriter().flush();            ServletActionContext.getResponse().getWriter().close();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     *      * @param object     */    public void writeJsonOut(Object object){        OutputStream outputStream=null;        String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm");        ServletActionContext.getRequest().getSession();        ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");        HttpServletResponse response = ServletActionContext.getResponse();        byte[] jsonby;        try {            jsonby = json.toString().getBytes("utf-8");            response.setContentLength(jsonby.length);            outputStream=response.getOutputStream();            outputStream.write(jsonby);            outputStream.flush();            outputStream.close();        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * 参数是已经封装好的json集合     * @param map     */    public void writeJson(Map<String, Object>map) {        OutputStream outputStream=null;        try {            HttpServletRequest request = ServletActionContext.getRequest();            HttpServletResponse response = ServletActionContext.getResponse();            request.setCharacterEncoding("UTF-8");            response.setContentType("text/json;charset=utf-8");            request.getSession();            byte[] jsonby=map.toString().getBytes("utf-8");            response.setContentLength(jsonby.length);            outputStream=response.getOutputStream();            outputStream.write(jsonby);            outputStream.flush();            outputStream.close();        } catch (Exception e) {            e.printStackTrace();        }finally{            if (outputStream!=null) {                try {                    outputStream.close();                } catch (Exception e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }}

struts中的action一般都是继承ActionSupport的,只是里面增加一些公用的属性和方法,例如获取httpRequest,又比如获取用户信息的方法,完全是自己封装的。

这样做避免每个action甚至每个方法都要写这些,增加了代码的复用性。


web项目中对Action层进行公共方法的抽取放入到BaseAction中:

在项目启动的时候,struts过滤器已经把jsp常用内置对象和map集合存入到了ActionContext和值栈(ValueStack)中。如果实现了XXXAware接口,就会从相应的ActionContext中获取对应的map进行传入(通过拦截器实现: servletConfig 这个拦截器是在struts-default.xml中配置的)

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

2.CategoryAction.java中的Category赋值方式:显示层页面通过拦截器然后由OGNL表达式实现值的注入的下面进行具体步骤的分析。

在CategoryAction.java中定义一个语句,使其显示值栈中的栈顶内容或根节点内容

CategoryAction.javapublic String query(){   System.out.println(ActionContext.getContext().getValueStack().getRoot());}

3.让CategoryAction实现数据模型驱动接口

public class CategoryAction extends BaseAction implements ModelDriven{ public Object getModel() { //它会把得到的值压入栈顶中(删除category对象的setter、getter方法)        Category category = new Category() ;        return category; }public String update(){        System.out.println(ActionContext.getContext().getValueStack().getRoot());        System.out.println("==update==") ;        System.out.println(categoryService) ; //如果还没有与spring整合,所以输出为null        System.out.println(category) ;        //    categoryService.update(category);        return "index" ;    }}---------- index.jsp<a href="${pageContext.request.contextPath}/category_update.action?id=1&type=儿童休闲&hot=false">ModelDriven驱动程序测试</a> ----------如果修改action     CategoryAction.javaprivate Integer id ;    private Integer id1 ;    public void setId1(Integer id1) {        this.id1 = id1;    }public String update(){        System.out.println(ActionContext.getContext().getValueStack().getRoot());        System.out.println("==update==") ;        System.out.println(category) ;        System.out.println(id) ;        System.out.println(id1) ;        return "index" ;    }   index.jsp<a href="${pageContext.request.contextPath}/category_update.action?id=1&type=儿童休闲&hot=false&id1=123">ModelDriven驱动程序测试</a> 此时id=null, id1=123

ModelDriven 同样是通过拦截器(ModelDrivenInterceptor)实现的

ModelDrivenInterceptor.java 
public String intercept(ActionInvocation invocation) throws Exception {        Object action = invocation.getAction();        if (action instanceof ModelDriven) {            ModelDriven modelDriven = (ModelDriven) action;            ValueStack stack = invocation.getStack();            Object model = modelDriven.getModel();            if (model !=  null) {             stack.push(model);            }        }        return invocation.invoke();    }

4.moderDriven是所有的action都可以使用的,所以可以把modelDriven放到baseAction中去同时要使用到泛型

public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {protected T model ; public T getModel() {  ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass() ;  Class clazz = (Class)type.getActualTypeArguments()[0] ;  try {   model = (T)clazz.newInstance() ;  } catch (InstantiationException e) {   e.printStackTrace();  } catch (IllegalAccessException e) {   e.printStackTrace();  }  return model; }}

5.然后在简化CategoryAction.java,这样就只剩下service层的类对象了。

CategoryAction.javapublic class CategoryAction extends BaseAction<Category>{ private CategoryService categoryService ; public void setCategoryService(CategoryService categoryService){  this.categoryService = categoryService ; } public String update(){  System.out.println(ActionContext.getContext().getValueStack().getRoot());  System.out.println("==update==") ;  System.out.println(model) ;  return "index" ; } public String save(){  System.out.println("==save==") ;  System.out.println(categoryService) ; //如果还没有与spring整合,所以输出为null  return "index" ; } public String query(){  System.out.println(ActionContext.getContext().getValueStack().getRoot());  request.put("categoryList", categoryService.query()) ;  session.put("categoryList", categoryService.query()) ;  application.put("categoryList", categoryService.query()) ;  return "index" ; }}
 BaseAction.java public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> { protected Map<String,Object> request ; protected Map<String,Object> session ; protected Map<String,Object> application ; //以下都是通过ActionContex传递过来的 public void setApplication(Map<String, Object> application) {  this.application = application ; } public void setSession(Map<String, Object> session) {  this.session = session ; } public void setRequest(Map<String, Object> request) {  this.request = request ; } protected T model ; public T getModel() {  ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass() ;  Class clazz = (Class)type.getActualTypeArguments()[0] ;  try {   model = (T)clazz.newInstance() ;  } catch (InstantiationException e) {   e.printStackTrace();  } catch (IllegalAccessException e) {   e.printStackTrace();  }  return model; }}
  1. 为了进一步简化,现在连CategoryAction中的service也放到baseAction中去。
protected CategoryService categoryService ; protected AccountService  accountService; public void setAccountService(AccountService accountService){  this.accountService = accountService ; } public void setCategoryService(CategoryService categoryService){  this.categoryService = categoryService ; }

为了实现在baseAction中依赖spring注入,需要配置

     applicationContext-action.xml
<bean id="categoryAction" class="cn.it.shop.action.CategoryAction" scope="prototype" parent="baseAction"/>    <bean id="baseAction" class="cn.it.shop.action.BaseAction" scope="prototype">        <property name="categoryService" ref="categoryService"/>        <property name="accountService" ref="accountService"/></bean>

BaseAction定义好之后现在定义其他action实现类就变得简单了,下面定义

AccountAction.java
public class AccountAction extends BaseAction<Account>{ public String query(){  System.out.println(model);  return "index" ; }}
定义    index.jsp<a href="account_query.action?id=10&login=zz">account</a>  <br>  ${id }<br>${login }<br>${name}<br>${pass }<br> 

然后定义struts的配置文件

    struts.xml<action name="account_*" class="accountAction" method="{1}">            <result name="index">/index.jsp</result></action> 

然后再定义spring的配置文件

applicationContext-action.xml
<bean id="accountAction" class="cn.it.shop.action.AccountAction" scope="prototype" parent="baseAction"/>