📄 java+mysql图片保存和读取.txt
字号:
try {
pstmt = conn.prepareStatement("UPDATE hr01 SET hr01_photo=? where hr01_id=?");
FileInputStream in = new FileInputStream(path);
pstmt.setBinaryStream(1,in,in.available());
pstmt.setInt(2,id);
pstmt.executeUpdate();
pstmt.executeUpdate("COMMIT");
logger.info(" 图片 " + path + " 被添加到数据库中! ");
flag = true;
}catch(IOException e){
logger.error(" 图片 " + path + " 文件读写错误!请检查文件路径是否正确 ");
throw new SQLException(" 无法保存图片! ");
}catch (SQLException ex) {
logger.error(new java.util.Date() + "Error:Insert into table."
+ ex.getMessage());
logger.error(" 图片 " + path +" 没有被保存到数据库 .");
throw new SQLException(" 图片 " + path +" 没有被保存到数据库 .");
} finally {
try {
pstmt.close();
conn.close();
logger.info("DbHrinfo saveImage() closed the connection created at " + time);
} catch (SQLException e) {
}
}
>
// 图片添加成功以后就删除临时文件夹中的图片数据
if(flag == true){
File file = new File(path);
if(file.exists()){
file.delete();
}
}
}
需要注意的是 pstmt.executeUpdate("COMMIT"); 这行代码,最初我并没有写这行,程序能顺利执行,日志中也显示“图片××被添加到数据库中”,
但是到库里一查询,什么都没有。 SQL 语句被提交,但是数据库里面没有即时的显示,估计是缓冲区的作用,它把我的 SQL 语句缓存起来而
不是立即提交给数据库。后来我在 textpad 里面单独执行这段代码,发现不用“ COMMIT ” SQL 语句就立即被提交了。这个地方还没有弄清楚,
以后需要继续研究。
功能上做一点小改进,用户提交了照片以后,浏览了一下觉得不满意,只要还没有最终提交数据,当然允许他重新上传一个照片。
我们只需要在 <img src=””> 下面提供一个“重新提交”的链接就可以了。这个链接指向一个 AlterImageAction ,它的功能就是清除 session
中用户已经上传照片的标记,并把刚才保存到临时文件夹中的照片删掉,等待用户重新上传。这部分代码如下:
public ActionForward execute(ActionMapping mapping,
ActionForm form,HttpServletRequest request,
HttpServletResponse response)
throws IOException,ServletException{
HttpSession session = request.getSession();
//1. 从临时文件夹中删除图片
String filename = (String)session.getAttribute("filename");
String path = session.getServletContext().getRealPath("/")
+ "temp\\" + filename;
File file = new File(path);
if(file.exists()){
file.delete();
logger.info(" 文件 " + path + " 已经被删除 ");
}
//2. 从 session 中清除上传图片的标记
session.removeAttribute("imageuploaded");
session.removeAttribute("filename");
return mapping.findForward("next");
}
提交和保存到此功德圆满。下次用户想要查询自己的信息的时候,因为临时文件夹中已经没有用户照片,需要从数据库中读取。
用一个 ShowImageAction 来实现这个功能:
public ActionForward execute(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response)
throws IOException,ServletException{
// 需要的情况下设置数据源
if (!DbManager.hasSetDataSource()) {
javax.sql.DataSource dataSource;
try {
dataSource = getDataSource(request);
DbManager.setDataSource(dataSource);
} catch (Exception e) {
logger.error(e.getMessage());
mapping.findForward("error");
}
}
String photo_no = request.getParameter("photo_no");
Connection conn = null;
Statement stmt = null;
// 获取连接
try {
conn = DbManager.getConnection();
logger.info("showimage.jsp 从 DbManager 数据库连接池获取一个连接。 ");
} catch (SQLException e) {
// 如果没有能够从 DbManager 获取连接,此次查询操作失败
logger.error(" showimage.jsp 不能获取数据库连接,无法读取图片! ");
}
try {
// 准备语句执行对象
stmt = conn.createStatement();
String sql = " SELECT hr01_photo FROM hr01 WHERE hr01_id='" + photo_no + "'";
ResultSet rs = stmt.executeQuery(sql);
if (rs.next()) {
InputStream in = rs.getBinaryStream("hr01_photo");
int bytesRead = 0;
byte[] buffer = new byte[8192];
response.setContentType("image/jpeg");
response.setContentLength(in.available());
OutputStream outs = response.getOutputStream();
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
outs.write(buffer, 0, bytesRead);
}
outs.flush();
in.close();
rs.close();
} else {
rs.close();
response.sendRedirect("error.jsp");
}
}catch(SQLException e){
}finally {
try{
stmt.close();
conn.close();
}catch(SQLException ex){
}
}
return null;
}
以前一直不清楚 execute 方法中的 response 参数的用法,因为处理完以后总要 redirect 到另外一个页面,所以用的最多的就是把数据保存在 session 中,在另一个页面里再取出来用。这次纯粹是试验性地在 response 中写入 image/jpeg 内容,然后返回一个 null 值。最后的执行结果跟我预期的一样,在浏览器中直接显示从数据库中读出的图片。那么接下来就很好做了,只需要在 JSP 页面中设置一个 <image> 标签,指向这个 Action 就可以,当然,在这之前需要在 struts-config.xml 中先部署这个 Action :
<action path="/ShowImage"
type="software.action.ShowImageAction"></action>
然后在 JSP 页面中引用这个 Action 来显示图像 :
<img src="/tibet/ShowImage.do?photo_no=666542">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -