JSP开发业务应用

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属性有三个值:

  1. application/x-www-form-urlencoded:是其默认值,该属性主要用于处理少量文本数据的传递。
  2. multipart/form-data:上传二进制数据,只有使用了multipart/form-data才能完整地传递文件数据,进行上传操作。
  3. 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修饰的类。简单了解一下即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值