1. 程式人生 > >JavaEE-05 分頁與文件上傳

JavaEE-05 分頁與文件上傳

實現 嵌入 repo new har his 超過 ble args

學習要點

  • 新聞分頁顯示數據
  • 新聞圖片上傳

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() + "\t" + news.getNtitle() + "\t" + 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.5\docs

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完成新聞發布信息的添加圖片功能
  • 管理員選擇某一條新聞,單擊修改鏈接後,在新聞編輯頁面顯示此條新聞內容。
  • 編輯好新聞內容後,單擊提交按鈕更新此條新聞。

上機練習

需求描述

  • 管理員選擇某一條新聞,單擊修改鏈接後,在新聞編輯頁面顯示此條新聞內容。
  • 編輯好新聞內容後,單擊提交按鈕更新此條新聞。

JavaEE-05 分頁與文件上傳