文件上传
UploadServlet:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;UTF-8");
//接收参数
//文件描述
String filedesc = request.getParameter("filedesc");
System.out.println("文件描述:"+filedesc);
//接收文件
Part part = request.getPart("uploadfile");
long fileSize = part.getSize();//文件大小
String inputName = part.getName();//input中的name属性名称
System.out.println("文件大小:"+fileSize);
System.out.println("input中的name属性名称:"+inputName);
//获得上传的文件名称
String header = part.getHeader("Content-Disposition");
//返回f字母所在的位置
int idx = header.lastIndexOf("filename=\"");
//filename="xxx.xxxx";xxx.xxx的位置是idx+10~header.length()-1;
String fileName = header.substring(idx+10, header.length()-1);
System.out.println("文件名:"+fileName);
//获得文件内容
InputStream is = part.getInputStream();
//获得文件上传位置uploadFiles的路径:xxx/xxx/uploadFiles
String path = this.getServletContext().getRealPath("/uploadFiles");
//获得唯一文件名,不重复
String uuidFileName = UUIDUtils.getUUIDFilename(fileName);
//path是uploadFiles的路径,UploadUtils.getPath(uuidFileName)获取的是文件在uploadFiles里面的路径。
String realPath = path + UploadUtils.getPath(uuidFileName);
//new File(String pathname):通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File file = new File(realPath);
//如果file不存在,在这个路径下创建文件
if(!file.exists()) {
file.mkdirs();
}
//在realPath下创建名称为uuidFileName的文件。
OutputStream os = new FileOutputStream(realPath+"/"+uuidFileName);
byte[] b = new byte[1024];
int len = 0;
//read:从输入流读取数据的下一个字节。 值字节被返回作为int范围0至255 。 如果没有字节可用,因为已经到达流的末尾,则返回值-1 。
while((len = is.read()) != -1) {
os.write(b, 0, len);
}
os.close();
}
UploadUtils:
目录分离算法解决一个目录下文件过多 :
- 使用唯一文件名.hashCode(); – 得到一个代表当前这个文件的int类型值.
- int类型占4个字节32位.可以让hashCode值&0xf; 得到一个int值,用这个int值作为一级目录.
- 让hashCode右移4位 &0xf ;得到一个int值,用这个int值作为二级目录.依次类推.
package utils;
/**
* UploadUtils.getPath(uuidFileName)获取的是文件在uploadFiles里面的路径。
* @author 45度炸
*
*/
public class UploadUtils {
public static String getPath(String uuidFileName) {
//唯一文件名.hashcode()
int code1 = uuidFileName.hashCode();
int d1 = code1 & 0xf; //获得一级目录
int code2 = code1 >>> 4; //右移四位
int d2 = code2 & 0xf; //获得二级目录
return "/"+d1+"/"+d2;
}
}
UUIDUtils:
package utils;
import java.util.UUID;
public class UUIDUtils {
public static String getUUID() {
return UUID.randomUUID().toString().replace("-","");
}
/**
* 获取随机文件名
* @param fileName
* @return
*/
public static String getUUIDFilename(String fileName) {
return UUID.randomUUID().toString().replace("-", "")+"_"+fileName;
}
}
upload.jsp:
- 表单的提交的方式必须是POST.
- 表单中需要有文件上传的表单元素:这个元素这个元素必须有name属性和值:
- 表单的enctype属性的值必须是multipart/form-data.
<body>
<form action="/Web16/UploadServlet" method="post" enctype="multipart/form-data">
<table border="1px" width="600">
<tr>
<td>文件描述</td>
<td><input type="text" name="filedesc"></td>
</tr>
<tr>
<td>文件上传</td>
<td><input type="file" name="uploadfile"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="上传"></td>
</tr>
</table>
</form>
</body>
异步请求的Servlet
package Async;
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 异步请求的Servlet
*/
public class AsyncServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext context = request.startAsync(request, response);
context.start(new MyRunnable(context));
//输出1-10
for(int i = 0;i < 10;i++) {
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public 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
//输出a-z
public void run() {
for(char i='a';i < 'z';i++) {
try {
context.getResponse().getWriter().print(i);
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}