Strus2 + pager-taglib 实现分页总结

尚学堂的OA 中实现时用Filter来为ThreadLocal对象的PagerSize和Offset设值.这样就可以动态加入值而不用修改manager层的代码逻辑,这是AOP(面向切面编程)的思想.

经本人测试直接把代码移植过来后在Struts1.x中使用没有问题,而在Strus2中使用时出现异常:ognl.OgnlException: target is null for setProperty(null, “offset”, [Ljava.lang.String;@c3dfb9),查阅相关资料,有两种方法,第一种方法:在Struts2中加入修改配置webwork.devMode = false;第二种方法是:写一段这样的代码:     HttpServletRequest request=ServletActionContext.getRequest();
if(request.getParameter(“pager.offset”)==null){
offset=0;
}else{
offset=Integer.parseInt(request.getParameter(“pager.offset”));
System.out.println(“offset:”+offset);
}

经过分析第一种方法显然是在规避问题,根本没有解决.第二种方法加入后代码具有侵入性,这样就失去了AOP编程无侵入性的意义.我现在提供第三种方法:在原来的Action中加入这样一句:public Pager pager=new Pager();建一个Pager类,其中有两个变量pagerSize和offset并实现getter和setter方法;原因很简单提示一下,Sturts2支持Pojo.

本人在测试时发现使用Filter时是不能精确定位到列表显示的方法和页面上的,这样不是造成很多的不需要的重复吗.能不能精确定位到显示列表的方法上呢?

一开始想到了JDK的动态代理来实现,但这样需要在客户端调用时使用代理类.后来想到了使用Spring的AOP编程.这样确实能够实现刚才的想法.后来想到了使用Struts2的拦截器,拦截器是层层嵌套的能和Struts2很好的配合.OK,就使用拦截器了.去掉原来的Filter,改用PagerInterceptor代码如下:

 

  1. package com.ssh.utile;
  2. import javax.servlet.http.HttpServletRequest;
  3. import org.apache.struts2.ServletActionContext;
  4. import com.opensymphony.xwork2.ActionInvocation;
  5. import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
  6. public class PagerInterceptor extends MethodFilterInterceptor {
  7.     public static final String PAGE_SIZE_NAME = “ps”;
  8.     @Override
  9.     protected String doIntercept(ActionInvocation invocation) throws Exception {
  10.         String result=””;
  11.         try {
  12.            //在调用真正的方法之前在线程内设置pagesize和offset.
  13.            HttpServletRequest httpRequest = ServletActionContext.getRequest();
  14.            SystemContext.setOffset(getOffset(httpRequest));
  15.            SystemContext.setPagesize(getPagesize(httpRequest));
  16.            //调用真正的方法.
  17.            result=invocation.invoke();
  18.         } catch (Exception e) {
  19.            e.printStackTrace();
  20.            throw new RuntimeException(“分页时传入参数出错!”);
  21.         }finally {
  22.            //不管是否调用真正的方法,都要移除线程内的ThreadLocal对象.
  23.            SystemContext.removeOffset();
  24.            SystemContext.removePagesize();
  25.         }
  26.        return result;
  27.     }
  28.     private int getOffset(HttpServletRequest request) {
  29.        int offset = 0;
  30.        try {
  31.         offset = Integer.parseInt(request.getParameter(“pager.offset”));
  32.        } catch (Exception ignore) {
  33.        }
  34.        return offset;
  35.     }
  36.     private int getPagesize(HttpServletRequest httpRequest) {
  37.        // 首先判断request中是否有pagesize参数,如果有这个参数,证明客户端正在请求改变每页显示的行数
  38.            String psvalue = httpRequest.getParameter(PAGE_SIZE_NAME);
  39.            if (psvalue != null && !psvalue.trim().equals(“”)) {
  40.                 Integer ps = 0;
  41.                 try {
  42.                     ps = Integer.parseInt(psvalue);
  43.                 } catch (Exception e) {
  44.                 }
  45.                 if (ps != 0) {
  46.                     httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, ps);
  47.                 }
  48.            }
  49.            // 判断当前session中是否有pagesize的值
  50.            Integer pagesize = (Integer) httpRequest.getSession().getAttribute(PAGE_SIZE_NAME);
  51.            if (pagesize == null) {
  52.                 Integer pageSize= Integer.parseInt(ServletActionContext.getServletContext().getInitParameter(“pageSize”));//这里没有用try拦截异常,以为在它的上层拦截了异常.此处进行了每页记录数可配置的扩展功能.
  53.                 httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, pageSize);
  54.                 return pageSize;
  55.            }
  56.            return pagesize;
  57.         }
  58.     }

在Struts2的配置文件中配置如下:

 

 

  1.              <interceptors>
  2.     <interceptor name=”pager” class=”com.ssh.utile.PagerInterceptor” />
  3.     <interceptor-stack name=”myInterceptor”>
  4.         <interceptor-ref name=”pager”>
  5.             <!–<param name=”includeMethods”>queryUser</param>–>
  6.         </interceptor-ref>
  7.         <interceptor-ref name=”defaultStack”></interceptor-ref>
  8.     </interceptor-stack>
  9. </interceptors>

 

  1.      <action name=”user” class=”userAction” >
  2.     <result name=”showQuery”>/showQuery.jsp</result>
  3.     <result name=”error”>/error.jsp</result>
  4.     <result name=”showUpdate”>/update.jsp</result>
  5.     <result name=”success”>/pub_add_success.jsp</result>
  6.     <interceptor-ref name=”myInterceptor”></interceptor-ref>
  7. </action>

在web.xml中加入下面的配置:

 

 

  1. <context-param>
  2.    <param-name>page_size</param-name>
  3.    <param-value>5</param-value>
  4. </context-param>

再加一句,使用Spring的AOP编程也是完全可以实现的.

标签