web day20 单表练习之分页,java web监听器, 国际化

分页

 

什么是分页

 

例:

第N页/共M页 首页 上一页 1 2 3 4 5 6 7 8 9 10 下一页 尾页 口 go

分页的优点:只查询一页,不用查询所有页

 

分页数据

 

页面的数据都是由Servlet传递来的

Servlet:

   1.当前页面页数:pageCode,pc(没有传递按默认第一页)

   2.总页数:totalPages,tp(总记录数/每页记录数)

   3.总记录数:totalRecored,tr(dao来获取,select count(*) fromt_customer)\

   4.每页记录数:pageSize,ps

   5.当前页的记录:beanList

  6.url:保存/项目名,保存/Servlet路径,保存?后面的参数(既保留多条件查询的条件)

 
分页Bean的设计

 

页数据总要在各层之间来回的传递,这些分页数据封装到一个javabean中,

它就叫分页Bean,例如:PageBean

 

代码

 

public class PageBean<T> {
	private int pc;// 当前页码page code
//	private int tp;// 总页数total page
	private int tr;// 总记录数total record
	private int ps;// 每页记录数page size
	private List<T> beanList;// 当前页的记录
	
	private String url;//它就是url后的条件!

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public int getPc() {
		return pc;
	}

	public void setPc(int pc) {
		this.pc = pc;
	}

	/**
	 * 计算总页数
	 * @return
	 */
	public int getTp() {
		// 通过总记录数和每页记录数来计算总页数
		int tp = tr / ps;
		return tr%ps==0 ? tp : tp+1;
	}

//	public void setTp(int tp) {
//		this.tp = tp;
//	}

	public int getTr() {
		return tr;
	}

	public void setTr(int tr) {
		this.tr = tr;
	}

	public int getPs() {
		return ps;
	}

	public void setPs(int ps) {
		this.ps = ps;
	}

	public List<T> getBeanList() {
		return beanList;
	}

	public void setBeanList(List<T> beanList) {
		this.beanList = beanList;
	}
}

 

 

分页在各层中的处理

 

Servlet传递pc,设定ps

由dao层返回一个PageBean

保存到域中再由页面显示

 


图2

 

 

 

显示分页页码列表

 

1 2 3 4 5 [6] 7 8 9 10

↑最多显示多少个页码!定为10

↑当前页,在页码列表中的位置,定为6

 

↑只需要当前页码来定出来页码列表

↓定下来页码列表只需要两样数据

  1.begin

  2.end

 

10 11 12 13 14 [15] 16 17 18 19

需要使用pc来推算出begin和end

begin = pc – 5

end = pc + 4

公式:

*如果总页数<=10(列表长度),那么begin=1,end=总页数

*使用公式计算;begin=pc-5, end=pc + 4

*头溢出:当begin<1时,让begin=1

*尾溢出:当end>${tp}时,让end=${tp}

 

代码

...
JSP
<%-- 
给出分页的链接
 --%>
<center>
第${pb.pc }页/共${pb.tp }页

<a href="${pb.url }&pc=1">首页</a>
<c:if test="${pb.pc > 1 }">
<a href="${pb.url }&pc=${pb.pc-1}">上一页</a>
</c:if>

<%-- 计算begin、end --%>
<c:choose>
	<%-- 如果总页数不足10页,那么把所有的页数都显示出来! --%>
	<c:when test="${pb.tp <= 10 }">
		<c:set var="begin" value="1" />
		<c:set var="end" value="${pb.tp }" />
	</c:when>
	<c:otherwise>
		<%-- 当总页数>10时,通过公式计算出begin和end --%>
		<c:set var="begin" value="${pb.pc-5 }" />
		<c:set var="end" value="${pb.pc+4 }" />	
		<%-- 头溢出 --%>
		<c:if test="${begin < 1 }">
			<c:set var="begin" value="1" />
			<c:set var="end" value="10" />
		</c:if>	
		<%-- 尾溢出 --%>
		<c:if test="${end > pb.tp }">
			<c:set var="begin" value="${pb.tp - 9 }" />
			<c:set var="end" value="${pb.tp }" />
		</c:if>	
	</c:otherwise>
</c:choose>
<%-- 循环遍历页码列表 --%>
<c:forEach var="i" begin="${begin }" end="${end }">
	<c:choose>
		<c:when test="${i eq pb.pc }">
			[${i }]
		</c:when>
		<c:otherwise>
			<a href="${pb.url }&pc=${i}">[${i }]</a>	
		</c:otherwise>
	</c:choose>
	
</c:forEach>


<c:if test="${pb.pc < pb.tp }">
<a href="${pb.url }&pc=${pb.pc+1}">下一页</a>
</c:if>
<a href="${pb.url }&pc=${pb.tp}">尾页</a>
</center>
  </body>
</html>

 

 
在超链接中要保留参数

 

当使用多条件查询后,然后在点击第2 页时,这个第2页超链接没有条件了,

所以会丢失条件,所以我们需要在页面上的所有链接都要保留条件

要把条件以一个字符串的形式保存到PageBean的url中!这个任务交给Servlet

 

代码

web层相关

	public String findAll(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/*
		 * 1. 获取页面传递的pc
		 * 2. 给定ps的值
		 * 3. 使用pc和ps调用service方法,得到PageBean,保存到request域
		 * 4. 转发到list.jsp
		 */
		int pc = getPc(request);//得到pc
		int ps = 10;//给定ps的值,第页10行记录
		PageBean<Customer> pb = customerService.findAll(pc, ps);//传递pc, ps给Service,得到PageBean
		
		// 设置url
		pb.setUrl(getUrl(request));
		
		request.setAttribute("pb", pb);//保存到request域中
		return "f:/list.jsp";//转发到list.jsp
	}
	
	/**
	 * 获取pc
	 * @param request
	 * @return
	 */
	private int getPc(HttpServletRequest request) {
		/*
		 * 1. 得到pc
		 *   如果pc参数不存在,说明pc=1
		 *   如果pc参数存在,需要转换成int类型即可
		 */
		String value = request.getParameter("pc");
		if(value == null || value.trim().isEmpty()) {
			return 1;
		}
		return Integer.parseInt(value);
	}

	public String query(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//		System.out.println(getUrl(request));
		/*
		 * 0. 把条件封装到Customer对象中
		 * 1. 得到pc
		 * 2. 给定ps
		 * 3. 使用pc和ps,以及条件对象,调用service方法得到PageBean
		 * 4. 把PageBean保存到request域中
		 * 5. 转发到list.jsp
		 */
		// 获取查询条件
		Customer criteria = CommonUtils.toBean(request.getParameterMap(), Customer.class);
		
		/*
		 * 处理GET请求方式编码问题!
		 */
		criteria = encoding(criteria);
		
		int pc = getPc(request);//得到pc
		int ps = 10;//给定ps的值,第页10行记录
		PageBean<Customer> pb = customerService.query(criteria, pc, ps);
		
		// 得到url,保存到pb中
		pb.setUrl(getUrl(request));
		
		request.setAttribute("pb", pb);
		return "f:/list.jsp";
	}
	
	/**
	 * 处理四样
	 * @param criteria
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	private Customer encoding(Customer criteria) throws UnsupportedEncodingException {
		String cname = criteria.getCname();
		String gender = criteria.getGender();
		String cellphone = criteria.getCellphone();
		String email = criteria.getEmail();
		
		if(cname != null && !cname.trim().isEmpty()) {
			cname = new String(cname.getBytes("ISO-8859-1"), "utf-8");
			criteria.setCname(cname);
		}
		
		if(gender != null && !gender.trim().isEmpty()) {
			gender = new String(gender.getBytes("ISO-8859-1"), "utf-8");
			criteria.setGender(gender);
		}
		
		if(cellphone != null && !cellphone.trim().isEmpty()) {
			cellphone = new String(cellphone.getBytes("ISO-8859-1"), "utf-8");
			criteria.setCellphone(cellphone);
		}
		
		if(email != null && !email.trim().isEmpty()) {
			email = new String(email.getBytes("ISO-8859-1"), "utf-8");
			criteria.setEmail(email);
		}
		return criteria;
	}

	/**
	 * 截取url
	 *   /项目名/Servlet路径?参数字符串
	 * @param request
	 * @return
	 */
	private String getUrl(HttpServletRequest request) {
		String contextPath = request.getContextPath();//获取项目名
		String servletPath = request.getServletPath();//获取servletPath,即/CustomerServlet
		String queryString = request.getQueryString();//获取问号之后的参数部份
		
		//  判断参数部份中是否包含pc这个参数,如果包含,需要截取下去,不要这一部份。
		if(queryString.contains("&pc=")) {
			int index = queryString.lastIndexOf("&pc=");
			queryString = queryString.substring(0, index);
		}
		
		return contextPath + servletPath + "?" + queryString;
	}
}



dao层相关

	/**
	 * 查询所有
	 * @return
	 */
	public PageBean<Customer> findAll(int pc, int ps) {
		try {
			/*
			 * 1. 他都PageBean对象pb
			 * 2. 设置pb的pc和ps
			 * 3. 得到tr,设置给pb
			 * 4. 得到beanList,设置给pb
			 * 5. 返回pb
			 */
			PageBean<Customer> pb = new PageBean<Customer>();
			pb.setPc(pc);
			pb.setPs(ps);
			/*
			 * 得到tr
			 */
			String sql = "select count(*) from t_customer";
			Number num = (Number)qr.query(sql, new ScalarHandler());
			int tr = num.intValue();
			pb.setTr(tr);
			/*
			 * 得到beanList
			 */
			sql = "select * from t_customer order by cname limit ?,?";
			List<Customer> beanList = qr.query(sql, 
					new BeanListHandler<Customer>(Customer.class), 
					(pc-1)*ps, ps);
			pb.setBeanList(beanList);
			return pb;
		} catch(SQLException e) {
			throw new RuntimeException(e);
		}
	}
//多条件查询 带分页
	public PageBean<Customer> query(Customer criteria, int pc, int ps) {
		try {
			/*
			 * 1. 创建PageBean对象 
			 * 2. 设置已有的属性,pc和ps
			 * 3. 得到tr
			 * 4. 得到beanList
			 */
			/*
			 * 创建pb,设置已有属性
			 */
			PageBean<Customer> pb = new PageBean<Customer>();
			pb.setPc(pc);
			pb.setPs(ps);
			
			/*
			 * 得到tr
			 */
			
			/*
			 * 1. 给出一个sql语句前半部
			 */
			StringBuilder cntSql = new StringBuilder("select count(*) from t_customer");
			StringBuilder whereSql = new StringBuilder(" where 1=1");
			/*
			 * 2. 判断条件,完成向sql中追加where子句
			 */
			/*
			 * 3. 创建一个ArrayList,用来装载参数值
			 */
			List<Object> params = new ArrayList<Object>();
			String cname = criteria.getCname();
			if(cname != null && !cname.trim().isEmpty()) {
				whereSql.append(" and cname like ?");
				params.add("%" + cname + "%");
			}
			
			String gender = criteria.getGender();
			if(gender != null && !gender.trim().isEmpty()) {
				whereSql.append(" and gender=?");
				params.add(gender);
			}
			
			String cellphone = criteria.getCellphone();
			if(cellphone != null && !cellphone.trim().isEmpty()) {
				whereSql.append(" and cellphone like ?");
				params.add("%" + cellphone + "%");
			}
			
			String email = criteria.getEmail();
			if(email != null && !email.trim().isEmpty()) {
				whereSql.append(" and email like ?");
				params.add("%" + email + "%");
			}
			
			/*
			 * select count(*) .. + where子句
			 * 执行之
			 */
			Number num = (Number)qr.query(cntSql.append(whereSql).toString(), 
					new ScalarHandler(), params.toArray());
			int tr = num.intValue();
			pb.setTr(tr);
			
			/*
			 * 得到beanList
			 */
			StringBuilder sql = new StringBuilder("select * from t_customer");
			// 我们查询beanList这一步,还需要给出limit子句
			StringBuilder limitSql = new StringBuilder(" limit ?,?");
			// params中需要给出limit后两个问号对应的值
			params.add((pc-1)*ps);
			params.add(ps);
			// 执行之
			List<Customer> beanList = qr.query(sql.append(whereSql).append(limitSql).toString(), 
					new BeanListHandler<Customer>(Customer.class), 
					params.toArray());
			pb.setBeanList(beanList);
			
			return pb;
			
		} catch(SQLException e) {
			throw new RuntimeException(e);
		}
	}
}



JavaWeb监听器

 

三大组件:Servlet/Listener/Filter

 

Listener:监听器

1.初次相见:AWT

2.二次相见:SAX

 

监听器:

  它是一个接口,内容由我们来实现

  它需要注册,例如注册在按钮上

  监听器中的方法,会在特殊事件发生时被调用

 

观察者:

  例:

事件源:小偷

事件:偷东西

监听器:警察

监听器中的方法:抓捕

 

 

JavaWeb中的监听器

 

事件源:三大域-ServletContext/HttpSession/ServletRequest

 

ServletContext

   生命周期监听:ServletContextListener

   方法:2个,一个在出生时调用,一个在死亡时调用

      void contextInitialized(ServletContextEvent sce):创建SErvletcontext时

       void contextDestroyed(ServletContextEvent sce):销毁Servletcontext时

 

   属性监听:ServletContextAttributeListener

   方法:3个,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

       void attributeAdded(ServletContextAttributeEvent event):添加属性时;

       void attributeReplaced(ServletContextAttributeEvent event):替换属性时

       void attributeRemoved(ServletContextAttributeEvent event):移除属性时

 

HttpSession

   生命周期监听:HttpSessionListener,

   两个方法,一个在出生时调用,一个在死亡时调用

       void sessionCreated(HttpSessionEvent se):创建session时

       void sessionDestroyed(HttpSessionEvent se):销毁session时

 

   属性监听:HttpSessioniAttributeListener,

   三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

       void  attributeAdded(HttpSessionBindingEvent event):添加属性时;

       void  attributeReplaced(HttpSessionBindingEvent event):替换属性时

       void  attributeRemoved(HttpSessionBindingEvent event):移除属性时

 

ServletRequest

   生命周期监听:ServletRequestListener,

   两个方法,一个在出生时调用,一个在死亡时调用;

       void  requestInitialized(ServletRequestEvent sre):创建request时

       void  requestDestroyed(ServletRequestEvent sre):销毁request时

 

   属性监听:ServletRequestAttributeListener,

   三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个是在移除属性时调用。

       void  attributeAdded(ServletRequestAttributeEvent srae):添加属性时

       void  attributeReplaced(ServletRequestAttributeEvent srae):替换属性时

       void  attributeRemoved(ServletRequestAttributeEvent srae):移除属性时

 

 

javaWeb中完成编写监听器:

1.写一个监听器类:要求必须去实现某个监听器接口;

2.注册,是在web.xml中配置来完成注册

 

事件对象及方法

 

ServletContextEvent:

       ServletContext   getServletContext()

HttpSessionEvent:

       HttpSession   getSession()

ServletRequest:

       ServletContext   getServletContext();

       ServletReques   getServletRequest();

ServletContextAttributeEvent:

       ServletContext   getServletContext();

       String  getName():获取属性名

       Object  getValue():获取属性值

HttpSessionBindingEvent:同上/获取相应对象/属性名/属性值

ServletRequestAttributeEvent :同上/获取相应对象/属性名/属性值

 

感知监听(都与HttpSession相关)

 

区别:

   它用来添加到JavaBean上,而不是添加到三大域上!

   这两个监听器都不需要在web.xml中注册

 

HttpSessionBindingListener:添加到javabean上,javabean就知道自己是否添加到session中了。

HttpSessionActivationListener:Tomcat钝化/活化session时→保存到硬盘/从硬盘加载到内存,javabean可以感知到相关操作

 

钝化和活化

 

其实就是使用序列化和反序列化技术把session从内存保存到硬盘,和把session从硬盘加载到内存

如果javabean没有实现Serializable(序列化)接口,当session钝化时就不会钝化,

而是把Person从session中移除再钝化!这也说明session活化后,session中就不在有javabean对象了

 

国际化

 

什么是国际化:国际化就是可以把页面中的中文变成英文。

理解国际化:想把页面文字修改就不能硬编码 ,而是把相应文字编成变量

 

Locale类

       newLocale(“zh”, “CN”);

       newLocale(“en”, “US”);

一个Locale对象表示的就是语言和国家

 

ResourceBundle类

 

ReourceBundle类用来获取配置文件中的内容

 

ResourceBundle的getBundle()方法需要两个参数:

1.配置文件的基本名称

2.Locale

getBundle()方法会通过两个参数来锁定配置文件

 

 

页面国际化


 

NumberFormat

NumberFormat类用来对数字进行格式化:需要使用Stringformat(double)方法

 

DateFormat

DateFormat类用来对日期进行格式化:需要使用Stringformat(Date)方法

 

MessageFormat

MessageFormat可以把模式中的{N}使用参数来替换。我们把{N}称之为点位符。其中点位符中的N是从0开始的整数。

MessageFormat.format(String pattern, Object… params),其中pattern中可以包含0~n个点位符,而params表示对点位符的替换文本。注意,点位符需要从0开始。

 


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值