zoukankan      html  css  js  c++  java
  • JavaEE-05 分页与文件上传

    学习要点

    • 新闻分页显示数据
    • 新闻图片上传

    JSP分页显示数据

    分页

    • 数据信息较多的的时候一般采用列表显示,方便展示信息;
    • 数据量较大的时候一般采用列表加分页的方式显示,便于阅读。
    • 分页方式:集合或者session、存储过程、SQL语句分页

    分页步骤

    1. 确定每页显示的数据数量
    2. 确定分页显示所需的总页数
    3. 编写SQL查询语句,实现数据查询
    4. 在JSP页面中进行分页显示设置
    5. 对分页过程中的数据进行封装,封装到Page类中 

    实现过程

    1. 确定每页显示的数据量:例如:每页显示5条数据
    2. 计算显示的页数:使用count()函数查询数据库中的记录数;通过记录数和每页数据量计算总页数,把信息封装到Page类中。
    3. Page类代码
    /**分页泛型类*/
    public class Page<T> {
    	// 总页数
    	private int totalPageCount = 1;
    	// 页面大小,即每页显示记录数
    	private int pageSize = 0;
    	// 记录总数
    	private int totalCount = 0;
    	// 当前页号
    	private int currPageNo = 1;
    	// 每页数据集合
    	private List<T> List;
    
    	public List<T> getList() {
    		return List;
    	}
    
    	public void setList(List<T> list) {
    		List = list;
    	}
    
    	public int getCurrPageNo() {
    		if (totalPageCount == 0)
    			return 0;
    		return currPageNo;
    	}
    
    	public void setCurrPageNo(int currPageNo) {
    		if (this.currPageNo > 0)
    			this.currPageNo = currPageNo;
    	}
    
    	public int getTotalPageCount() {
    		return totalPageCount;
    	}
    
    	public void setTotalPageCount(int totalPageCount) {
    		this.totalPageCount = totalPageCount;
    	}
    
    	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;
    			// 计算总页数
    			totalPageCount = this.totalCount % pageSize == 0 ? (this.totalCount / pageSize)
    					: this.totalCount / pageSize + 1;
    		}
    	}
    }
    

      

    JavaBean的概念:JavaEE项目中对数据或者业务进行封装的简单类。

    类似于Page或者News新闻实体类。

    News类实现了数据的封装,Page类实现了业务的封装,并且这两个类都没有继承除Object类外的其他类或者实现接口,所有属性进行了封装,有无参构造方法。

    4.设计SQL语句

    MySQL分页语句:

    SELECT * FROM news ORDER BY NID ASC LIMIT (pageindex-1)*pagesize,pagesize;
    

      

    5.数访问层实现

    NewsDao:

    public abstract int getTotalCount();
    public List<News> getPageNewsList(int pageIndex,int pageSize);
    

      

    NewsDaoImpl:

    	/** 获取分页新闻信息 */
    	public List<News> getPgeNewsList(int pageNo, int pageSize) {
    		List<News> newsList = new ArrayList<News>();
    		String sql = "select NID,NTITLE,NCREATEDATE from NEWS order by NCREATEDATE desc LIMIT ?,?";
    		Object[] args = { (pageNo - 1) * pageSize, pageSize };
    		ResultSet rs = this.executeQuery(sql, args);
    		try {
    			while (rs.next()) {
    				int nId = rs.getInt("NID");
    				String nTitle = rs.getString("NTITLE");
    				Timestamp times = rs.getTimestamp("NCREATEDATE");
    				SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
    				String nCreateDate = sdf.format(times);
    				// String nCreateDate = rs.getString("NCREATEDATE");
    				News news = new News();
    				news.setNid(nId);
    				news.setNtitle(nTitle);
    				news.setNcreatedate(nCreateDate);
    				newsList.add(news);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return newsList;
    	}
    
    	/**查询总记录数*/
    	public int getTotalCount() {
    		int count = 0;
    		Connection conn = this.getConnection();
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = "select count(1) from news";
    		try {
    			pstmt = conn.prepareStatement(sql);
    			rs = pstmt.executeQuery();
    			if (rs.next()) {
    				count = rs.getInt(1);
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			this.closeAll(rs, pstmt, conn);
    		}
    		return count;
    }
    

      

    6.测试方法

    public static void main(String[] args) {
    		NewsDaoImpl newsDao = new NewsDaoImpl();
    		int totalCount = newsDao.getTotalCount();
    		Page<News> page = new Page<News>();
    		page.setCurrPageNo(3); // 设置当前页面
    		page.setPageSize(3); // 设置每页条数
    		page.setTotalCount(totalCount); // 设置总记录数
    		System.out.println("新闻总数量是:" + page.getTotalCount());
    		System.out.println("每页条数是:" + page.getPageSize());
    		System.out.println("总页数:" + page.getTotalPageCount());
    		System.out.println("当前是第" + page.getCurrPageNo() + "页:");
    		List<News> newsList = newsDao.getPgeNewsList(page.getCurrPageNo(), page.getPageSize());
    		page.setList(newsList);// 设置每页显示的集合
    		for (News news : page.getList()) {
    			System.out.println(news.getNid() + "	" + news.getNtitle() + "	" + news.getNcreatedate());
    		}
    }
    

     

    7.JSP页面信息页控制代码

    当前页数:[<%=pageIndex%>/<%=totalpages%>]
        	 <%
       	 if(pageIndex > 1){		//控制页面显示风格
    	 %>   
       		   <a href="pageControl.jsp?pageIndex=1">首页</a> 
        		   <a href="pageControl.jsp?pageIndex=<%= pageIndex -1%>">上一页</a>
    	   <% }
        	   if(pageIndex < totalpages){	//控制页面显示风格
    	   %>
        		   <a href="pageControl.jsp?pageIndex=<%= pageIndex +1%>">下一页</a>
        		   <a href="pageControl.jsp?pageIndex=<%=totalpages%>">末页</a> 
    	   <%}%>   
    

      

    8.信息处理页参考代码

    String pageIndex = request.getParameter("pageIndex");//获得当前页数
    
        if (pageIndex == null) {
    
            pageIndex = "1";
    
        }
    
        int currPageNo = Integer.parseInt(pageIndex);
    
        NewsDaoImpl newsDao = new NewsDaoImpl();
    
        int totalCount = newsDao.getTotalCount();//获得总记录数
    
        Page<News> pages = new Page<News>();
    
        pages.setPageSize(3); //设置每页条数
    
        pages.setTotalCount(totalCount); //设置总记录数
    
        int totalpages = pages.getTotalPageCount();
    
        /*对首页与末页进行控制*/
    
        if (currPageNo < 1) {
    
            currPageNo = 1;
    
        } else if (currPageNo > pages.getTotalPageCount()) {
    
            currPageNo = totalpages;
    
        }
    
        pages.setCurrPageNo(currPageNo); //设置当前页面
    
        List<News> newsList = newsDao.getPgeNewsList(pages.getCurrPageNo(), pages.getPageSize());
    
        pages.setList(newsList); //设置每页显示的集合
    
        request.setAttribute("pages", pages);
    
    request.getRequestDispatcher("index.jsp").forward(request, response);
    

      

    上机练习:实现新闻分页显示

    需求说明

    编写代码实现首页新闻标题的分页显示,要求能够执行首页、下一页、上一页、末页的操作,并在页面中显示总页数和当前页

    实现思路

    • 确定每页显示的新闻数量
    • 编写数据库访问类,声明查询方法
    • 编写SQL语句
    • 编写JavaBean封装分页信息(Page类)
    • 在JSP中调用JavaBean

    使用Commons-FileUpload上传文件

    需求

    网页应用中,经常需要上传文件到服务器。上传文件网页代码:

    	<form action="doupload.jsp" enctype="multipart/form-data" method="post">
    		<p>姓名:<input type="text" name="user"></p>
    		<p>选择图片:<input type="file" name="nfile"></p>
    		<p><input type="submit" value="提交"></p>
    	</form>
    

      

    表单要上传文件,需要注意两点:

    1、设置enctype属性,值必须为multipart/form-data

    2、表单的提交方式必须为post

    上传文件组件

    • Commons-FileUpload组件可以方便地嵌入到JSP文件中,在JSP文件中仅编写少量代码即可完成文件的上传功能,十分方便。
    • 能够全程控制上传内容:可以获得全部上传文件的信息,包括文件名称、类型、大小等,方便操作。
    • 能够对上传文件的大小、类型进行控制:为了避免在上传过程中出现异常数据,在Commons-FileUpload组件中,专门提供了相应的方法用于对上传文件进行控制。

    获取Commons-FileUpload组件的方式

    • http://commons.apache.org/fileupload下载Commons-FileUpload组件

    Commons-FileUpload组件类库:commons-fileupload-1.3.2.jar

    Commons-FileUpload组件的API文档: apidocs

    • http://commons.apache.org/io下载Commons-IO组件

    Commons-IO组件类库:commons-io-2.5.jar

    Commons-IO组件的API文档: commons-io-2.5docs

    Commons-FileUpload组件的API

    • ServletFileUpload类的常用方法

    方法名称

    方法描述

    public void setSizeMax(long sizeMax)

    设置请求信息实体内容的最大允许的字节数

    public List parseRequest(HttpServletRequest req )

    解析form表单中的每个字符的数据,返回一个FileItem对象的集合

    public static final boolean isMultipartContent (HttpServletRequest req )

    判断请求信息中的内容 是否是“multipart/form-data”类型

    public void setHeaderEncoding(String encoding)

    设置转换时所使用的字符集编码

    • FileItem接口的常用方法

    方法名称

    方法描述

    public boolean isFormField()

    判断FileItem对象封装的数据类型(普通表单字段返回true,文件表单字段返回false)

    public String getName()

    获得文件上传字段中的文件名(普通表单字段返回null)

    public String getFieldName()

    返回表单字段元素的name属性值

    public void write()

    将FileItem对象中保存的主体内容保存到指定的文件中

    public String  getString()

    将FileItem对象中保存的主体内容以一个字符串返回。其重载方法public String  getString(String encoding)中的参数用指定的字符集编码方式

    public long getSize()

    返回单个上传文件的字节数

     

     

    • FileItemFactory接口与实现类

    实现类:DefaultFileItemFactory, DiskFileItemFactory

    方法名称

    方法描述

    public void setSizeThreshold(int sizeThreshold)

    设置内存缓冲区的大小

    public void setRepositoryPath(String path )

    设置临时文件存放的目录

     

    文件上传的实现

    • 实现步骤
    //创建FileItemFactory对象
    //创建ServletFileUpload对象	
    //解析form表单中所有文件
    if (普通表单字段){  
    //获取表单字段的name属性值
    if (此属性是“user”)){ 
    //输出XXX上传了文件
    }
    }else{   
    //文件表单字段
    //获取上传文件的名字
    if (名字不为空) {
    //保存此文件并输出保存成功		
    }
    } 
    

      

    • 示例代码
    <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@page import="java.io.File"%>
    <%@page import="org.apache.commons.fileupload.FileItem"%>
    <%@page import="org.apache.commons.fileupload.FileItemFactory"%>
    <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
    <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
    
    <%
    	String path = request.getContextPath();
    	String basePath = request.getScheme() + "://"
    			+ request.getServerName() + ":" + request.getServerPort()
    			+ path + "/";
    %>
    
    <%
    	request.setCharacterEncoding("utf-8");
    	String uploadFileName = ""; //上传的文件名
    	String fieldName = ""; //表单字段元素的name属性值
    	//请求信息中的内容是否是multipart类型
    	boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    	//上传文件的存储路径(服务器文件系统上的绝对文件路径)
    	String uploadFilePath = request.getSession().getServletContext()
    			.getRealPath("upload/");
    	if (isMultipart) {
    		FileItemFactory 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);
    						out.print("<br>文件保存绝对路径为:"+saveFile.getPath());
    						out.print("<br>文件保存相对路径为:"+"upload\"+uploadFileName);
    					}
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    %>
    

      

    上机练习

    需求描述

    完成新闻发布信息的添加图片功能

    实现思路

    1. 添加commons-fileupload.jar和commons-io-2.5.jar

    2. 在JSP文件中使用page指令导入Commons-FileUpload类

    3. 调用Commons-FileUpload组件相关类的方法获取文件信息并实现保存

    控制上传文件的属性

    控制文件上传的类型

    代码框架

    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{ 
        //上传文件
    }
    

      

    控制文件上传的大小

    代码框架

    ServletFileUpload upload = new ServletFileUpload(factory);
    //设置单个文件的最大限制
    upload.setSizeMax(1024*30); 
    try {
    //……省略上传代码
    }catch(FileUploadBase.SizeLimitExceededException ex){
        out.print(“上传失败,文件太大,单个文件的最大限制是:"+
        upload.getSizeMax()+"bytes!");
    

      

    完整代码示例

    <%@page import="org.apache.commons.fileupload.FileUploadBase"%>
    <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@page import="java.io.File"%>
    <%@page import="org.apache.commons.fileupload.FileItem"%>
    <%@page import="org.apache.commons.fileupload.FileItemFactory"%>
    <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
    <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
    
    <%
    	String path = request.getContextPath();
    	String basePath = request.getScheme() + "://"
    			+ request.getServerName() + ":" + request.getServerPort()
    			+ path + "/";
    %>
    
    <%
    	request.setCharacterEncoding("utf-8");
    	String uploadFileName = ""; //上传的文件名
    	String fieldName = ""; //表单字段元素的name属性值
    	//请求信息中的内容是否是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()) { //文件表单字段
    					String fileName = item.getName();
    					//通过Arrays类的asList()方法创建固定长度的集合
    					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();
    		}
    	}
    %>
    

      

    上机练习

    需求描述

    • 管理员在发布新闻时,可以同时实现新闻图片的上传
    • 允许上传的图片类型为:GIF文件、JPG文件、JPEG文件、PNG文件
    • 上传图片的大小不能超过5MB完成新闻发布信息的添加图片功能
    • 管理员选择某一条新闻,单击修改链接后,在新闻编辑页面显示此条新闻内容。
    • 编辑好新闻内容后,单击提交按钮更新此条新闻。

    上机练习

    需求描述

    • 管理员选择某一条新闻,单击修改链接后,在新闻编辑页面显示此条新闻内容。
    • 编辑好新闻内容后,单击提交按钮更新此条新闻。


    本博客文章未经许可,禁止转载和商业用途!

    如有疑问,请联系: 2083967667@qq.com


  • 相关阅读:
    sqlserver 表操作 SQL篇
    C#知识点汇总
    DDL
    sqlserver2008简介
    面向对象继承
    IO文件流
    【帅刺猬课堂】Winform中使用WPF的UserControl
    KS Gantt甘特图控件通过递归加载无限层级的数据
    Office 每次打开需要重新配置的问题修复方法
    扩展方法
  • 原文地址:https://www.cnblogs.com/rask/p/8486950.html
Copyright © 2011-2022 走看看