两个周的折腾(二)——在线文本编辑器中图片上传的实现

本文分享了将图片上传到服务器文件夹与数据库的具体实现,包括连接数据库、存储图片及读取图片的主要代码,并探讨了两种上传方式的区别。

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

中间的周末让我痛苦不已,辞职放弃的心都有了,因为看不懂代码,不知道执行顺序,不知道怎么上传,不知道怎么获取路径,再面对着从来没有用过的oracle数据库,还有一些经理提出来的从来没有听过的问题,我真的表示压力很大,但是,很感激武让,他有远大梦想,而且是一个经得住寂寞,可以去努力钻研每一个问题的人,让他帮我看上传文件代码的时候,虽然他也没做过,也没用过,但是,他可以静下心来慢慢研究,突然之间感觉自己有些惭愧,做的不够,自己做的真的不够,突然之间期盼着周一的到来,好去认真的研究一下代码。

图片的上传,在原来的基础上,修改upload_json.jsp。首先说一下这两种上传方式的不同:

1、将图片上传到服务器文件夹

将图片上传到服务器文件夹,主要思想是将图片以<img src="/upload/xxxxxx.jpg"/>的形式放到数据库中,等读取的时候,直接根据路径读取,这个应该很好理解。

2、将图片以blob的形式存到数据库中

刚开始我有一些不解,也有很多人问为什么不用上传到文件夹的方式上传,而且,存在数据库中占有的空间很大,太耗资源了,我同样这样想过,后来我问经理,他说,公司的服务器是分布式的,这样的话,可以共享数据库,但很少共享文件夹的,所以,当你的需求能保证不会产生很多的图片上传,那么,很有必要将图片放到数据库而不是文件夹。我想了想,恩,确实很有道理,不知道还有没有其他的原因…

将图片上传到数据库中的原理基本上是这样的:对于上传而言:首先建立路径,然后以流的形式读取,获取流之后插入数据库。我将主要代码记录一下:

首先,当然要连接数据库的类:

public class DbConn { private final static String dbDriver="oracle.jdbc.OracleDriver"; private final static String dbUrl="jdbc:oracle:thin:@218.1.69.119:9152:TJEETEST"; private final static String dbUser="db_other"; private final static String dbPwd="db_other"; private static Connection conn=null; /** * 获得数据库连接方法 * @return */ public static Connection getConnection(){ if (conn==null) { init(); } /** * 否则返回conn对象 */ return conn; } /** * 如果Connection对象为空,则执行该方法 */ public static void init(){ try { Class.forName(dbDriver); conn=DriverManager.getConnection(dbUrl, dbUser, dbPwd); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } /** * 关闭当前Connnection对象的方法 */ public static void closeConnection(){ if (conn!=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }; } 然后存储图片主要代码:
public class UserImageDAO{ private static Connection conn=null; private final static String SAVEIMGSQL="insert into USERPIC(USERIMG,IMGDATE,TEXTID) values(?,?,?)"; //private final static String READIMGSQL="select * from userPic order by id desc limit 1"; //ivate final static String READIMGSQL="select * from USERPIC where ID = ?"; //ivate final static String READIDSQL = "select userpicid_seq.nextval colname from dual"; //ivate final static String READTEXTIDSQL = "select userpicid_seq.nextval colname from dual"; static { conn=DbConn.getConnection(); } /**(non-Javadoc) * 存储图片方法 */ public boolean saveUserImgWithBlob(String filePath,String date){ PreparedStatement pmst =null; int result=0; boolean flag = false; File file = null; InputStream imgStream = null; try { file=new File(filePath); imgStream = new FileInputStream(file); } catch (FileNotFoundException e1) { e1.printStackTrace(); } try { pmst = conn.prepareStatement(SAVEIMGSQL); pmst.setBinaryStream(1, imgStream, (int)file.length()); pmst.setString(2, date); pmst.setInt(3, getTextId()); result= pmst.executeUpdate(); if (result>0) { flag=true; } } catch (Exception e) { e.printStackTrace(); } return flag; } } 这样,就可以在之前的上传图片文件中进行修改,实例化这个类,然后调用相应的存储方法。


其次是读取图片:读取图片也是一个艰难的过程,你想啊,怎么能将id号对应好,读取到上传上去的图片呢,刚开始,我用的mysql,其中主键是建立的自动增长类型,这样,我可以试着去在js文件中创建一个一个变量,在后台添加一个方法,返回当前数据库中最新的一条记录的id值,这样,根据返回的值来决定生成的img中src的链接的id值,方法如下:

/** (non-Javadoc) * @return imgid */ public static int getImgId(){ PreparedStatement pmst =null; ResultSet rs=null; int id = 0; try { pmst = conn.prepareStatement(READIDSQL); rs= pmst.executeQuery(); if (rs.next()) { id = rs.getInt(1); } } catch (Exception e) { e.printStackTrace(); } return id; }
好,想到这里了又有问题了,我怎么把返回的这个值传给我的js文件呢,那可是一个实实在在的js文件,不是jsp文件…有点傻了,但是,为了能完成功能,要不惜一切代价,好吧,新建一个jsp文件,然后将那么那么长的js文件中的代码放到这个新建的jsp文件中,然后引入这个类,调用这个static方法,然后再在现实的链接里添加上id值,这样,自动生成img标签的那段代码就有点改变:那就是在读取的那个servlet中带上一个id值来决定取哪个图片。<img src="XXXX.do?id='取到的id值'"/>


好像一个大问题解决了,但是,还是有问题,因为,当我上传一个图片的时候,我从数据库中取到当前id,然后加1后赋值给id,但是,当我选择第二张第三张图片的时候,这个id就还是那个啊,因为,这个过程,不会再和后台交互了,哎,继续想办法……

为了解决这个问题,在网上查一下吧,哇,看到一个惊奇的全局变量,用吧,首先设置全局变量为1,后面没生成一个加一次1,这样,对于全局变量来说,就保证了和数据库中的值一致。

最后再记录一点,那就是图片读取的方法和显示的方法:/**(non-Javadoc) *读取图片 */ public void readUserImageWithBlob(ServletOutputStream sos,HttpServletResponse response, int id){ PreparedStatement pmst =null; ResultSet rs=null; try { pmst = conn.prepareStatement(READIMGSQL); pmst.setInt(1, id); rs= pmst.executeQuery(); if (rs.next()) { response.setContentType("image/jpeg"); sos=response.getOutputStream(); InputStream input=rs.getBinaryStream("userImg"); byte b[]=new byte[1024]; @SuppressWarnings("unused") int len=0; while ((len=input.read(b))!=-1) { sos.write(b); } input.close(); } } catch (Exception e) { e.printStackTrace(); } }


最最后一个让我觉得惊奇的事情是,读取图片竟然可以这样:

<img src="imgeReadWithBlob.do?id=136"/>这句话的意思竟然是:imgeReadWithBlob.do对应读取的servlet,id是传过去的值。

先记录到这,下篇要说这个的缺点了……



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值