基础不牢固,地动山摇!
最近做项目上传文件出现很多bug,回来看视频学习
文件上传:
使用的jar包,apache:commons-fileupload,他又依赖于commons-io.jar包,需要将两个jar包引入。
前台jsp:
后台Servlet:
<input type="file" name="picture"/>
注意:表单提交方式必须是post,因为文件是特别的大,地址栏会放不下,它只能存放大概4K的数据。在表单中必须增加一个属性enctype="multipart/form-data"
。
注意的问题:
上传目录 upload
1.如果修改代码则在tomcat启动时,会被删除
原因:当修改代码的时候,tomcat会重新编译一份class,并重新部署(重重新创建各种目录)
2.如果不改代码,则不会删除
原因:没有修改代码,class仍然是之前的class
因此为了防止上传目录丢失:a.虚拟路径 ,b.更换上传目录到非tomcat目录.
限制上传:
类型,大小。
具体代码如下:
(1)上传Servlet:
public class UploadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=UTF-8");
// 上传
// request.getParameter("sname")
try {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {// 判断前台的form是否有 mutipart属性
// FileItemFactory factory = new DiskFileItemFactory();
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//设置上传文件时用到的临时文件大小,factory(因为上传文件是先一点点上传到缓冲区,然后再放文件)
factory.setSizeThreshold(50000);//设置临时的缓存文件是
factory.setRepository(new File("D:\\study\\uploadtemp"));//设置临时文件的位置
//控制上传文件的大小~KB upload
upload.setSizeMax(100000);//单位是字节B
Thread.sleep(3000);
// 通过parseRequest解析form中的所有请求字段,并保存到 items集合中(即前台传递的sno sname
// spicture此时就保存在了items中)
List<FileItem> items = upload.parseRequest(request);
// 遍历items中的数据(item=sno sname spicture)
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
String itemName = item.getFieldName();
int sno = -1;
String sname = null;
// 判断前台字段 是普通form表单字段(sno sname),还是文件字段
// request.getParameter() -- iter.getString()
if (item.isFormField()) {
if (itemName.equals("sno")) {// 根据name属性 判断item是sno sname 还是spicture?
sno = Integer.parseInt(item.getString("UTF-8"));
} else if (itemName.equals("sname")) {
sname = item.getString("UTF-8");
} else {
System.out.println("其他字段xxx.....");
}
} else {// picture
// 文件 上传
// 文件名 getFieldName是获取 普通表单字段的Name值
// getName()是获取 文件名
String fileName = item.getName();//a.txt a.docx a.png
String ext = fileName.substring(fileName.indexOf(".")+1 );
if(!(ext.equals("png") ||ext.equals("gif")||ext.equals("jpg"))){
System.out.println("图片类型有误,格式只能是");
return; //终止
}
// 获取文件内容 并上传
// 定义文件路径:指定上传的位置(服务器路径)
// 获取服务器路径D:\\study\\apache-tomcat-8.5.30\\wtpwebapps\\UpAndDown\\upload
// String path =request.getSession().getServletContext().getRealPath("upload");
String path = "D:\\study\\upload";
File file = new File(path, fileName);
item.write(file);// 上传
System.out.println(fileName + "上传成功!");
return;
}
}
}
}
catch (FileUploadBase.SizeLimitExceededException e) {//SizeLimitExceededException是FileUploadException的一个子类
System.out.println("上传文件大小超过限制");
}
catch (FileUploadException e)
{
e.printStackTrace();
}
// 解析请求
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
JSP表单:
<body>
<form action="UploadServlet" method="post" enctype="multipart/form-data">
学号:<input type="sno"/><br/>
姓名:<input type="sname"/><br/>
上传照片:<input type="file" name="picture"/><br/>
<input type="submit" value="注册"/>
</form>
<a href="DownLoadServlet?filename=酷酷.jpg">酷酷</a>
</body>
文件的下载:
下载不需要任何的jar包,
a.前端发一个请求(地址a form),请求Servlet ,
b.Servlet 通过文件的地址,将文件转为输入流,读到Servlet 中,
c.通过输入流 将已经转为输入流的文件,输出给用户
注意:下载文件需要设置两个 响应头
response.addHeader("content-Type", "application/octe-stream");//任意二进制文件类型
response.addHeader("content-Disposition", "attachement;fileName="+fileName);//fileName包含了文件后缀
下载时可能会出现文件名乱码:
IE、360谷歌等浏览器设置方式:
response.addHeader("content-Disposition", "attachment;fileName="+URLEncoder.encode(fileName,"UTF-8"));
火狐浏览器比较复杂,首先要给文件名加上前缀和后缀
前缀:=?UTF-8?B?
外层String构造方法
中间:Base64.encode
后缀:?=
如下:
response.addHeader("content-Disposition", "attachment;fileName=?UTF-8?B?"+new String( Base64.encodeBase64(fileName.getBytes("UTF-8")))+"?=" );
具体下载代码如下:
public class DownLoadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//获取需要下载的文件名
String fileName =request.getParameter("filename");
//对于不同浏览器,进行不同的处理
//获取客户端的User-Agent:信息
String agent = request.getHeader("User-Agent");
if(agent.toLowerCase().indexOf("firefox")!= -1){
//火狐谷歌等
response.addHeader("content-Disposition", "attachment;fileName=?UTF-8?B?"+new String( Base64.encodeBase64(fileName.getBytes("UTF-8")))+"?=" );
}else{
//IEx下载文件名乱码问题
response.addHeader("content-Disposition", "attachment;fileName="+URLEncoder.encode(fileName,"UTF-8"));//fileName包含了文件后缀
}
//下载文件需要设置响应消息头
response.addHeader("content-Type", "application/octe-stream");//任意二进制文件类型
//Servlet 通过文件的地址,将文件转为输入流,读到Servlet 中,
InputStream in = getServletContext().getResourceAsStream("/res/"+fileName);
//通过输入流 将已经转为输入流的文件,输出给用户
ServletOutputStream out = response.getOutputStream();
byte[] bs = new byte[1024]; //不断向缓冲区里面放
int len = -1;
while((len=in.read(bs)) != -1){
out.write(bs,0,len);
}
out.close();
in.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}