A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 我是楠楠 于 2018-7-4 17:26 编辑

【郑州校区】使用Servlet3.0完成一个文件上传的功能

1.1.1 需求:
在网站上有商品维护,上传商品图片,需要使用文件上传:
1.1.2 分析:1.1.2.1 技术分析:
【文件上传的概述】
Ø 文件上传:
* 指的是将本地的文件 写到 服务器上.
Ø 文件上传技术:
* Servlet3.0                :注解开发,文件上传,异步请求.
* JSPSmartUpload        :嵌入到JSP中完成文件上传.主要用于Model1年代的.
* FileUpload                :Apache的文件上传组件.
* Struts2                        :底层是FileUpload.
Ø 文件上传的要素:
* 表单的提交的方式必须是POST.
* 表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值:<input type=”file” name=”upload”>
* 表单的enctype属性的值必须是multipart/form-data.
【Servlet3.0】
Ø Servlet3.0与Servlet2.5提供了三个新特性:
* 注解开发        :方便
* 文件上传        :有些API不是特别全.
* 异步请求        :
【Servlet3.0的注解开发】
Ø @WebServlet
Ø @WebListener
Ø @WebFilter
【文件上传原理分析】
Ø 设计文件上传的页面:
进行文件上传的抓包分析:
没有设置enctype属性的时候:只能获得文件的名称,而没有文件内容.
设置enctype属性为multipart/form-data:获得到文件名及文件内容.
1.1.3 代码实现:
【步骤一】:设置一个文件上传页面.
【步骤二】:点击提交,提交到Servlet中.
【步骤三】:在Servlet中接收参数.
【步骤四】:获得服务器的文件上传的路径.
【步骤五】:通过流写到该路径下就OK了.
代码:
[AppleScript] 纯文本查看 复制代码
@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 filedesc = request.getParameter("filedesc");

System.out.println("文件描述"+filedesc);

// 接收文件:

Part part = request.getPart("upload");


long size = part.getSize();// 获得文件大小:

System.out.println("文件大小:"+size);

String name = part.getName();

System.out.println("文件表单中的name属性的名称"+name);

// 获得文件名:

String header = part.getHeader("Content-Disposition");

int idx = header.lastIndexOf("filename=\"");

String fileName = header.substring(idx+10, header.length()-1);

System.out.println("文件名:"+fileName);

// 获得文件内容:

InputStream is = part.getInputStream();

// 获得upload的路径:

String path = this.getServletContext().getRealPath("/upload");

OutputStream os = new FileOutputStream(path+"/"+fileName);

byte[] b = new byte[1024];

int len = 0;

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.1.4 总结:1.1.4.1 文件上传问题:文件名重名.
使用随机的唯一文件名:
* 使用UUID作为随机的文件名.
1.1.4.2 文件上传问题:一个目录下存放的文件过多.
一个目录下文件过多,导致打开都很慢,更别说是读写操作.
目录分离:
* 按时间分        :一个月一个目录,一个星期一个目录,一天一个目录
* 按数量分        :一个目录下存5000个文件,创建一个新的目录,再去存放.
* 按用户分        :为每个用户创建一个单独目录 存放文件.
* 按目录分离算法分                :
    * 使用唯一文件名.hashCode(); -- 得到一个代表当前这个文件的int类型值.
    * int类型占4个字节32位.可以让hashCode值&0xf; 得到一个int值,用这个int值作为一级目录.
    * 让hashCode右移4位 &0xf ;得到一个int值,用这个int值作为二级目录.依次类推.
1.1.4.3 Servlet3.0异步请求:
[AppleScript] 纯文本查看 复制代码
/**

 * 异步请求的Servlet

 */

@WebServlet(urlPatterns="/AsyncServlet",asyncSupported=true)

public class AsyncServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

 

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

AsyncContext context = request.startAsync(request, response);

context.start(new MyRunnable(context));


for(int i = 1;i<=10;i++){

System.out.println(i);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

 

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

doGet(request, response);

}

 

}

 

class MyRunnable implements Runnable{

private AsyncContext context;

public MyRunnable(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();

}

}

}


}
传智播客·黑马程序员郑州校区地址
河南省郑州市 高新区长椿路11号大学科技园(西区)东门8号楼三层
联系电话 0371-56061160/61/62
来校路线  地铁一号线梧桐街站A口出

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马