Jsp+Servlet+Commons-Upload实现无刷新文件上传到MySql表存为Blob格式,及个人心得

这篇博客总结了使用Jsp+Servlet+Apache Commons-Upload组件实现无刷新文件上传到MySQL数据库中Blob字段的过程。重点包括:Servlet代码实现,iframe的使用以实现无刷新,设置ServletFileUpload的setSizeMax参数,处理Java内存溢出问题,调整MySQL的max_allowed_packet参数,以及解决因字符集导致的SQL语法错误。同时分享了在遇到问题时的解决方案和数据库策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

啥也不说了,网上软文太多,总结自己写的一些经验总结

1、首先是MySql的连接类

没啥好说的

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class MySql {
	Connection conn;

	public Connection openDB() {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8";
			String username = "root";
			String password = "123456";
			conn = DriverManager.getConnection(url, username, password);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	public boolean close() {
		try {
			if (conn == null) {
				return false;
			} else {
				conn.close();
				return true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
	}
}

2、然后是用到的Jsp文件

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>

</head>
<body>   
  
<form action="UploadBlob.bw" id="form1" name="form1" encType="multipart/form-data"   method="post" target="hidden_frame" >   
     <input type="file" id="file" name="file">   
     <INPUT type="submit" value="上传文件">
     <br>
     <font color="red">请上传文件</font>                 
     <iframe name='hidden_frame' id="hidden_frame" style="display: none;"></iframe>   
</form>
  
</body>
</html>
3、MySQL语句

DROP TABLE IF EXISTS `xxx`;
CREATE TABLE `xxx` (
  `bid` int(11) NOT NULL AUTO_INCREMENT,
  `bfile` longblob,
  PRIMARY KEY (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

DROP PROCEDURE IF EXISTS `insertBlob`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `insertBlob`(`arg_file` longblob)
BEGIN

	INSERT INTO abc.xxx(bfile) VALUES(arg_file);

END



4、Servlet代码

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;

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 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;

@WebServlet("/UploadBlob.bw")//需要servlet3支持
public class UploadBlob extends HttpServlet {
	MySql mySql;
	ResultSet rs;
	private static final long serialVersionUID = 1L;

	public UploadBlob() {
		super();
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost");
		try {
			
			File tempfile = new File(System.getProperty("java.io.tmpdir"));
			DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
			diskFileItemFactory.setSizeThreshold(50000);
			diskFileItemFactory.setRepository(tempfile);
			ServletFileUpload fu = new ServletFileUpload(diskFileItemFactory);
			fu.setSizeMax(999999999);//这个要根据实际需求设定大小,我这个值貌似是最大的了
			List fileItems = fu.parseRequest(request);
			Iterator i = fileItems.iterator();
			try {
				
				while (i.hasNext()) {
					FileItem fi = (FileItem) i.next();
					if (!fi.isFormField()) {
						MySql mySql = new MySql();
						Connection conn = mySql.openDB(getServletContext());
						String sqlSelect = "{call `abc`.`insertBlob` (?)}";
						CallableStatement cs = conn.prepareCall(sqlSelect);
						InputStream stream = new BufferedInputStream(fi.getInputStream());
						cs.setBinaryStream("arg_file", stream);//虽然数据库是blob格式但这里要这么写
						int result = cs.executeUpdate();
						System.out.println(result);//输出结果
					}
				}
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				if (rs != null) {
					try {
						rs.close();
					} catch (Exception e2) {

					}
				}
				if (mySql != null) {
					mySql.close();
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}
}

虽然上面的代码看上去不太难,但实际操作中会报各种错的个人总结了一些,从表向里说下:

1、注意form表单里的target指定的是iframe的name属性

      无刷新上传文件的实质就是iframe的使用,将display设置成none就不可见了

2、Apache的CommonsUpload组件中的ServletFileUpload对象setSizeMax需要按实际需求设定,否则会失败或降低性能

3、Java上传大文件出现java.lang.OutOfMemoryError: Java heap space错误是表示超过JVM的最大设置了,如何设置稍后补上



4、MySql出现Data truncation: Data too long for column  '列名' 是因为你的数据库列的blob格式设置的太小了

      MySql有如下blob类型:

TinyBlob 最大 255
Blob 最大 65K
MediumBlob 最大 16M
LongBlob 最大 4G

所以要制定数据库文件政策,一般都要求15M吧,呵呵

5、MySql出现 com.mysql.jdbc.PacketTooBigException: Packet for query is too large (11499581 > 8388608)

    表示MySql接受的上传大小低于你的实际传送文件大小,所以要设定MySql的 max_allowed_packet参数,稍后补上

修改MySql安装目录下my.ini(linux为安装目录下的my.cnf

添加set-variable=max_allowed_packet=20M,重启服务就可以更改MySql允许的上传包大小了


不修改设定的话,10M内的文件是没问题的

6、MySql在插入blob对象时报

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '??ù??L×>·X?N??\0:?/?p???*Rm?è?SWe??óYP69‰?I?9? l6yK?V1>Cí?u??5??R?#???\' at line 1这类错误的解决办法
在数据库连接字符串的数据库名后加?useUnicode=true&characterEncoding=utf-8,就应该能解决问题了
这个问题是在这里找到解决方法的http://fenghuang.iteye.com/blog/363931,感谢作者,感谢霞霞姐




最后如果调用存储过程的sql写错的话会报getParameter空指向,自己找了很久都没找到哪错,汗




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值