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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值