首先要上传就要写个表单,代码如下:
<form action="/TestUpload/UploadServlet" method="post" enctype="multipart/form-data">
账户:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
头像:<input type="file" name="userhead"><br>
<button>提交数据</button>
</form>
上面的enctype属性如果不写就会直接把文件名作为数据提交,写了后会把表单里面所有的数据作为流的方式上传。用火狐抓包可以看到
把文件的二进制数据上传了在请求头中有这样的数据
说明每一个参数是按照--------------15381157045721这行东西分割的
抓包可能有错误,可以在写代码验证下读取的到底是不是和抓包抓到的一样
InputStream in = request.getInputStream();
int i=in.read();
while(i!=-1) {
char c = (char)i;
System.out.print(c);
i=in.read();
}
在doget方法中写上面的代码后输出结果为
看来servlet中接收的就是这个东西,既然获取到这个东西理论上是可以自己手动分割后读取数据的,当读到文件时用io流就可以把文件写入。但是好在有人早就写好了工具类,拿来用就完了。
使用file upload工具上传
思路:
1.导入fileupload包和io包(fileupload实现过程中会用到io包)
2.执行简单的三条语句
3.获得到一个集合(FileItem对象)
4.遍历集合
5.如果当前FileItem项时普通项
建立一个map集合存储数据
将普通项上name的属性的值作为键,获取到的内容作为值放到map中
6.如果当前FileItem为上传项
通过FileItem获取到输入流对象,通过输入流可以获取到图片的二进制数据,在服务端创建一个空文件(后缀必须一致)
建立和空文件对应的输出流
将输入流的数据刷到输出流中
释放资源
将name属性的值作为键,复制后文件的路径作为值存入map
7.利用BeanUtils将map中的数据映射到一个实体里面
8.用持久层将上传的数据保存到数据库中
代码实现
Map<String, String> map = new HashMap<String, String>();
try {
// DiskFileItemFactory是创建FileItem对象的工厂
DiskFileItemFactory fac = new DiskFileItemFactory();
// ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象
ServletFileUpload sf = new ServletFileUpload(fac);
// 解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。
List<FileItem> list = sf.parseRequest(request);
// 遍历集合
for(FileItem item:list) {
// 是表单吗
if(item.isFormField()) {
map.put(item.getFieldName(), item.getString("utf-8"));
}else {
// 是上传项
InputStream in = item.getInputStream();
// 获取当前项目的真实路径下面的某个文件夹
String realPath = this.getServletContext().getRealPath("/images/img");
// 创建文件第一个参数是路径,第二个参数是文件名
File file = new File(realPath, item.getName());
// 如果file不存在就创建
if(!file.exists()) {
file.createNewFile();
}
// 创建与文件对应的输出流
OutputStream os = new FileOutputStream(file);
// 输入流和输出流对接
IOUtils.copy(in, os);
// 关闭输入流和输出流
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(os);
map.put("userhead", "images/img"+item.getName());
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
这样就能够上传成功了,下面还有两个引发的问题,因为目录是tomcat项目中的,当项目重新编译时会清空里面的数据,所以图片也会消失,更改文件夹即可解决。还有就是文件过多会影响性能,不应将所有文件放在一个目录中,这点暂时还不会解决。