本次博客主要记录的是如何基于JavaWeb实现图片上传的功能,小编查看过网上许多篇博客,但是发现代码过于冗杂(因为都是带有其他功能实现的,可能我水平还不够),所以我特意整理了一下自己的思路,并为大家讲解一下如何实现图片的上传/展示的操作,小编水平一般,大神勿喷......
首先我们先来看一下实现的效果,我们先选择图片:
其次,选择图片进行提交,上传图片到数据库,点击提交即可跳转到我们的展示页面,如下图所示:
首先,我先展示Dao层的代码,数据库的表只需要定义一个主键id和blob类型的字段即可(blob支持上传的图片大小比较小,或者可以设置为mediumblob.......或者更大的字段大小),本次代码实现主要是通过IO流的方式进行的:
PhotoDao.java代码:
package dao;
import domain.PhotoBean;
import utils.JDBCUtils;
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class PhotoDao {
public List<PhotoBean> findAll(String path){
List list = new ArrayList();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select * from photo";
pstmt = conn.prepareStatement(sql);
//执行查询的sql语句
rs = pstmt.executeQuery();
while (rs.next()){
PhotoBean photoBean = new PhotoBean();
photoBean.setId(rs.getInt("id"));
//读取数据库中的blob字段,用一个Bolb类的blob对象接收
Blob blob = rs.getBlob("url");
//通过blob字段的数据获取输入字节流(二进制数据流)
InputStream in = blob.getBinaryStream();
//把这个in的收入字节流输入到服务器的image目录下
// 首先给图片重命名
String filename = System.currentTimeMillis() + ".png";
//把输入字节流写入到文件中,这里的path是调用方法时传进来的参数
File file = new File(path,filename);
FileOutputStream out = new FileOutputStream(file);
//采用循环的方式进行读写
byte[] buf = new byte[1024];
int length = 0;
//边读边写,读完为止
while((length = in.read(buf)) != -1){
//这里是写出
out.write(buf,0,length);
}
//关闭流
out.close();
in.close();
//写出成功后将图片名称设置到photoBean对象
photoBean.setUrl(filename);
list.add(photoBean);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, pstmt, conn);
}
return list;
}
public void addPhoto(PhotoBean photoBean) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into photo values(null,?)";
pstmt = conn.prepareStatement(sql);
//读取字节文件
InputStream in = new FileInputStream(photoBean.getUrl());
/**
* 设置blob字段
*/
pstmt.setBlob(1,in);
//执行sql
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(pstmt, conn);
}
}
}
上传图片的UploadServlet.java代码:
package photo;
import dao.PhotoDao;
import domain.PhotoBean;
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 org.apache.commons.io.FilenameUtils;
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.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
Map<String,Object> map = new HashMap<String,Object>();
String test = request.getParameter("file");
System.out.println(test);
//首先判断表单是否支持文件上传,即是否有:enctype="multipart/form-data"
boolean isMutipart = ServletFileUpload.isMultipartContent(request);
if(!isMutipart){
throw new RuntimeException("表单必须是enctype='multipart/form-data'类型的");
}
//创建一个DiskFileItemFactory工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建一个ServletUpload核心对象
ServletFileUpload sfu = new ServletFileUpload(factory);
//指定编码格式为utf-8
sfu.setHeaderEncoding("utf-8");
//解析request对象得到一个表单项FileItem的集合
PhotoBean photoBean = new PhotoBean();
try {
List<FileItem> fileItems = sfu.parseRequest(request);
//我们遍历表单的数据内容
for (FileItem fileItem : fileItems) {
if(!fileItem.isFormField()){ //处理上传的表单项
//获取文件存盘的目录绝对路径
String uploadPath = this.getServletContext().getRealPath("image");
File file = new File(uploadPath);
//判断文件是否存在,如果不存在就创建文件
if (!file.exists()) {
file.mkdirs();
}
//获取文件上传的名称
String filename = fileItem.getName();// 文件名称,可能带路径
filename = FilenameUtils.getName(filename);// 文件名称,不带路径
//根据路径创建一个file对象
File uploadFile = new File(uploadPath,filename);
//上传文件,然后删除临时文件
fileItem.write(uploadFile);
//设置url给对象
photoBean.setUrl(uploadPath + "/" + filename);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
PhotoDao photoDao = new PhotoDao();
photoDao.addPhoto(photoBean);
response.sendRedirect(request.getContextPath() + "/photoServlet");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
从数据库中提取图片返回到前端的PhotoServlet.java代码:
package photo;
import dao.PhotoDao;
import domain.PhotoBean;
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.File;
import java.io.IOException;
import java.util.List;
@WebServlet("/photoServlet")
public class PhotoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//首先创建一个image路径D:\IDEA_WebSpace\ID25\out\artifacts\ID25_war_exploded\image
String path = this.getServletContext().getRealPath("image");
//如果不是idea的服务器目录则无法使用
// String path = "D:\\IDEA_WebSpace\\ID25\\web\\image";
//为了方便检测,我们打印一下路径
System.out.println(path);
//如果没有这个文件夹就创建文件
File file = new File(path);
if (!file.exists()){
//不存在则创建
file.mkdirs();
}
//如果存在就直接执行在这部分代码
PhotoDao photoDao = new PhotoDao();
//把路径传给dao层,用于把数据库的图片保存到本地路径
List<PhotoBean> list = photoDao.findAll(path);
request.setAttribute("photo",list);
request.getRequestDispatcher("/photo.jsp").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
前端Jsp的两个页面upload.jsp、photo.jsp:
upload.jsp:
<%--
upload.jsp
Created by IntelliJ IDEA.
User: Simon
Date: 2019/11/25
Time: 9:50
To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--一定要记得使用post的方式--%>
<form action="${pageContext.request.contextPath}/uploadServlet"
enctype="multipart/form-data" method="post">
添加图片到服务器<input type="file" name="file" multiple="multiple">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
photo.jsp:
<%--
Created by IntelliJ IDEA.
User: Simon
Date: 2019/11/23
Time: 19:26
To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图片保存数据库的操作</title>
<style>
img{
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<table>
<c:forEach items="${requestScope.photo}" var="student">
<tr>
<td>${student.id}</td>
<td><img src="image/${student.url}"></td>
</tr>
</c:forEach>
</table>
</body>
</html>
要导入的两个jar包分别是:commons-fileupload-1.2.2.jar、commons-io-2.2.jar:
百度网盘地址:https://pan.baidu.com/s/1YfyWKR_yR04CkPlZRYf3BA
附录
JavaBean:PhotoBean.java代码
package domain;
public class PhotoBean {
private int id;
private String url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}