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

        中间的周末让我痛苦不已,辞职放弃的心都有了,因为看不懂代码,不知道执行顺序,不知道怎么上传,不知道怎么获取路径,再面对着从来没有用过的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是传过去的值。

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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值