1.3案例二:使用Servlet3.0技术完成文件的上传: 1.3.1需求: 1.3.2分析: 1.3.2.1技术分析: 【Servlet3.0】 Servlet3.0 与 Servlet2.5: * Servlet3.0需要运行在tomcat7以上的服务器中. * Servlet3.0以后web.xml就不是必须的. 1.Servlet3.0支持注解开发. 2.提供异步请求. 3.支持文件上传. 【Servlet3.0支持注解开发】 使用@WebServlet替换web.xml中配置的Servlet: @WebServlet(urlPatterns="/ServletDemo1",loadOnStartup=2,initParams=@WebInitParam(name="username",value="root"))

使用@WebListener替换web.xml中监听器的配置: @WebListener

使用@WebFilter替换web.xml中的过滤器的配置: @WebFilter(urlPatterns="/*") 【Servlet3.0支持异步请求-了解】 使用的是多线程的方式处理的,将传统的方式一次请求的非常耗时的操作,分成多个线程去处理. 需要在Servlet上添加一个属性: @WebServlet(urlPatterns="/ServletDemo2",asyncSupported=true)

@WebServlet(urlPatterns="/ServletDemo2",asyncSupported=true) public class ServletDemo2 extends HttpServlet{

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	
	AsyncContext context = req.startAsync(req, resp);
	context.start(new MyRunner(context));

	for(int i=1;i<=20;i++){
		System.out.println(i);
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	doGet(req, resp);
}

}

class MyRunner implements Runnable{

private AsyncContext context;

public MyRunner(AsyncContext context) {
	this.context = context;
}

@Override
public void run() {
	for(char i='a';i<='z';i++){
		try {
			context.getResponse().getWriter().println(i);
			Thread.sleep(100);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

} 【Servlet3.0的文件上传】 文件上传: 文件上传:指的是将本地的文件 写到 服务器上. 文件上传的要素: 1.表单的提交的方式必须是POST. 2.表单中必须有一个文件上传项:<input type=”file”>,而且文件上传项必须有name属性和值. * <input type=”file” name=”upload”/> 3.表单的enctype属性的值必须是multipart/form-data 文件上传的抓包分析: 未修改enctype属性的时候:

POST /WEB17_WEB/demo1/demo1.jsp HTTP/1.1 Accept: text/html, application/xhtml+xml, / X-HttpWatch-RID: 22325-10011 Referer: http://localhost:8080/WEB17_WEB/demo1/demo1.jsp Accept-Language: zh-Hans-CN,zh-Hans;q=0.5 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Host: localhost:8080 Content-Length: 47 Connection: Keep-Alive Cache-Control: no-cache Cookie: JSESSIONID=99CD51DA9A47D29200168968AD983E9E

upload=C%3A%5CUsers%5Capple%5CDesktop%5Caaa.txt

已经修改了enctype属性: POST /WEB17_WEB/demo1/demo1.jsp HTTP/1.1 Accept: text/html, application/xhtml+xml, / X-HttpWatch-RID: 22325-10026 Referer: http://localhost:8080/WEB17_WEB/demo1/demo1.jsp Accept-Language: zh-Hans-CN,zh-Hans;q=0.5 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko Content-Type: multipart/form-data; boundary=---------------------------7e02e526160b66 Accept-Encoding: gzip, deflate Host: localhost:8080 Content-Length: 224 Connection: Keep-Alive Cache-Control: no-cache Cookie: JSESSIONID=99CD51DA9A47D29200168968AD983E9E

-----------------------------7e02e526160b66 Content-Disposition: form-data; name="upload"; filename="C:\Users\apple\Desktop\aaa.txt" Content-Type: text/plain

Hello shouyi -----------------------------7e02e526160b66— 【文件上传的原理】 根据分割线将请求体的部分分成几块:

  • 判断 每块是 普通项还是文件上传项.
    • 普通项:获得名称和值.
    • 文件上传项:获得文件名 和 文件内容输入流. 【文件上传的技术】 JspSmartUpload: jspSmartUpload组件是应用JSP进行B/S程序开发过程中经常使用的上传下载组件,它使用简单,方便。现在我又为其加上了下载中文名字的文件的支持,真个是如虎添翼,必将赢得更多开发者的青睐。-Model1年代的文件上传的工具. FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能,与常见的SmartUpload齐名.应用在Model2年代了. Servlet3.0 : Struts2 : 1.3.2.2步骤分析: 设计一个文件上传页面: 提交到Servlet: 接收普通项:request.getParameter(); 接收上传项:Part: 通过Part对象中的方法完成文件的上传. 1.3.3代码实现 package com.itheima.servlet;

import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream;

import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part;

/**

  • 文件上传的Servlet */ @WebServlet("/UploadServlet") @MultipartConfig public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 接收普通项: request.setCharacterEncoding("UTF-8"); String desc = request.getParameter("desc"); System.out.println("文件描述:"+desc); Part part = request.getPart("upload"); // 获得上传的文件的大小 long size = part.getSize(); System.out.println("文件大小"+size); String type = part.getContentType(); System.out.println("文件类型"+type); // text/plain image/jpeg String name = part.getName(); System.out.println(name); // 获得文件名: String header = part.getHeader("Content-Disposition"); System.out.println(header);

     int idx = header.lastIndexOf("filename=\"");
     String fileName = header.substring(idx+10, header.length()-1);
     System.out.println(fileName);
     
     // 获得文件内容:
     InputStream is = part.getInputStream();
     
     // 获得文件上传路径:
     String path = this.getServletContext().getRealPath("/upload");
     
     OutputStream os = new FileOutputStream(path+"/"+fileName);
     int len = 0;
     byte[] b = new byte[1024];
     while((len = is.read(b))!=-1){
     	os.write(b, 0, len);
     }
     is.close();
     os.close();
    

    }

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

} 1.3.4总结: 1.3.4.1文件名重名的问题: UUID随机产生一个文件名. 1.3.4.2文件上传的目录分离: 按用户分 :一个用户创建一个或多个路径. 按时间分 :按月,星期,天进行划分. 按个数分 :一个路径中存3000个文件. 按分离算法分 :按照一定的算法进行划分.