向数据库保存图片时,我们通常都是将图片转换为字节流插入到表格对应的列中。保存图片的列的类型与使用的数据库有关,在这里我是用的是MySQL数据库,列类型使用的是LONGBLOB
类型,LONGBLOB是一个二进制大对象
,可以容纳可变数量的数据。
在jsp页面使用<input type=’file’/>
标签来选择上传的图片,可以通过设置accept
属性来自定义上传文件的类型。
<input type="file" class="hide" id="addPic" onchange="" name="addPic" accept="image/jpg, image/png, image/jpeg, image/gif" />
<span class="glyphicon glyphicon-picture" title="插入图片" onclick="addPic()"></span>
这里我将file类型的input标签隐藏,使用一个图标并设置点击事件来激活input
function addPic(){
document.all('addPic').click();
}
在使用form
表单提交数据的时候,一定要在form标签中添加enctype属性
,并设置值为"multipart/form-data"
,指定了提交数据类型,否则在servlet中将无法接收。
<form action="${ctx}/servlet/UserServlet?fun=addTrends" method="post" enctype="multipart/form-data" id="formImg">
<textarea name="trendsname" id="trendsname" style="width: 100%;"></textarea>
<div class="trendsplus">
<input type="file" class="hide" id="addPic" onchange="" name="addPic" accept="image/jpg, image/png, image/jpeg, image/gif" />
<span class="glyphicon glyphicon-picture" title="插入图片" onclick="addPic()"></span>
<button type="submit" id="submit" class="hide"></button>
</div>
</form>
之后创建一个JavaBean类,用来存放图片表格的字段信息。
public class Trends {
private int trendsid;
private String trendsname;
private Date trendsdate;
private byte[] trendsimg;//图片是转换为二进制数组保存进数据库的,所以数据类型为byte[]
private int userid;
//以下getter和setter省略
创建数据库操作接口及其实现类,声明一个addTrends的方法来保存图片信息
public class UserDaoImpl implements IUserDao {
private Connection con=null;
private PreparedStatement ps = null;
private ResultSet rs=null;
String addTrends = "insert into trends(trendsname,trendsdate,trendsimg,userid) values(?,?,?,?)";
@Override
public int addTrends(Trends trends) {
// TODO Auto-generated method stub
int count = 0;
try {
con=DbUtil.getConnection();
ps=con.prepareStatement(addTrends);
ps.setString(1, trends.getTrendsname());
ps.setTimestamp(2, new Timestamp(trends.getTrendsdate().getTime()));
ps.setBytes(3,trends.getTrendsimg());//使用setBytes方法保存byte[]类型的数据
ps.setInt(4, trends.getUserid());
count=ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
DbUtil.close(con, ps, null);
}
return count;
}
}
由于form标签添加了enctype="multipart/form-data"
属性,那么form表单中文件以外的其他数据在servlet是接收不到的,这个时候就需要引入两个jar包
这两个jar包可以通过创建文件工厂,再通过判断来分别接收不同类型的数据。
public void addTrends(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
DiskFileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);//创建文件工厂
upload.setHeaderEncoding("UTF-8");//设置文件工厂编码,防止出现中文乱码
Trends trends = new Trends();//创建Trends对象
List<FileItem> formItems;//创建FileItem对象
try {
formItems = upload.parseRequest(request);//接收请求中的数据
for (FileItem item : formItems) {//循环并判断数据的类型
//isFormField 表单元素
if (!item.isFormField()) {//通过isFormField判断是否为文件
trends.setTrendsimg(item.get());//添加到Trends中
}else
{
//获取其他字段
String con = item.getString("UTF-8");
trends.setTrendsname(con);
}
}
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Date date = new Date();
trends.setTrendsdate(date);
boolean state = userSer.addTrends(trends);
JSONObject json = new JSONObject();
json.put("data", state);
response.getWriter().write(json.toString());//返回json类型的数据
}
当然,如果只是单纯的上传图片,没有附带的其他信息的话,就不用这么麻烦了。