JSP分页显示数据
为什么需要分页
随着科技的发展,人们越来越依赖于网络进行营销,交流和宣传,基于Interent的Web应用也变的越来越复杂,资源也越来越庞大,而通过网络搜索数据是我们最常使用的操作。例如,假设要从数据报表中查询销售数据:如下图所示,当数据量很大时,可能有几万。几十万条,几百万条数据,不利于信息查看。

在日常生活中分页是随处可见的 例如:登录E-mail收取邮件时,邮件列表就是以分页来进行数据展示的如下图:

分页实现
实现分页的方式有多种,例如将所有的查询结果以集合的形式保存在内存中,翻页时从中取出一页所需的数据展示。这种方法有两个缺点:一是用户看到的可能是过期数据;二是如果数据量非常大,查询一次数据集会消耗很长时间。
另一种做法是每次翻页时只从数据库中检索出本页需要的数据。虽然每次翻页都查询数据库,但是查询出的记录数相对较少,总体开销不大,在配以连接池技术以及其他查询优化,可以达到比较高的效率。
实现数据分页显示 需要以下几个步骤:

有了需要展示的记录总数后,就可以根据每页显示的记录数计算共需要划分多少页,基于方便代码管理的考虑,将有关分页的数据封装到一个Page类中,其中包括每页显示的数据数量,数据的总数量,显示的总页数,当前页码,每页显示的数据集合。
代码如下所示
package com.xinwen.util;
import java.util.List;
import com.xinwen.enitiy.News;
public class Page {
//总页数
private int pageCount=0;
//每页显示的记录数
private int pageSize=5;
//记录总数
private int totalCount;
//当前页码
private int pageNo=1;
//每页新闻集合
private List<News> newsList;
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if(pageSize>0) {
this.pageSize = pageSize;
}
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if(totalCount>0) {
this.totalCount = totalCount;
//计算总页数
if(this.totalCount%pageSize==0) {
pageCount = this.totalCount/pageSize;
}else {
pageCount = this.totalCount/pageSize+1;
}
}
}
public int getPageNo() {
if(pageCount==0) {
return 0;
}
return pageNo;
}
public void setPageNo(int pageNo) {
if(pageNo>0) {
this.pageNo = pageNo;
}
}
public List<News> getNewsList() {
return newsList;
}
public void setNewsList(List<News> newsList) {
this.newsList = newsList;
}
}
在以上代码中,setTotalCount()方法中,根据记录总数和每页显示记录数计算出总页数,如果记录总数能被每页显示的记录数整除,则总页数为两者的商;如果不能被总页数整数,则余出的记录数单独列为一页,所以总页数为两者的商在加一。
编写SQL语句:
select * from news limit 0,3
在上边SQL语句中,limit子句的两个参数分别代表起始偏移量和最大返回行数,最大返回行数相当于每页显示的记录数,是一个固定值,而每页的数据起始偏移量是动态的,应该如何确定呢?
有一个规律: 起始偏移量=(当前页码-1)*每页显示的记录数 。
用Commons-FileUpload组件实现文件上传
实现文件上传,涉及对文件的读写操作,实现起来需要编写大量的代码,并容易引发异常。幸运的是,目前有很多非常实用的文件上传工具,可以帮助我们来实现文件上传的功能,其中应用比较多的是Commons-FileUpload组件,使用该组件可以极大简化开发人员的编码工作量。
Commons-FileUpload简介

获取Commons-FileUpload组件的步骤

表单的属性设置
在文件上传时,需要在表单属性中添加enxtType属性,该属性用于设置表单提交数据的编码方式。由于文件传至服务器时与一般文本类型的编码方式不同,需要使用multipart/form-data的编码方式。该属性设置方法如下:
<form action="doupdate.jsp" method="post" enctype="multipart/form-data">
注意:上传文件时form标签的method属性取值必须为 post 不能为 get。
表单的enxtType属性有三个值:
- application/x-www-form-urlencoded:是其默认值,该属性主要用于处理少量文本数据的传递。
- multipart/form-data:上传二进制数据,只有使用了multipart/form-data才能完整地传递文件数据,进行上传操作。
- text/plain:主要用于向服务器传递大量文本数据,比较适用于电子邮件的应用。
使用File控件选择文件
如果要实现文件上传,就需要在页面中使用File控件 在表单中添加File控件 如下所示:
<form action="doupdate.jsp" method="post" enctype="multipart/form-data">
<p>姓名:<input type="text" name="user"></p>
<p>选择图片<input type="file" name="nfile"></p>
<p><input type="submit" value="提交"></p>
</form>
表单设置好后。就可以进行文件上传了。
Commons-FileUpload组件的API
在使用Commons-FileUpload组件之前,首先需要在项目中添加commons-fileupload-1.2.2.jar和commons-io-2.4.jar文件。添加完jar文件后,在JSP文件中还需要将Commons-FileUpload组件所使用的类库导入到JSP文件中 代码如下
<%@ page import="org.apache.commons.fileupload.*" %>
在项目中添加完Commons-FileUpload组件后,再来了解该组件都提供了哪些接口和类来实现文件的上传。
1.ServletFileUpload类
.ServletFileUpload类用于实现文件上传操作 提供的常用方法如下所示:

2.FileItem接口
FileItem接口用于封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem实例,在应用程序中使用的是其实现类DiskFileItem。FileItem接口提供的方法如下所示:

3.FileItemFactory接口与实现类
创建ServletFileUpload实例需要依赖FileItemFactory工厂接口。DiskFileItemFactory是FileItemFactory接口的实现类,该类常用方法如下:

Commons-FileUpload组件的应用
以上面示例的页面作为文件上传页面,将表单提交到doupload.jsp代码如下所示:
<%@page import="java.util.Arrays"%>
<%@page import="java.io.File"%>
<%@page import="java.util.Iterator"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.fileupload.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>处理页面</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String uploadFileName="";
String fieldName="";
//请求信息中的内容是否是multipart类型
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
//上传文件的存储的存储路径(服务器文件系统上的绝对路径)
String uploadFilePath=request.getSession().getServletContext().getRealPath("upload/");
if(isMultipart){
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try{
//解析form表单中的所有文件
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
while(iter.hasNext()){ //依次处理每个文件
FileItem item = (FileItem) iter.next();
if(item.isFormField()){ //普通表单字段
fieldName = item.getFieldName(); //表单字段的name属性值
if(fieldName.equals("user")){
//输出表单字段的值
out.print(item.getString("UTF-8")+"上传了文件。<br/>");
}
}else{//文件表单字段
String fileName = item.getName();
if(fileName!=null && !fileName.equals("")){
File fullFile = new File(item.getName());
File saveFile = new File(uploadFilePath,fullFile.getName());
item.write(saveFile);
uploadFileName = fullFile.getName();
out.print("上传成功后的文件名是:"+uploadFileName+",文件大小是:"+item.getSize()+"bytes!");
}
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
%>
</body>
</html>
在以上示例中完成了一个文件上传的功能,对于其中的关键步骤如下:
- 在JSP文件中使用page指令导入Commons-FileUpload组件所需的类。
- 判断请求中的内容是否是multipart类型,如果是则进行处理。
- 通过FileItemFactory工厂对象实例化ServletFileUpload对象。
- 调用ServletFileUpload对象的parseRequest()将表单中的字段解析成FileItem对象的集合。
- 通过迭代依次对每个FileItem对象处理,如果是普通字段,通过getString()方法得到响应表单字符的值,该值与表单字段中的 name 属性对应,如果是文件字段,则通过File的构造方法构建一个指定路径名和文件名的文件,并通过FileItem对象的write()放啊将上传文件的内容保存到文件中。
用Commons-FileUpload组件控制文件上传
在实际应用中,为了能够保证系统安全运行,可能会需要对上传的文件进行控制。例如,上传图片时指定图片大小,发送邮件时对附件的类型和大小进行控制等。
1.控制文件上传的类型
大家都知道,在计算机文件可以划分出很多中类型,例如,图片就有JPG,GIF,CIF格式等,在上传文件时就需要对允许用户上传的文件类型进行控制。代码如下所示:
<%@page import="java.util.Arrays"%>
<%@page import="java.io.File"%>
<%@page import="java.util.Iterator"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.fileupload.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>处理页面</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String uploadFileName="";
String fieldName="";
//请求信息中的内容是否是multipart类型
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
//上传文件的存储的存储路径(服务器文件系统上的绝对路径)
String uploadFilePath=request.getSession().getServletContext().getRealPath("upload/");
File tempPatchFile = new File("d:\\temp\\buffer");
if(!tempPatchFile.exists()){
tempPatchFile.mkdirs(); //创建指定目录,包括所有必需但不存在的父目录
}
if(isMultipart){
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try{
//解析form表单中的所有文件
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
while(iter.hasNext()){ //依次处理每个文件
FileItem item = (FileItem) iter.next();
if(item.isFormField()){ //普通表单字段
fieldName = item.getFieldName(); //表单字段的name属性值
if(fieldName.equals("user")){
//输出表单字段的值
out.print(item.getString("UTF-8")+"上传了文件。<br/>");
}
}else{//文件表单字段
String fileName = item.getName();
List<String> filType= Arrays.asList("gif","bmp","jpg");
String ext = fileName.substring(fileName.lastIndexOf(".")+1);
if(!filType.contains(ext)){ //判断类型是否在指定范围内
out.print("上传失败,文件类型只能是gif,bmp,jpg");
}
else{
if(fileName!=null && !fileName.equals("")){
File fullFile = new File(item.getName());
File saveFile = new File(uploadFilePath,fullFile.getName());
item.write(saveFile);
uploadFileName = fullFile.getName();
out.print("上传成功后的文件名是:"+uploadFileName+",文件大小是:"+item.getSize()+"bytes!");
}
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
%>
</body>
</html>
在以上代码中用到了Arrays类,此类包含用于操作数组的各种方法,通过它的asList()方法创建固定长度的集合,也就是得到允许文件类型的集合,然后通过集合的contains()放啊匹配上传文件的扩展名来判断文件类型是否在允许范围内。
控制文件上传的大小
在上传文件除了要控制上传类型,同时还需要对上传文件的大小进行控制,代码如下所示:
<%@page import="java.util.Arrays"%>
<%@page import="java.io.File"%>
<%@page import="java.util.Iterator"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.fileupload.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>处理页面</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String uploadFileName="";
String fieldName="";
//请求信息中的内容是否是multipart类型
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
//上传文件的存储的存储路径(服务器文件系统上的绝对路径)
String uploadFilePath=request.getSession().getServletContext().getRealPath("upload/");
File tempPatchFile = new File("d:\\temp\\buffer");
if(!tempPatchFile.exists()){
tempPatchFile.mkdirs(); //创建指定目录,包括所有必需但不存在的父目录
}
if(isMultipart){
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲区大小4kb
factory.setSizeThreshold(4096);
//设置上传文件用到临时文件存放路径
factory.setRepository(tempPatchFile);
ServletFileUpload upload = new ServletFileUpload(factory);
//设置一个完整请求的最大允许大小
upload.setSizeMax(1024*30);
try{
//解析form表单中的所有文件
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iter = items.iterator();
while(iter.hasNext()){ //依次处理每个文件
FileItem item = (FileItem) iter.next();
if(item.isFormField()){ //普通表单字段
fieldName = item.getFieldName(); //表单字段的name属性值
if(fieldName.equals("user")){
//输出表单字段的值
out.print(item.getString("UTF-8")+"上传了文件。<br/>");
}
}else{//文件表单字段
String fileName = item.getName();
List<String> filType= Arrays.asList("gif","bmp","jpg");
String ext = fileName.substring(fileName.lastIndexOf(".")+1);
if(!filType.contains(ext)){ //判断类型是否在指定范围内
out.print("上传失败,文件类型只能是gif,bmp,jpg");
}
else{
if(fileName!=null && !fileName.equals("")){
File fullFile = new File(item.getName());
File saveFile = new File(uploadFilePath,fullFile.getName());
item.write(saveFile);
uploadFileName = fullFile.getName();
out.print("上传成功后的文件名是:"+uploadFileName+",文件大小是:"+item.getSize()+"bytes!");
}
}
}
}
}catch( FileUploadBase.SizeLimitExceededException ex){
out.print("上传失败,文件太大,全部文件的最大限制是:"+upload.getSizeMax()+"bytes!");
}catch(Exception e){
e.printStackTrace();
}
}
%>
</body>
</html>
在以上示例中,创建临时文件目录路径,通过DiskFileItemFactory对象的setSizeThreshold()方法设置缓冲区大小,当上传文件大小超过缓冲区大小,则临时存储在通过DiskFileItemFactory对象的setRepository()方法设置的临时文件目录中。同时通过ServletFlieUpload对象的setSizeMax()限制了一个完整请求的最大字节数,如果超出设置的字节数,则会抛出一个FileUploadBase.SizeLimitExceededException类型的异常,并通过异常处理提示错误信息
说明:FileUploadBase.SizeLimitExceededException是一个静态内部类,内部类是指定义在另一个类内部的类。内部类作为外部类的一个成员,并且依附于外部类而存在。这里的FileUploadBase就是外部的类,而SizeLimitExceededException就是定义在FileUploadBase内部的由static修饰的类。简单了解一下即可。
1万+

被折叠的 条评论
为什么被折叠?



