您的位置:首页 > 数据库 > MySQL

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

2011-07-17 17:32 615 查看
啥也不说了,网上软文太多,总结自己写的一些经验总结
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空指向,自己找了很久都没找到哪错,汗
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: