posts - 14, comments - 22, trackbacks - 0, articles - 4
  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理

从分页来体验Struts的诟病

Posted on 2006-09-09 11:24 誰伴我闖蕩 阅读(3167) 评论(0)  编辑  收藏

我曾经介绍过自己构建的分页程序,在那个程序中,我们把分页显示的数据放到了Action的成员中,而没有放在execute函数中,如果把他放到execute函数中会产生什么效果呢?由于我们没有采用页码来确定数据,而是单纯的调用下一页来完成的,所以当变量放到execute中时我们每次访问到的都只会是第一页,这就是Struts的诟病,单用户每次访问都会为用户创建一个新的线程,而非Servlet为每用户单独开辟一个线程,所以才会产生以上的问题?

那问题该如何解决呢?

1.用页码来区分需要显示的数据更有效
2.Spring可以解决这个诟病

合二为一来介绍一下吧:

/**
 * Page.java
 * @author baputista
 * Email:
baputista@hotmail.com
 * 2006-8-26 0:05:36
 */

package subject.bean;

import java.util.ArrayList;
import java.util.List;

public class Page
{
 private int current = 1; //当前页码
 private int nextPage = 0; //下一页码
 private int previousPage = 0;//上一页码
 private int total = 0;//总的数据
 private int pages = 0;//总页数
 private int each = 5;//每页数据
 private int start = 0;//当前页的起始数据
 private int end = 0;//当前页的结束数据
 private boolean next = false;//是否存在下一页
 private boolean previous = false;//是否存在上一页
 private List list = null;
//需要显示的数据

 public Page( List list, int each )//以需要显示的数据和每页要显示的数据为参数进行初始化
 {
  this.list = list;
  this.each = each;
  total = list.size();//总的数据等于List的大小
  if ( total % each == 0 )//总页数和没页显示的数据可以整除,则为总页数
   pages = total / each;
  else
   pages = total / each + 1;//否则就需要加上一页了
  if ( current >= pages )
  {
   next = false;//判断是否有下一页
  }
  else
  {
   next = true;
   nextPage = current + 1;//有,还得算出来下一页是多少呢!
  }
  if ( total < each )
  {
   start = 0;//这页显示多少数据啊?如果是最后一页,只显示整除后的余数了
   end = total;
  }
  else
  {
   start = 0;//否则要显示每页需要显示的数据数
   end = each;
  }
 }

 public int getCurrent()
 {
  return current;
 }

 public boolean isNext()
 {
  return next;
 }

 public boolean isPrevious()
 {
  return previous;
 }

 public int getPages()
 {
  return pages;
 }

 public int getTotal()
 {
  return total;
 }

 public int getNextPage()
 {
  return nextPage;
 }

 public int getPreviousPage()
 {
  return previousPage;
 }

 @SuppressWarnings ( "unchecked" )
 public List get( int page )//获取指定页码的List
 {
  if ( page > 0 && page <= pages )
  {
   current = page;//page在有效范围内则为当前页
  }
  if ( ( current - 1 ) > 0 )//计算上一页是否存在以及值
  {
   previous = true;
   previousPage = current - 1;
  }
  else
  {
   previous = false;
  }
  if ( current >= pages )//计算下一页是否存在以及值
  {
   next = false;
  }
  else
  {
   next = true;
   nextPage = current + 1;
  }
  if ( page * each < total )//计算显示的记录在List中的位置
  {
   end = current * each;
   start = end - each;
  }
  else
  {
   end = total;
   start = each * ( pages - 1 );
  }
  List gets = new ArrayList();//把显示的数据放到一个新的List里
  for ( int i = start; i < end; i++ )
  {
   gets.add( list.get( i ) );
  }
  return gets;
 }
}

上面的Page Bean比那个就简略的很多,我们再来看看Action怎么来做?

public class AdminAction extends BaseAction
{
 private AdminManager mgr;

 public void setAdminManager( AdminManager mgr )
 {
  this.mgr = mgr;
 }

public ActionForward execute( ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response )
   throws Exception
 {
  Integer pageId = getInt( request, "page" );
  Page page = null;
  List rs =mgr.getStudents();
   if ( rs != null && rs.size() != 0 )
   {
    page = new Page( rs, 10 );
    request.setAttribute( "students", page.get( pageId ) );
   }
   request.setAttribute( "search", Select.studentSearch() );
  }  
  request.setAttribute( "page", page );
  return mapping.findForward("student");
 }

}

这样我们就可以把分页对象和List放到Execute中了,在这里我们把业务逻辑对象AdminManager的实例mgr声明成了bean的形式,这样可以在Spring中利用ioc来注入:

Struts的声明:

<action path="/admin" type="org.springframework.web.struts.DelegatingActionProxy" />

Spring中的声明:

<!-- 业务逻辑 -->
 <bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager" ref="transactionManager" />
  <property name="transactionAttributes">
   <props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="remove*">PROPAGATION_REQUIRED</prop>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
   </props>
  </property>
 </bean>

 <bean id="adminManager" parent="txProxyTemplate">
  <property name="target">
   <bean class="subject.service.impl.AdminManagerImpl">
    <property name="dao" ref="dao" />
   </bean>
  </property>
 </bean>

<bean name="/admin/admin" class="subject.web.action.AdminAction" singleton="false">
  <property name="adminManager">
   <ref bean="adminManager" />
  </property>
 </bean>

从而实现了Struts和Spring的完美暇接,singleton="false"从而可以解决单例的诟病!


只有注册用户登录后才能发表评论。


网站导航:
 
有事在这里给我留言噢!