数据库存储html代码-html5代码库源代码库
使用 commons-fileupload-1.4-bin.zip 中的工具获取带有文件流的表单数据。 表单中上传文件的第二种方法是使用FileItem类、ServletFileUpload类和DiskFileItemFactory类实现的。 (方法一是使用servlet的Part接口来实现,在我的另一篇文章中)问题分析:
前端表单向后端传输数据时,会遇到一个很棘手的问题:数据中有文件数据吗? ? 因为有不同的方式来处理它们。 现在设计前端使用Ajax应用技术。 后端收到请求后会自动判断表单数据是否有文件数据。 如果有文件数据,则对文件流进行处理,保存到指定路径。
那么如何判断表单发送的数据是否包含文件流呢? 这里用到的思想和工具是FileItem类、ServletFileUpload类、DiskFileItemFactory类。
使用这三个工具,可以将前端表单中的所有数据都一个一个的拆分成FileItem对象,每一个数据都是一个对象,所以我们可以用一个循环来判断每一个数据是否是文件数据,这里直接使用if condition 语句实现,如果是文件数据,则必须保存到路径下,如果不是文件数据,使用函数fileItem.getFieldName()将name的名称保存到数据库中的字段名字符串strfiestr1语句sql; 使用fileItem.getString("utf-8")将数据保存到数据库语句sql中的值中,我将字符串命名为strvalSTR1。 这是为以后将数据模块化插入数据库做准备的参数。 即每取一个,fileItem.getFieldName()的值作为sql命令串的字段名,fileItem.getString的值作为sql命令串的内部值。
文件项类
主要用于处理前端传来的数据
ServletFileUpload 类
主要用于判断前端数据是否为mime协议传输
DiskFileItemFactory 类
主要用于设置限制上传文件大小
结合ServletFileUpload生成一个文件工厂,保存在FileItem类型的List中数据库存储html代码,这样就可以一一判断是否是文件数据。
DiskFileItemFactory factory1=new DiskFileItemFactory();//来源于:commons-fileupload-1.4.jar
factory1.setSizeThreshold(1024*1024*20);//设置内存中用字节数
ServletFileUpload uploadf1=new ServletFileUpload(factory1); //创建文件工厂
uploadf1.setHeaderEncoding("utf-8");//只能解决文件名或路径中汉字乱码
java.util.List fileItemList;
fileItemList = uploadf1.parseRequest(request);
for(FileItem fileItem :fileItemList ){
//循环每一个数据对象,也就是每一个input标签数据
}
1、FileItem类最重要的五个方法
fileItem.isFormField()方法用于判断FileItem类对象封装的数据是普通文本表单域还是文件表单域。 如果是普通表单字段,则返回true,否则返回false。
fileItem.getName()方法用于获取上传文件的文件路径名,后面会处理该名称。
fileItem.getFieldName 方法用于获取输入标签的名称值。
fileItem.getString()方法用于获取当前对象的数据值,即用户在input标签中输入的内容。
fileItem.writer() 方法用于将上传的文件写入磁盘。
二、ServletFileUpload类
ServletFileUpload.isMultipartContent(request)方法用于判断前端传来的数据是否为mime协议,即判断传来的数据是否包含文件数据。 enctype="多部分/表单数据"
三、DiskFileItemFactory类
factory1.setSizeThreshold(1024*1024*20);//设置内存使用的字节数
4、结合以上技术,可以自动实现前端表单数据无论是否包含文件数据都可以保存到数据库中。 工具类代码:
package com.jdbc.utils;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.sql.Statement;
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;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mysql.jdbc.Connection;
public class FormPostUtil {
public void getparm(HttpServletRequest request,HttpServletResponse response, String path1, JSONArray jsonarr1,JSONObject jsonob1,String tablname1) {
String fname1=""; //预留文件名,不管以后用不用,如果有文件上传,它就有值;不传文件,它就是空值
//如果是MIME才能进行文件上传
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
response.setContentType("text/html;Charset=UTF-8");
String sqlfiestr1="";这个串用于保存sql的insert命令中的字段列名,一键搞定
String sqlvalSTR1=""; //这个串用于保存sql的insert命令中的vlaue值
DiskFileItemFactory factory1=new DiskFileItemFactory();//来源于:commons-fileupload-1.4.jar
factory1.setSizeThreshold(1024*1024*20);//设置内存中用字节数
ServletFileUpload uploadf1=new ServletFileUpload(factory1); //创建文件工厂
uploadf1.setHeaderEncoding("utf-8");//只能解决文件名或路径中汉字乱码
java.util.List fileItemList;
try {
fileItemList = uploadf1.parseRequest(request);
for(FileItem fileItem :fileItemList )
{if(fileItem.isFormField()) //表示是普通参数,不是文件.下面为拼凑sql命令insert串做准备
{ sqlfiestr1=sqlfiestr1+fileItem.getFieldName()+",";
try {
sqlvalSTR1=sqlvalSTR1+"'"+fileItem.getString("utf-8")+"',";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //要加编码,否则取出来汉字可能是乱码
}
else //不是fileItem.isFormField()),那下一项就是文件流了(以上程序结构要注意,在表单中要把文件最在最后一项,要不然你就在上面循环调用处理文件保存 独立函数
{ fname1=fileItem.getName();//提前把文件名取出来,后面保存到数据库时要使用
savefile(fileItem, path1);//把上传文件写入保存路径
}
}
//准备把以上数据插入到数据库中; 调用 inserttable()函数
inserttable("xs", sqlfiestr1, sqlvalSTR1, fname1,fileinputname);//向指定表,插入指定字段名,指定值,是否带文件(如果fname1为空则在表中插入空串即可
PrintWriter out1;
try {
out1 = response.getWriter();
out1.println(jsonob1);
out1.flush();
out1.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
//模块化文件保存
private void savefile(FileItem fileItem,String path1) {
String fname1;
fname1=fileItem.getName();
System.out.println(fileItem.getSize());
if(fileItem.getSize()>1024*1024*20) {return; } //文件太大了,拒绝上传
//那说明没有上传文件过来,这样处理 好处是,用户可传可不传文件,无所谓
if(fname1==null||fname1.equals("")||fileItem.getSize()==0)
{ }
else {
File savefile1=new File(path1,fname1);
try {
//可以使用系统时间数字避免文件名重复(我另一篇文件上传的方法中有)
fileItem.write(savefile1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void inserttable(String tablename, String sqlfiestr1,String sqlvalSTR1,String fname1 ,String fileinputname) {
if(sqlfiestr1.length()<1||sqlvalSTR1.length()<1) //那说明没有数据上传
;
else { //说明表单中有数据上传 ,这样才有必要写到数据库中。 同学们,这种偷懒 方法前提是HMTL表单中的控件name要与数据库表列名相同才行。
String sqlstr1="";
if(fname1==""||fname1.equals(""))//说明没有上传文件
{ //要去掉字段名串最后多的一个逗号
sqlfiestr1=sqlfiestr1.substring(0,sqlfiestr1.length()-1);
sqlvalSTR1=sqlvalSTR1.substring(0,sqlvalSTR1.length()-1);
sqlstr1="insert into "+tablename+"("+sqlfiestr1+")values("+sqlvalSTR1+")";
}
else //表示有文件上来,文件名不为空 .调整insert串照片参数
{ sqlfiestr1=sqlfiestr1+ fileinputname ;//fileinputname是文件控件的name的属性值也是数据库中的字段名。
int po=fname1.lastIndexOf("\\"); //只保留后面的文件名,不要前面路径
if(po!=-1)//说明找到了右斜杠\
{ fname1=fname1.substring(po+1);}
sqlvalSTR1=sqlvalSTR1+"'"+fname1+"'";
sqlstr1="insert into "+tablename+"("+sqlfiestr1+")values("+sqlvalSTR1+")";
}
System.out.println(sqlstr1);
Connection con1=(Connection) JdbcConUtil.getConnection();
Statement st1;
try {
st1 = con1.createStatement();
st1.execute(sqlstr1);
JdbcConUtil.close(st1, con1);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
需要用到alibaba的json jar包,commons-fileupload的jar包,commons-io的jar包
阿里巴巴的json jar
%C2%A0
公地-io
%C2%A0
共享文件上传
%C2%A0
servlet测试代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
JSONArray jsonarr1=new JSONArray();
JSONObject jsonob1=new JSONObject();
String path1="C:\\JAVA3\\uploadfile"; //指定保存上传文件的服务器位置
String tablname1="xs";//指定要操作的表名
if(ServletFileUpload.isMultipartContent(request))//判断是不是mime方式过来的
{
new FormPostUtil.getparm(request, response, path1, jsonarr1, jsonob1,tablname1);
}
else {
//这里处理不带文件的数据,这里是自己的另一个插入数据的工具类InsertObject方法
BeanUtils.populate(tempCourse, request.getParameterMap());
String sql1 = "insert into course(cno,cname,tno) values(?,?,?)";
JdbcCRUDUtil.InsertObject(sql1, tempCourse);
}
经过一番思考:我决定改进上面的文件上传功能。 改进点如下:
1.实现多个文件的上传
2.实现窗体任意位置的文件控制
(以上代码文件控件只能在窗体末尾,有局限性)
3、inserttable()函数的参数减少,只需要:表名,sql字段名,sql values值
但是: 这种方式必须在数据库中设置多个字段用于文件存储,即前端的每个文件控件都必须对应数据库中的每个字段。 所以还有改进的余地。
改进:数据库中只设置一个字段保存所有前端文件名,文件名之间用特殊字符分隔。 不过,以后拍照的时候,也需要借助这个垫片一张一张的拍照。
工具类FormPostInsertUtil源码:
/*
* 从前端接收数据插入到数据库一步到位工具类
* servlet测试代码:
* String path1="D:\\Web后端开发技术\\uploadFile"; //指定保存上传文件的服务器位置
* String tablname1="user";//指定要操作的数据库表名
* new FormPostInsertUtil().getParmInsert(request, response, path1, tablname1);
* */
package com.jdbc.utils;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
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 com.alibaba.fastjson.JSONArray;
import com.mysql.jdbc.Connection;
public class FormPostInsertUtil {
public void getParmInsert(HttpServletRequest request,HttpServletResponse response, String path1,String tablname1) {
System.out.println("进入servlet");
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setContentType("text/html;Charset=UTF-8");
String sqlfiestr1=""; //这个串用于保存sql的insert命令中的字段列名,一键搞定
String sqlvalSTR1=""; //这个串用于保存sql的insert命令中的vlaue值
DiskFileItemFactory factory1=new DiskFileItemFactory();//来源于:commons-fileupload-1.4.jar
factory1.setSizeThreshold(1024*1024*20);//设置内存中用字节数
ServletFileUpload uploadf1=new ServletFileUpload(factory1); //创建文件工厂
uploadf1.setHeaderEncoding("utf-8");//只能解决文件名或路径中汉字乱码
java.util.List fileItemList;
try {
fileItemList = uploadf1.parseRequest(request);
for(FileItem fileItem :fileItemList )
{
if(fileItem.isFormField()) //表示是普通参数,不是文件.下面为拼凑sql命令insert串做准备
{
sqlfiestr1=sqlfiestr1+fileItem.getFieldName()+",";//fileItem.getFieldName()获取input标签的name名字
System.out.println(fileItem.getFieldName());
try {
sqlvalSTR1=sqlvalSTR1+"'"+fileItem.getString("utf-8")+"',";//fileItem.getString("utf-8")获取值
System.out.println(fileItem.getString("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} //要加编码,否则取出来汉字可能是乱码
}
/*fileItem.getName()有些浏览器可以直接获取到文件名,不需要处理
但是如果有的浏览器获取的是带有路径的名字,这里要处理后才可以拼接fileinputnames*/
else //当前项是文件流,要把数据写入磁盘
{
String tempFileinputname=fileItem.getFieldName();//文件标签名
String tempFilename=fileItem.getName();//文件名
//处理文件名字
int po=tempFilename.lastIndexOf("\\"); //只保留后面的文件名,不要前面路径
if(po!=-1)//说明找到了右斜杠\
{ tempFilename=tempFilename.substring(po+1);}
//处理文件名完毕
if(tempFilename==""||tempFilename.equals(""))//如果没有上传文件,什么也不做
{ }
//有上传文件就添加sql语句,并写入磁盘
else{
sqlfiestr1=sqlfiestr1+tempFileinputname+",";//fileItem.getFieldName()获取input标签的name名字
sqlvalSTR1=sqlvalSTR1+"'"+tempFilename+"',";//所有上传文件的名字
savefile(fileItem, path1);//把上传文件写入磁盘中,即保存上传文件
}
}
}
//准备把以上数据插入到数据库中; 调用 inserttable()函数
inserttable(tablname1, sqlfiestr1, sqlvalSTR1);//向指定表,插入指定字段名,指定值,上传文件字段名,上传文件名字
/*
* 这里的jsonob1对象看似没有任何作用,但是如果前端ajax的接收数据类型为dataType: "json",时
* 若没有这里的输出,ajax会到error函数,并不是到success函数,所以必须给前端输出一个json对象
*/
JSONObject jsonob1=new JSONObject();
PrintWriter out1;
try {
out1 = response.getWriter();
out1.println(jsonob1);
out1.flush();
out1.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
/*
* 关于fileItem.getName()获取文件名字有个注意事项
* 网上说有的浏览器获取的直接就是文件的名字
* 而有的浏览器获取的是带有路径的文件名字
* 为了两者兼容,直接使用处理带路径的文件名字的方法
* */
private void savefile(FileItem fileItem,String path1) {
System.out.println("来了老弟,要保存文件了");
String fname1;
fname1=fileItem.getName();
//去掉前面的路径,只要后面干净文件名。
int po=fname1.lastIndexOf("\\");
if(po!=-1)//说明找到了右斜杠\
{fname1=fname1.substring(po+1);}
if(fileItem.getSize()>1024*1024*20) {return; } //文件太大了,拒绝上传
if(fname1==null||fname1.equals("")||fileItem.getSize()==0)
{ }//那说明没有上传文件过来,这样处理 好处是,用户可传可不传文件,无所谓
else {
File savefile1=new File(path1,fname1);
try {
fileItem.write(savefile1);//可以使用系统时间数字避免文件名重复(我另一篇文件上传的方法中有)
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
* 参数:
* tablename:表名
* sqlfiestr1:用于保存sql的insert命令中的字段列名
* sqlvalSTR1:用于保存sql的insert命令中的vlaue值
*/
private void inserttable(String tablename, String sqlfiestr1, String sqlvalSTR1) {
System.out.println("开始保存数据到数据库");
if(sqlfiestr1.length()<1||sqlvalSTR1.length()<1) //那说明前端没有数据上传
{ }
else { //说明表单中有数据上传 ,这样才有必要写到数据库中。这种偷懒 方法前提是HMTL表单中的控件name要与数据库表列名相同才行。
String sqlstr1="";
//要去掉字段名串最后多的一个逗号
sqlfiestr1=sqlfiestr1.substring(0,sqlfiestr1.length()-1);
sqlvalSTR1=sqlvalSTR1.substring(0,sqlvalSTR1.length()-1);
sqlstr1="insert into "+tablename+"("+sqlfiestr1+") values("+sqlvalSTR1+")";
System.out.println(sqlstr1);
Connection con1=(Connection) JdbcConUtil.getConnection();
Statement st1;
try {
st1 = con1.createStatement();
st1.execute(sqlstr1);
JdbcConUtil.close(st1, con1);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
小服务程序源代码:
package com.servlet;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jdbc.utils.FormPostUtil;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "regionServlet", value = "/regionServlet")
public class regionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path1="D:\\Web后端开发技术\\uploadFile"; //指定保存上传文件的服务器位置
String tablname1="user";//指定要操作的数据库表名
new FormPostUtil().getparm(request, response, path1, tablname1);
}
}
HTML 源代码:
用户注册
用户注册
<form action="regionServlet" method="POST" id="form1" enctype="multipart/form-data">
用户名:
头像2:
密码:
头像1:
还有另一种上传文件的方法数据库存储html代码,使用servlet的Part接口实现: