zoukankan      html  css  js  c++  java
  • JSP实现上传文件(或图片)到MySQL

           这学期JAVAEE课程做了个项目,其中有个功能是在前端输入文本及选择文件,将这些文本和文件传到MySQL里。查了资料,先后用两种方式实现。难点在于如何把前端input标签file类型的文件取到。这里记录了【两种上传文件到指定目录的方式】和【项目展示:JSP实现上传文件到MySQL】。

    参考资料

    [1] Java+mysql本地图片上传数据库及下载示例
    [2] 使用Servlet3.0提供的API实现文件上传到指定位置

    上传文件方式一

           先来讲第一种方式,在项目后期被第二种方式取代了,原因后续会说到。最开始查到了这部分代码,虽然实现了上传指定路径的文件到数据库中,但是得去改浏览器设置。如果不改,获取出来的路径是这样的:C:fakepath文件名。显而易见,获取到的是一个不存在的路径。原因很简单:出于安全性考虑,文件路径可能会暴露你的用户名或者其他内容,浏览器通过fakepath直接代替了其中的路径名,保护用户隐私。有一个解决办法,不过仅限IE浏览器。打开浏览器,在菜单栏依次点击:工具 -> Internet选项 -> 安全 -> 自定义级别 -> 找到“其他”中的“将本地文件上载至服务器时包含本地目录路径”,选中“启用”即可。但作为开发者,我们不能指望用户去这么做,应该通过代码解决这个问题。

    上传文件方式二

           后续查找资料并没有找到有效可用的代码,于是去请教了老师。老师给我提供了一种思路:使用Servlet3.0提供的API,实现文件上传到指定文件夹,再获取该文件的名称,然后加上之前指定的路径,就可以得到该文件的绝对路径了,最后再把文件传到MYSQL中。上传文件至指定目录的代码可参考资料2

    项目展示

    Dynamic Web Project项目结构如下,值得注意的是用到了mysql-connector-java-5.1.46.jar,这里准备了网上分享的链接,没有的话先去下载

    建立数据库和表

    先准备一个数据库和表,这里我用的库名是fileDB,表名是files,以下是建表脚本

    CREATE TABLE files (
    	id INT NOT NULL,
    	-- 文件ID
    	content VARCHAR (100) NULL,
    	-- 文件描述
    	file1 LONGBLOB NULL,
    	-- 文件源1
    	file2 LONGBLOB NULL,
    	-- 文件源2
    	PRIMARY KEY (id)
    );
    

    index.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
    <%
    	String path = request.getContextPath();
    	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
    			+ path + "/";
    %>
    
    <html>
    <head>
    <base href="<%=basePath%>">
    <title>My JSP to MySQL</title>
    </head>
    <body>
    	<form id="myform" name="myform"
    		action="${pageContext.request.contextPath}/UploadFile" method="post"
    		enctype="multipart/form-data">
    		文件描述 <br> <input id="content" name="content" type="text"><br>
    		文件1 <br> <input id="file1" name="file" type="file" value="选择文件"><br>
    		文件2 <br> <input id="file2" name="file" type="file" value="选择文件"><br>
    		<input id="form_submit" name="form_submit" type="submit" value="上传"
    			onclick="submit()">
    	</form>
    </body>
    </html>
    

    web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
      <display-name>JSPtoMySQL</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>
    

    JDBC.java

    package Conn;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class JDBC {
    	// jdbc四大参数,记得修改MySQL的用户名和密码
    	static final public String driver = "com.mysql.jdbc.Driver";
    	static final public String url = "jdbc:mysql://localhost:3306/filedb?useSSL=false";
    	static final public String username = "root";
    	static final public String password = "root";
    
    	static Connection conn = null;
    	static PreparedStatement ps = null;
    	static ResultSet rs = null;
    
    	static {
    		try {
    			Class.forName(driver);
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    			throw new RuntimeException();
    		}
    	}
    
    	public int getNewID() {
    		String sql = "select MAX(id) from files";
    		int id = -1;
    		try {
    			conn = DriverManager.getConnection(url, username, password);
    			ps = conn.prepareStatement(sql);
    			rs = ps.executeQuery();
    			while (rs.next())
    			{
    				id = rs.getInt("MAX(id)");
    			}
    			System.out.println("getMAXID="+id);
    			return id + 1;
    		} catch (SQLException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		} finally {
    			close(conn, ps, rs);
    		}
    	}
    
    	public void insert(int id, String content) {
    		String sql = "insert into files(" + "id, content) " + "values (" + "?, ?);";
    
    		try {
    			conn = DriverManager.getConnection(url, username, password);
    			ps = conn.prepareStatement(sql);
    			ps.setInt(1, id);
    			ps.setString(2, content);
    			ps.executeUpdate();
    		} catch (SQLException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		} finally {
    			close(conn, ps, null);
    		}
    	}
    
    	public int upload_file(int id, String fileUrl, int flag) {
    		String sql = "";
    		// 区分上传的是文件1还是文件2
    		if (flag == 1) {
    			sql = "update files set " + "file1 = ? " + "where id = " + id + ";";
    		} else if (flag == 2) {
    			sql = "update files set " + "file2 = ? " + "where id = " + id + ";";
    		}
    		FileInputStream fis = null;
    		// 读取文件
    		File file = new File(fileUrl);
    		// 记录被影响的行数
    		int success = 0;
    
    		try {
    			// 转换文件为字节流
    			fis = new FileInputStream(file);
    			conn = DriverManager.getConnection(url, username, password);
    			ps = conn.prepareStatement(sql);
    			ps.setBlob(1, fis);
    			success = ps.executeUpdate();
    			System.out.println("受影响的行:"+success);
    			return success;
    		} catch (IOException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		} catch (SQLException e) {
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		} finally {
    			close(conn, ps, null);
    		}
    	}
    
    	// 回收资源
    	public void close(Connection conn, PreparedStatement ps, ResultSet rs) throws RuntimeException {
    		if (rs != null) {
    			try {
    				rs.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    				throw new RuntimeException(e);
    			}
    		}
    		if (ps != null) {
    			try {
    				ps.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    				throw new RuntimeException(e);
    			}
    		}
    		if (conn != null) {
    			try {
    				conn.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    				throw new RuntimeException(e);
    			}
    		}
    	}
    }
    

    UploadFile.java

    package servlet;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Collection;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    import Conn.JDBC;
    //使用@WebServlet配置UploadFile的访问路径
    @WebServlet(name = "UploadFile", urlPatterns = "/UploadFile")
    //使用注解@MultipartConfig将一个Servlet标识为支持文件上传
    @MultipartConfig // 标识Servlet支持文件上传
    public class UploadFile extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		System.out.println("UploadFile开始工作");
    		request.setCharacterEncoding("utf-8");
    		response.setCharacterEncoding("utf-8");
    		response.setContentType("text/html;charset=utf-8");
    		
    		JDBC jdbc = new JDBC();
    		int id = jdbc.getNewID();
    		String content = request.getParameter("content");
    		System.out.println("UploadFile获取到的id:" + id);
    		System.out.println("UploadFile获取到的content:" + content);
    		// 将JSP接收到的文本类型数据插入到数据库中
    		jdbc.insert(id, content);
    		
    		/* 以下代码的作用:上传文件到指定目录,并插入到数据库中  */
    		// 存储路径
    		String savePath = request.getServletContext().getRealPath("/WEB-INF/uploadFile");
    		// 判断文件夹是否存在
    		File file = new File(savePath);
    		// 如果文件夹不存在则创建
    		if (!file.exists() && !file.isDirectory()) {
    			file.mkdir();
    			System.out.println(savePath + "已创建");
    		} else {
    			System.out.println(savePath + "已存在");
    		}
    		// 获取上传的文件集合
    		Collection<Part> parts = request.getParts();
    		System.out.println("parts.size="+parts.size());
    		
    		// num用于标识和记录当前处理的第n个文件,success用于记录成功插入文件的次数
    		int num = 1;
    		int success = 0;
    		for (Part part : request.getParts()) {
    			// 只处理上传文件区段
    			if (part.getName().startsWith("file")) {
    				String fileName = getFileName(part);
    				// 防止只上传文件2,不上传文件1出现的bug
    				if (fileName.length()==0) {
    					num++;
    					continue;
    				}
    				// 把文件写到指定路径
    				part.write(savePath + File.separator + fileName);
    				String fileUrl = savePath + "\" + fileName;
    				System.out.println(fileName+"已上传");
    				// 向数据库表中插入两个文件
    				success += jdbc.upload_file(id, fileUrl, num++);
    			}
    		}
    
    		PrintWriter out = response.getWriter();
    		out.println("数据插入成功,其中包括" + success + "个文件");
    		//response.sendRedirect("index.jsp");
    		out.flush();
    		out.close();
    	}
    	
    	private String getFileName(Part part) {
            String header = part.getHeader("Content-Disposition");
            String fileName = header.substring(header.indexOf("filename="") + 10, header.lastIndexOf("""));
            header.lastIndexOf(""");
            return fileName;
            }
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		this.doGet(request, response);
    	}
    }
    
  • 相关阅读:
    TFS实现需求工作项自动级联保存
    Oracle PL/SQL Developer集成TFS进行团队脚本文件版本管理
    TFS2017持续集成构建
    TFS 测试用例步骤数据统计
    精细化容量管理的设备成本优化之路
    腾讯Web工程师的前端书单
    React Native For Android 架构初探
    SQL系列(八)—— 分组(group by)
    SQL系列(七)—— 相似(like)
    SQL系列(六)—— 过滤(where)
  • 原文地址:https://www.cnblogs.com/ast935478677/p/13160853.html
Copyright © 2011-2022 走看看