本次博客主要记录的是如何基于JavaWeb实现图片上传的功能,小编查看过网上许多篇博客,但是发现代码过于冗杂(因为都是带有其他功能实现的,可能我水平还不够),所以我特意整理了一下自己的思路,并为大家讲解一下如何实现图片的上传/展示的操作,小编水平一般,大神勿喷......

首先我们先来看一下实现的效果,我们先选择图片:

doc插入图片 java javaweb中如何添加图片_IO流

 其次,选择图片进行提交,上传图片到数据库,点击提交即可跳转到我们的展示页面,如下图所示:

doc插入图片 java javaweb中如何添加图片_JavaWeb_02

 首先,我先展示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;
    }
}