文件的上传
1. 第一步就是修改表单的提交提交方式:
<form method=” post” enctype="multipart/form-data" ></form>//以二进制流的形式传输数据
2. 第二步就在表单中加入文件上传组件
<input type="file" />
3.以流的形式提交数据,所以用流接收数据InputStreaminput=request.getInputStream();
4.导入2个jar包,放入到WEB-INF下的lib文件下,然后添加依赖即可
commons-fileupload-1.2.2.jar
commons-io-2.4.jar
我这里用的是上面的两个版本的jar包,一个upload包和一个io包
在site/index.jsp有例子
5./tomcat/ temp目录 默认上传到该位置 item.delete();删除temp目录中的临时文件
item.getInputStream();
6.FileItem item.get...获取上传文件的信息
7.this.getServletContext().getRealPath("/xx");
8.具体servlet中具体的写法:
dopost方法中的代码:
request.setCharacterEncoding("UTF-8");
boolean multipartContent = ServletFileUpload.isMultipartContent(request);
if(multipartContent){
//获取到一个文件工厂
FileItemFactory factory = new DiskFileItemFactory();
//从工厂中拿出一个文件上传类
ServletFileUpload upload = new ServletFileUpload(factory);
try {
//上传类接受请求的数据
List<FileItem> items =upload.parseRequest(request);
//遍历数据
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem)iter.next();
if (item.isFormField()) {
//文本域
processFormField(item);
} else {
//文件域
processUploadedFile(item);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
判断是上传的是文本还是文件后的处理方法:
private void processUploadedFile(FileItem item) {
String fieldName = item.getFieldName();
//打印文件域名字
System.out.println("fieldName = " + fieldName);
String fileName = item.getName();
//打印文件名
System.out.println("fileName = " + fileName);
long sizeInBytes = item.getSize();
//打印文件大小
System.out.println("sizeInBytes = " + sizeInBytes);
System.out.println("-----------------------");
//将上传的文件对应输出到一个指定文件夹下面
File file=new File("C:\Users\Administrator\Desktop\upfiles\"+fileName);
try {
item.write(file);
} catch (Exception e) {
e.printStackTrace();
}
}
private void processFormField(FileItem item) {
//打印文本域名字
String name = item.getFieldName();
System.out.println("name = " + name);
String value = item.getString();
//打印文本域的类容
System.out.println("value = " + value);
System.out.println("-----------------------");
}
9.文件上传后要考虑的问题
1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名,可使用UUID+原文件名进行创建文件名称或者当前时间毫秒值getCurrentTime()+原文件名。
3、为防止一个目录下面出现太多文件,要使用hash算法打散存储,做二级目录或者三级目录。
4、要限制上传文件大小的最大值。
5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
文件的下载
1. 在浏览器中,可以直接给个a标签,href指向文件的地址,如果能打开,浏览器自动播放,如果不能打开浏览器会提示下载
2. 如果非要进行下载的话,那么只能用servlet里面的流进行下载!具体的流程如下!
jsp:直接用a标签指向servlet即可,并且附带文件名
<a href="DownloadServlet?filename=mysql-connector-java-5.0.8-bin.jar">下载一个mysql-connector-java-5.0.8-bin.jar</a><br/>
<a href="DownloadServlet?filename=张国荣 - 当年情.mp3">下载一个张国荣 - 当年情.mp3</a><br/>
3. servlet中的写法:七大步骤
//1.获取文件名
String filename = request.getParameter("filename") ;
//2.获取文件的绝对路径
String filePath = this.getServletContext().getRealPath("/dx/"+filename);
//3.处理中文乱码问题
response.setCharacterEncoding("UTF-8");
String userAgent = request.getHeader("User-Agent");
//针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
filename = URLEncoder.encode(filename, "UTF-8");
} else {
//非IE为内核的浏览器:
filename = new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
//4.设置下载的文件名(当文件名有空格的时候要用转义的双引号将文件名包起来 "张国荣 - 当年情.mp3" 不然遇见空格就自动的断开不显示后面部分了)
response.addHeader("content-disposition", "attachment;filename=\""+filename+"\"");
//5.得到下载文件的大小
File file = new File(filePath);
response.setContentLengthLong(file.length());
//6.得到文件下载的类型
response.setContentType(this.getServletContext().getMimeType(filename));
//7.写文件并且读出文件以供下载
ServletOutputStream outputStream = response.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(filePath);
byte[] bs = new byte[1024*100];
int total=-1;
while((total=fileInputStream.read(bs))!=-1){
outputStream.write(bs,0,total);
}
4. 在下载的时候还可以用监听器加上一个防盗链,直接输入地址不让下载,非要本网站内部进行请求转发到下载地址才允许下载!这样就防止别人网站直接盗用我们的下载链接
1. 防盗链定义:所谓防盗链是指防止其他web站点页面通过连接本站点的页面来访问本站点内容,这样对于本站点来说侵犯了本站点的版权
2.非法用户: 常访问本站点页面的链接有三种出处:
(1) 地址栏输入链接地址。如地址栏上输入www.csdn.com/news_100.jsp;
(2)其他站点上的应用程序的页面上通过链接本站点页面资源。
(3)本站点上的页面资源连接到本站点的另外的页面资源。如(www.csdn.com/mulu.jsp页面上有一链接指向www.csdn.com/news_100.jsp);
这三类用户中第一类和第二类通常是非法用户,如果控制这些用户不能访问本站点页面资源
3.如何防盗链:通过调用request.getHeader("Referer");判断访问本页面的链接来自哪里。具体做法:
//防盗链
// 根据Referer 请求头,确定当前请求是否来自本网站
// 如果不是,响应 404, 并狠狠地骂回去
String referer =req.getHeader("Referer");
if(referer!=null&&!"".equals(referer=referer.trim())){
//获取请求的来路应用,http://localhost:8080/testDaoLian/ ---->这个是盗链的例子
int index =referer.lastIndexOf("/");//最后一个‘/’
String substring = referer.substring(0,index);//获取到http://localhost:8080/testDaoLian
index = substring.lastIndexOf("/");
String srcContextPath =substring.substring(index);//获取到/testDaoLian
String contextPath = req.getContextPath();//获取到自己/download
if(!contextPath.equals(srcContextPath=srcContextPath.trim())){
resp.sendError(404, "你这条盗链狗!!!!");
return;
}
}