servlet文件上传
注意事项:在写了响应后,若后面还需要执行代码,需要添加return;
apach的servlet3.0提供了文件上传的功能.
**在客户端中的jsp如何上传文件:**使用form标签
使用input标签type的file属性
form表单中的的enctype必须加:使用二进制的方式进行传输,否则不能进行传输
<form action="/registe" method="post" enctype="multipart/form-data">
账号:<input type="text" name="username"><br>
头像1:<input type="file" name="headImg"><br>
<input type="submit" name="注册">
在服务器获取客户端上传的文件:
| 方法 | 作用 |
|---|---|
| req.getPart(String name) | 获取请求中指定名字的单个文件 |
| req.getParts() | 获取请求中所有的文件 |
返回的getPart(Sting name)中有以下的方法可以使用
| 方法 | 作用 |
|---|---|
| getContentType() | 获取文件的类型: img/png |
| getSize() | 获取文件大小: 70340 |
| getSubmittedFileName() | 获取文件的名字: 小狗.png |
| getName() | 获取请求的属性: headImg |
| write(String filename) | 将接收到的文件保存在磁盘中 |
获取文件的细节
1.解决文件上传同名的问题
由于用户不关心上传后的文件名称,所以文件的名称可以不和源文件相同,所以我们只需要改变文件的名字就可以解决文件同名的问题,后缀名不用修改,只需要进行获取
//使用UUID生成唯一的文件名
String filename = UUID.randomUUID().toString();
//获取源文件的名字,首先得取到文件
headImg = req.getPart("headImg");
//获取这个文件的名字
String submittedFileName = headImg.getSubmittedFileName()
//得到"."在文件中最后出现的一次索引lastIndexOf
int index = submittedFileName.lastIndexOf(".");
//从文件名中根据索引截取扩展名subString
String ext = submittedFileName.substring(index);
//动态获取项目中的路径(使用SservletContext中的RealPath获取项目的绝对路径)
String realPath = req.getServletContext().getRealPath("/files");
//将上传的文件存在项目下的文件中,避免使用绝对路径
headImg.write(realPath+"\\"+filename+ext);
获取文件的时候需要自己手动部署项目
选择字节码输出目录
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXxaeNPW-1684929761373)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417212802286.png)]](https://img-blog.csdnimg.cn/889c98b4932240f58e9977343360e758.png)
添加输出目录
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sgq117zG-1684929761374)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417212824654.png)]](https://img-blog.csdnimg.cn/7fabeef494de432480140f22c74844d7.png)
修改tomcat的部署,使用自己的项目进行部署
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5erWDjGb-1684929761375)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417212951526.png)]](https://img-blog.csdnimg.cn/43d1fd3df24a4533b3677164b4b040fd.png)
用户上传的文件类型不符合解决办法
使用文件类型进行判断getPar的方法:headImg.getContentType().startsWith(“image/”)
servlet应该将错误信息响应给用户
if(!headImg.getContentType().startsWith("image/")){
//告知用户,文件类型不正确
//共享错误信息
req.setAttribute("errMsg","文件类型不正确");
回到注册页面
req.getRequestDispatcher("/register.jsp").forward(req,resp);
return;//结束当前方法的执行
}
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GOnLZ8cM-1684929761375)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417213601867.png)]](https://img-blog.csdnimg.cn/f4d720cac4624c02ac6a9849c1951cff.png)
限制用户上传文件的大小(servlet中进行限制)
以前使用书写java代码,现在使用注解的方式()@MultipartConfig进行限制文件上传的大小,
| 方法 | 作用 |
|---|---|
| maxFileSize=1024*… | 限制单个文件的大小 |
| maxRequestSize=1024*… | 限制请求数据的大小 |
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyKxY0bP-1684929761376)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417214044690.png)]](https://img-blog.csdnimg.cn/163f36d552364362a4780fa0e9260527.png)
用户文件的下载
这里的文件下载分别下载普通目录下的和WEB-INF下的文件,由于WEB-INF下的文件普通用户不能进行访问,所以只有通过使用servlet进行提取文件
1.普通用户文件的下载
在jsp中直接点击链接就可以进行下载,不需要通过java代码的处理
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0VM1VItt-1684929761376)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417214550839.png)]](https://img-blog.csdnimg.cn/7b2a3b242d184ad9ac6c6e124bf26140.png)
2.会员进行登录下载
jsp页面需要进行跳转的时候应该带上文件的名称拼接在路径上,使用servlet进行处理
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6lB8fPWc-1684929761377)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20230417214847380.png)]](https://img-blog.csdnimg.cn/65dc4cae90934ce89ec1b968759bc125.png)
servlet的处理如下:
//获取请求中下载文件的名字
String filename =req.getparameter("filename")
//找到WEB-INF/file在磁盘上的路径,使用 req.getServletContext().getRealPath()
String realPath = req.getServletContext().getRealPath("/WEB-INF/files");
//用户下载包的时候不能识别中文包的名字,需要将文件名设成浏览器识别的字符集
String s = new String(filename.getBytes(StandardCharsets.UTF_8), "ISO-8859-1");
//在响应头里面告诉浏览器下载文件的名字是什么,使用setHeader进行设置
resp.setHeader("Content-Disposition", "attachment;filename="+s);
//找到磁盘上的文件并响应给浏览器,使用Files的copy方法获取文件输出流,响应给浏览器
Files.copy(Path source, OutputStream out)//该方法的语法
//将source路径指定的文件内容复制到out指定的输出流中。
Files.copy(Path.get(realpath,filename),resp.getOutputStream)
java
Files.copy(Path source, OutputStream out)//该方法的语法
//将source路径指定的文件内容复制到out指定的输出流中。
```java
Files.copy(Path.get(realpath,filename),resp.getOutputStream)













![[极客大挑战 2019]HardSQL1](https://img-blog.csdnimg.cn/img_convert/371f807c75ee420b9af63daf209682b8.png)




