也就是在浏览器上,上传图片并回显,效果如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--enctype属性能把文件内容封装到请求体,没有这个只能上传文件名-->
<form action="/day58/FileUpload" enctype="multipart/form-data" method="post">
<input type="file" name="image"><br><!--用来上传文件的标签-->
<input type="text" name="username">用户名<br>
<input type="submit"><!--把form表单内容封装到请求报文-->
</form>
<img src="">
</body>
</html>
上传界面对应HTML
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.*;
public class FileUploadUtils {
//这是解析请求报文的函数
public static Map<String, Object> parseRequest(HttpServletRequest request) {
//创建生产DiskFileItem对象的工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置临时文件缓冲区,当某些上传文件过大,边上传边放入缓冲区
File repository = (File) request.getServletContext().getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);//把上一步的配置放入工厂
//利用factory拿到文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传中文文件名出现乱码
upload.setHeaderEncoding("utf-8");
//设置允许上传的文件最大空间,单位字节,一定要在parseRequest()前设置
upload.setFileSizeMax(100000);
//用来存表单里的key-value,为了后面用BeanUtils把Map封装到JavaBean类里
Map<String, Object> map = new HashMap<>();
try {
//解析请求体里的表单,每一个有name的input,对应一个FileItem
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iterator = items.iterator();
while (iterator.hasNext()) {//遍历表单数据
FileItem item = iterator.next();
//要对普通表单数据和上传的文件区别对待
if (item.isFormField()) {//这个input是普通表单数据
processFormField(item, map);
} else {//这个input是上传文件
processUploadFile(item, map, request);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
return map;
}
//对上传文件的处理函数
private static void processUploadFile(FileItem item, Map<String, Object> map, HttpServletRequest request) {
String key = item.getFieldName();//得到<input>属性name的值
String fileName = item.getName();//得到文件名 1.jpg
//老版edge获得的文件名是C:\Users\1.jpg,要去掉前缀,只留下1.jpg
int index = fileName.lastIndexOf("\\");//找到最后一个\的下标
//返回从(index+1)位置开始到结束的部分字符串
fileName = fileName.substring(index + 1);
//设置上传文件在服务器存储时的文件名
// 为了防止重复,新文件名=随机序列+老文件名
String random = UUID.randomUUID().toString();
//老文件名放后面,因为文件有后缀名(.txt)
fileName = random + "-" + fileName;
String contentType = item.getContentType();//获得文件类型(image/jpeg)
boolean isInMemory = item.isInMemory();//判断数据内容是存储在内存中,还是临时文件中,内存中返回true
long sizeInBytes = item.getSize();//返回上传文件大小(以字节为单位)
//为了防止服务器收到的文件太多,顺序查找文件速度慢,要把文件分散存储
int hashCode = fileName.hashCode();
String hexString = Integer.toHexString(hashCode);
char[] chars = hexString.toCharArray();
String basePath = "image";
for (char aChar : chars) {
basePath = basePath + "/" + aChar;
}
String relativePath = basePath + "/" + fileName;//前端访问图片的相对地址
//文件在存放在硬盘的绝对路径,
String absolutePath = request.getServletContext().getRealPath(relativePath);
File file = new File(absolutePath);
if (!file.getParentFile().exists()) {//判断该文件的父目录是否存在
file.getParentFile().mkdirs();//不存在就创建新的文件夹
}
try {
item.write(file);//将文件写入磁盘
map.put(key, relativePath);
//或者得到数据输入流,从而读取上传数据:InputStream uploadStream = item.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
//对于普通form表单,一般只对<input>标签的key-value感兴趣
private static void processFormField(FileItem item, Map<String, Object> map) {
String key = item.getFieldName();//得到<input>的key/name
String value = null;
try {
value = item.getString("utf-8");//防止value有中文乱码
map.put(key, value);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(key + ":" + value);
}
}
文件上传的工具类
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@WebServlet("/FileUpload")
public class FileUpload1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");//设置响应报文的编码格式为utf-8并告诉浏览器
//判断前端页面有没有文件上传属性enctype="multipart/form-data"
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
response.getWriter().println("没有文件上传属性");
}
Map<String, Object> map = FileUploadUtils.parseRequest(request);
//回显的操作建议写在另外一个servlet中
//用context域共享map对象
getServletContext().setAttribute("user", map);
response.getWriter().println("上传成功,信息即将进行回显....");
//2s后刷新到显示servlet
response.setHeader("refresh", "2;url=" + request.getContextPath() + "/viewshow");
}
}
处理文件上传的servlet
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet("/viewshow")
public class ViewServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决响应报文有中文会乱码,一定要加不然图片都不能正常显示
response.setContentType("text/html;charset=utf-8");
Map user = (HashMap) getServletContext().getAttribute("user");
response.getWriter().println("<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>");
response.getWriter().println("<div>" + user.get("username") + "</div>");
response.getWriter().println("<div><img src='" + request.getContextPath() + "/" + user.get("image") + "'></div>");
response.getWriter().println("</body>\n" +
"</html>");
}
}
完成回显的servlet