JavaWeb-08-Web應用中的MVC

Table of Contents

 

1:什麼是mvc

1.1:Model---邏輯處理

1.2:Controller---控制頁面跳轉

1.3:View ---演示數據

1.4:MVC的優缺點

2:定製錯誤頁面

 2.1:聲明錯誤頁面

2.2:容器處理異常:

3:文件上傳下載

3.1:文件上傳

3.1.1:用於上傳文件的Form表單,需要設置enctype屬性。

3.1.2:開發支持文件上傳的Servlet

3.1.3:part類

3.2:單文件上傳

3.2.1:html頁面

3.2.2:Servlet

3.3:文件下載

3.3.1:Servlet

3.3.2:Html頁面

3.3.3:設置contentType

3.3.4:常用ContentType


1:什麼是mvc

  1. MVC是一個框架型設計模式
  2. 本身沒有實際的代碼(功能)
  3. 它只是說明頁面、數據處理如何擺放。

1.1:Model---邏輯處理

  1. 封裝應用狀態(封裝應用數據)
  2.     響應狀態查詢(對數據進行增刪改查)
  3.     暴露應用的功能(暴露接口<public>)

1.2:Controller---控制頁面跳轉

  1. 驗證HTTP請求的數據(收集組織數據)
  2. 將用戶數據與模型的更新相映射(調用邏輯層)
  3. 選擇用於響應的視圖(選擇下一個界面)

1.3:View ---演示數據

  1. 產生HTML響應(展示數據),如jsp,html等
  2. 請求模型的更新(人機交互)
  3. 提供HTML form用於用戶請求(收集參數,調用邏輯層api)

1.4:MVC的優缺點

1.4.1:MVC的優點:

      低耦合性:視圖層和業務層分離

      高重用性和可適用性

      可維護性

      有利於軟件工程化管理

      提高軟件的健壯性

 1.4.2: MVC的缺點:

            工作量大,增加工作的複雜性,MVC不適合小型甚至中等規模的應用程序

將狀態查詢封裝在Model中,使Model過於臃腫。

 

2:定製錯誤頁面

聲明方式:

使用部署描述符爲特定情況(HTTP錯誤或Java異常)聲明錯誤頁面,並由Web容器將處理轉發到這些頁面

編程方式:

直接在servlet代碼中處理Java異常,並將HTTP請求轉發到所選定的錯誤頁面

 2.1:聲明錯誤頁面

使用error-page元素聲明一個給定HTTP狀態碼的處理器:

 <error-page>
 	<error-code>404</error-code>
 	<location>/error/404.html</location>
 </error-page>

可以聲明任意數量的錯誤頁面,但一個給定的狀態碼只能對應一個頁面。

  • 使用exception-type元素聲明給定Java異常的處理器
<error-page>
 	<exception-type>
        java.lang.ArithmeticException
 	</exception-type>
 	<location>/error/ExceptionPage</location>
</error-page>

可以聲明任意數量的錯誤頁面,但一個給定的異常類型只對應一個頁面。

不能使用父類捕獲多種異常。

2.2:容器處理異常:

一個servlet可拋出ServletException指明有異常產生

所有檢查到的異常必須被捕獲,並封裝在ServletException中

編寫錯誤處理Servlet

  • 應同時覆蓋doGet和doPost方法

兩個預定義的請求屬性:

  1.  javax.servlet.error.exception :包含原始(被包裝)的異常
  2.  javax.servlet.error.request_uri:包含原始客戶請求的URI

 

可編寫自己的servlet代碼捕獲所有異常並自己處理,而不是讓容器處理

使用此技術只可以處理Java異常,而非HTTP異常

步驟:

  1. 對可能產生異常的所有代碼使用一個 try-catch塊
  2. 在catch塊中使用RequestDispatcher將異常轉發到一個servlet異常處理器
  3. (可選)可以設置特定的請求屬性

聲明servlet異常處理器,但不提供URL映射

<servlet>
<servlet-name>ExceptionHandler</servlet-name>
<servlet-class>sl314.web.ExceptionDisplay</servlet-class>
</servlet>

 

使用servlet名獲得RequestDispatcher

ServletContext context = getServletContext();
RequestDispatcher errorPage= context.getNamedDispatcher("ExceptionHandler");
request.setAttribute("javax.servlet.error.exception", e);
request.setAttribute("javax.servlet.error.request_uri",
request.getRequestURI());
errorPage.forward(request, response);

 

3:文件上傳下載

 

3.1:文件上傳

在Servlet2.5中,我們要實現文件上傳功能時,一般都需要藉助第三方開源組件,例如Apache的commons-fileupload組件,在Servlet3.0中提供了對文件上傳的原生支持,我們不需要藉助任何第三方上傳組件,直接使用Servlet3.0提供的API就能夠實現文件上傳功能了。

3.1.1:用於上傳文件的Form表單,需要設置enctype屬性。

<form action="UploadServlet.do" method="post" enctype= "multipart/form-data">
	
</form>

3.1.2:開發支持文件上傳的Servlet

Servlet類的聲明上,使用註解@MultipartConfig可以設置Servlet支持文件上傳。

@MultipartConfig 
public class UploadServlet extends HttpServlet {

}

3.1.3:part類

Part是Java EE6.0新增的接口,Servlet3.0multipart/form-data的部分POST請求封裝成Part,通過Part對上傳的文件進行操作

//通過name獲得上傳文件對象Part
     Part part=request.getPart("file");

//獲取上傳的文件集合
Collection<Part> parts = request.getParts();

3.2:單文件上傳

3.2.1:html頁面

上傳單個文件
	<form action="UploadServlet.do" method="post" enctype="multipart/form-data">
		上傳文件:
		<input type="file" name="file">
		<br>
		<input type="submit" value="上傳">
	</form>

3.2.2:Servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		// 存儲路徑
		String savePath = request.getServletContext().getRealPath("/uploadFile");

		// 通過name獲得上傳文件對象Part
		Part part = request.getPart("file");
		// Servlet3沒有提供直接獲取文件名的方法,需要從請求頭中解析出來
		// 獲取請求頭,請求頭的格式:form-data; name="file"; filename="snmp4j--api.zip"
		String header = part.getHeader("content-disposition");
		// 獲取文件名
		String fileName = getFileName(header);
		// 把文件寫到指定路徑
		part.write(savePath + File.separator + fileName);

		PrintWriter out = response.getWriter();
		out.println("上傳成功");
		out.flush();
		out.close();
	}

獲取文件名的方法:

/**
	 * 根據請求頭解析出文件名 請求頭的格式:
	 * 火狐和google瀏覽器下:form-data;name="file";filename="AmazeUI-2.7.2.zip" 
	 * IE瀏覽器下:form-data; name="file";filename="E:\AmazeUI-2.7.2.zip"
	 * @param header 請求頭
	 * @return 文件名
	 */
	public String getFileName(String header) {
		String[] tempArr1 = header.split(";");
		/**
		 * 火狐或者google瀏覽器下:tempArr2={filename,"AmazeUI-2.7.2.zip"}
		 * IE瀏覽器下:tempArr2={filename,"E:\AmazeUI-2.7.2.zip"}
		 */
		String[] tempArr2 = tempArr1[2].split("=");
		// 獲取文件名,兼容各種瀏覽器的寫法
		String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
		return fileName;
	}

3.3:文件下載

在Servlet中實現文件的下載,第一需要通過HttpServletResponse的setContentType方法設置ContentType頭信息的值,這樣設置之後瀏覽器纔會以下載的方式來響應。第二需要使用IO流來讀取文件內容,將字節輸出在響應流中。

3.3.1:Servlet

@WebServlet("/downloadServlet.do")
public class DownloadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 處理請求
		// 根據根路徑得到絕對路徑
		String path = this.getServletContext().getRealPath("/uploadFile/AmazeUI-2.7.2.zip");
		// 讀取要下載的文件
		File f = new File(path);
		if (f.exists()) {
			//需要注意:源文件的名稱是《AmazeUI-2.7.2.zip》,下載後的文件名稱是《妹子UI.zip》
			// 解決中文文件名下載後亂碼的問題,將gbk編碼轉換成ISO8859_1編碼
			String filename = new String("妹子UI.zip".getBytes("GBK"),"ISO8859-1");
			response.setHeader("Content-Disposition", "attachment;filename=" + filename + "");

			// 獲取要下載的文件輸入流
			FileInputStream fis = new FileInputStream(f);
			int len = 0;
			// 創建數據緩衝區
			byte[] buffer = new byte[1024*16];
			// 通過response對象獲取OutputStream流
			OutputStream out = response.getOutputStream();
			// 將FileInputStream流寫入到buffer緩衝區
			while ((len = fis.read(buffer)) > 0) { 
				//使用OutputStream將緩衝區的數據輸出到客戶端瀏覽器
				out.write(buffer, 0, len);
				out.flush();
			}
			out.close();
		}
	}
}
public Response downUpload(String id) {


        InputStream in = null;
        ByteArrayOutputStream bos = null;
        try {

            String fileName = "";
            

            in = UploadIn.downloadFile(id);

            bos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;

            while((len = in.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }

            return Response.ok(bos.toByteArray())
                    .header("Content-disposition", "attachment;filename=" +  URLEncoder.encode(fileName, "UTF-8"))
                    .header("Cache-Control", "no-cache").build();

        }catch (Exception e){
            System.out.println(""+e);
        }finally {
            try {
                if(in != null)
                    in.close();
                if(bos != null)
                    bos.close();
            }catch (IOException e){
               System.out.println(""+e);
            }
        }
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }

 

3.3.2:Html頁面

<a href="downloadServlet.do">下載</a>

3.3.3:設置contentType

調用HttpServletResponse接口的setContentType方法,可以設置響應內容的類型,也叫MIME類型。它的作用是使客戶端瀏覽器可以區分不同類型的數據,並根據不同的MIME類型調用瀏覽器內不同的程序嵌入模塊來處理相應的數據。

例如web瀏覽器就是通過MIME類型來判斷文件是word。

// 根據根路徑得到絕對路徑
String path = this.getServletContext()
.getRealPath("/uploadFile/[匯才同飛教育]預科班教程_V1.6.docx");
// 讀取要下載的文件
File f = new File(path);

String filename = 
new String(f.getName().getBytes("GBK"),"ISO8859-1");
response.setHeader("Content-Disposition", 
"attachment;filename=" + filename + "");
//設置響應類型是word
response.setContentType("application/x-msdownload");

3.3.4:常用ContentType

 

文件擴展名

Content-Type(Mime-Type)

.*(二進制流,不知道文件類型)

application/octet-stream

.tif

image/tiff

.awf

application/vnd.adobe.workflow

.avi

video/avi

.bmp

application/x-bmp

.doc

application/msword

.class

java/*

.css

text/css

.exe

application/x-msdownload

.excel

application/vnd.ms-excel

.gif

image/gif

.htm

text/html

.html

text/html

.ico

image/x-icon

.img

application/x-img

   

.java

java/*

.jpe

image/jpeg

.jpeg

image/jpeg

.jpg

image/jpeg

.jsp

text/html

.mp3

audio/mp3

.mp4

video/mpeg4

.mpeg

video/mpg

.odc

text/x-ms-odc

.pdf

application/pdf

.png

image/png

.ppt

application/vnd.ms-powerpoint

rar

application/octet-stream  

.rmvb

application/vnd.rn-realmedia-vbr

.swf

application/x-shockwave-flash

.torrent

application/x-bittorrent

.txt

text/plain

.xml

text/xml

.zip

application/x-zip-compressed

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章