在实际的开发中,我们可能需要将图片、影音等文件直接保存到数据库中,然后通过编程方式将数据读出进行使用。例如将读出的图片数据显示出来,将读出的电影文件播放出来。
二进制数据直接保存到文件和从文件中读出非常的简单。和普通的数据库操作差别不大。只是用到部分流操作。例如各种输入输出流操作。所以深刻理解流操是非常重要的。
在此我借助于一个JSP的简单实例进行讲解。此实例保存职员数据,其中职员数据包含一个图片列。此列保存每名员工的照片。在此将照片直接保存到数据库中。首先建立职员信息表EmployeeInfo,表列非常的简单
employeeId:职员编号(自动增长);employeeName:职员姓名;age:职员年龄;pic:职员图片(image类型)
首先讲解信息的保存。先建立一个录入界面index.jsp,其中包含一个<input type="file"/>元素,用于让用户选择图片文件。
页面代码如下(不做过多讲解):
1 <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 <form action="addServlet" method="POST"> 25 <table border="15" width="60%" align="center"> 26 <tr> 27 <td width="30%" align="right">EmployeeName:</td> 28 <td width="70%" align="left"><input type="text" name="employeeName"/></td> 29 </tr> 30 <tr> 31 <td width="30%" align="right">Age:</td> 32 <td width="70%" align="left"><input type="text" name="age"/></td> 33 </tr> 34 <tr> 35 <td width="30%" align="right">Image:</td> 36 <td width="70%" align="left"><input type="file" name="pic"/></td> 37 </tr> 38 <tr> 39 <td colspan="2" align="center"><input type="submit" value="add"/></td> 40 </tr> 41 </table> 42 </form> 43 </body> 44 </html>
页面请求addServlet,获取录入信息,并调用JavaBean实现数据保存。Servlet代码如下:
1 import java.io.IOException; 2 import java.io.PrintWriter; 3 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import com.frank.rule.*; 9 public class AddServlet extends HttpServlet { 10 11 /** 12 * Constructor of the object. 13 */ 14 public AddServlet() { 15 super(); 16 } 17 18 /** 19 * Destruction of the servlet. <br> 20 */ 21 public void destroy() { 22 super.destroy(); // Just puts "destroy" string in log 23 // Put your code here 24 } 25 26 /** 27 * The doGet method of the servlet. <br> 28 * 29 * This method is called when a form has its tag value method equals to get. 30 * 31 * @param request the request send by the client to the server 32 * @param response the response send by the server to the client 33 * @throws ServletException if an error occurred 34 * @throws IOException if an error occurred 35 */ 36 public void doGet(HttpServletRequest request, HttpServletResponse response) 37 throws ServletException, IOException { 38 39 String employeeName=request.getParameter("employeeName"); 40 int age=Integer.parseInt(request.getParameter("age")); 41 String pic=request.getParameter("pic"); 42 EmployeeDAO employeeDAO=new EmployeeDAO(); 43 if(employeeDAO.employeeAdd(employeeName, age, pic)) 44 response.sendRedirect("success.jsp"); 45 else 46 response.sendRedirect("index.jsp"); 47 48 } 49 50 /** 51 * The doPost method of the servlet. <br> 52 * 53 * This method is called when a form has its tag value method equals to post. 54 * 55 * @param request the request send by the client to the server 56 * @param response the response send by the server to the client 57 * @throws ServletException if an error occurred 58 * @throws IOException if an error occurred 59 */ 60 public void doPost(HttpServletRequest request, HttpServletResponse response) 61 throws ServletException, IOException { 62 63 doGet(request,response); 64 } 65 66 /** 67 * Initialization of the servlet. <br> 68 * 69 * @throws ServletException if an error occurs 70 */ 71 public void init() throws ServletException { 72 // Put your code here 73 } 74 75 }
此Servlet只是简单的获取页面输入的数据,其中获取的Pic为用户选择的图片路径。严格讲,获取文件需要经过验证,防止非法图片的选择,这个可以根据自己的需要改善。然后Servlet调用业务类,将获取的数据通过参数传入,进行数据的增加。其中employeeAdd方法实现数据的保存,代码如下:
1 public boolean employeeAdd(String employeeName,int age,String pic){ 2 Connection conn=null; 3 PreparedStatement pstmt=null; 4 FileInputStream fis=null; 5 try{ 6 Class.forName("net.sourceforge.jtds.jdbc.Driver"); 7 conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa",""); 8 fis=new FileInputStream(pic); 9 10 String strSQL="INSERT INTO employeeInfo VALUES(?,?,?)"; 11 pstmt=conn.prepareStatement(strSQL); 12 pstmt.setString(1, employeeName); 13 pstmt.setInt(2, age); 14 pstmt.setBinaryStream(3, fis, fis.available()); 15 if(pstmt.executeUpdate()>0) 16 return true; 17 else 18 return false; 19 }catch(ClassNotFoundException ex){ 20 ex.printStackTrace(); 21 return false; 22 }catch(SQLException ex){ 23 ex.printStackTrace(); 24 return false; 25 }catch(IOException ex){ 26 ex.printStackTrace(); 27 return false; 28 }finally{ 29 try{ 30 fis.close(); 31 pstmt.close(); 32 conn.close(); 33 }catch(Exception ex){ 34 35 } 36 } 37 }
注意粗体部分,用获取的pic信息(文件路径)创建文件输入流对象,增加pic字段的内容通过流对象增加。
pstmt.setBinaryStream(3, fis, fis.available());
三个参数分别为:参数索引,流对象,流对象大小
当增加成功时,重定向到success.jsp
运行结果如下:

增加后,显示如下代表成功:

那么如何验证图片数据是否保存到了数据库中呢?我们通过再次检索增加的数据,读出增加的图片数据并在页面中显示出来进行验证。
首先建立一个非常简单的页面search.jsp,此页面通过文本框使用户输入要检索的人员的姓名,检索人员的基本信息(不检索图片数据),将检索的人员数据形成JOPO对象,保存到session中,以便页面使用。
POJO类(EmployeeObj)
1 public class EmployeeObj { 2 private int employeeId; 3 private String employeeName; 4 private int age; 5 public int getEmployeeId() { 6 return employeeId; 7 } 8 public void setEmployeeId(int employeeId) { 9 this.employeeId = employeeId; 10 } 11 public String getEmployeeName() { 12 return employeeName; 13 } 14 public void setEmployeeName(String employeeName) { 15 this.employeeName = employeeName; 16 } 17 public int getAge() { 18 return age; 19 } 20 public void setAge(int age) { 21 this.age = age; 22 } 23 24 }
search.jsp页面代码如下:
1 <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'search.jsp' starting page</title> 13 14 <meta http-equiv="pragma" content="no-cache"> 15 <meta http-equiv="cache-control" content="no-cache"> 16 <meta http-equiv="expires" content="0"> 17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 18 <meta http-equiv="description" content="This is my page"> 19 <!-- 20 <link rel="stylesheet" type="text/css" href="styles.css"> 21 --> 22 23 </head> 24 25 <body> 26 <form action="searchServlet" method="POST"> 27 employeeName:<input type="text" name="employeeName"/> 28 <input type="submit" value="search"/> 29 </form> 30 </body> 31 </html>
通过searchServlet实现基本信息的检索
1 import java.io.IOException; 2 import java.io.PrintWriter; 3 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 import javax.servlet.http.HttpSession; 9 10 public class SearchServlet extends HttpServlet { 11 12 /** 13 * Constructor of the object. 14 */ 15 public SearchServlet() { 16 super(); 17 } 18 19 /** 20 * Destruction of the servlet. <br> 21 */ 22 public void destroy() { 23 super.destroy(); // Just puts "destroy" string in log 24 // Put your code here 25 } 26 27 /** 28 * The doGet method of the servlet. <br> 29 * 30 * This method is called when a form has its tag value method equals to get. 31 * 32 * @param request the request send by the client to the server 33 * @param response the response send by the server to the client 34 * @throws ServletException if an error occurred 35 * @throws IOException if an error occurred 36 */ 37 public void doGet(HttpServletRequest request, HttpServletResponse response) 38 throws ServletException, IOException { 39 40 String employeeName=request.getParameter("employeeName"); 41 EmployeeDAO employeeDAO=new EmployeeDAO(); 42 EmployeeObj employeeObj=employeeDAO.getEmployeeByName(employeeName); 43 HttpSession session=request.getSession(); 44 session.setAttribute("employee", employeeObj); 45 response.sendRedirect("display.jsp"); 46 } 47 48 /** 49 * The doPost method of the servlet. <br> 50 * 51 * This method is called when a form has its tag value method equals to post. 52 * 53 * @param request the request send by the client to the server 54 * @param response the response send by the server to the client 55 * @throws ServletException if an error occurred 56 * @throws IOException if an error occurred 57 */ 58 public void doPost(HttpServletRequest request, HttpServletResponse response) 59 throws ServletException, IOException { 60 61 doGet(request,response); 62 } 63 64 /** 65 * Initialization of the servlet. <br> 66 * 67 * @throws ServletException if an error occurs 68 */ 69 public void init() throws ServletException { 70 // Put your code here 71 } 72 73 }
此Servlet调用业务类的getEmployeeByName方法检索人员基本信息,返回EmployeeObj对象,并放入session中,当然也可以放入request中,根据自己的需要改进。页面检索成功后重定向到display.jsp进行信息的显示(稍后讲解)
getEmployeeByName方法代码如下:
1 public EmployeeObj getEmployeeByName(String employeeName){ 2 Connection conn=null; 3 PreparedStatement pstmt=null; 4 ResultSet rst=null; 5 EmployeeObj employeeObj=new EmployeeObj(); 6 try{ 7 Class.forName("net.sourceforge.jtds.jdbc.Driver"); 8 conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa",""); 9 10 String strSQL="SELECT employeeId,employeeName,age FROM EmployeeInfo WHERE employeeName=?"; 11 pstmt=conn.prepareStatement(strSQL); 12 pstmt.setString(1, employeeName); 13 rst=pstmt.executeQuery(); 14 if(rst.next()){ 15 employeeObj.setEmployeeId(rst.getInt("employeeId")); 16 employeeObj.setEmployeeName(rst.getString("employeeName")); 17 employeeObj.setAge(rst.getInt("age")); 18 return employeeObj; 19 } 20 return null; 21 }catch(ClassNotFoundException ex){ 22 ex.printStackTrace(); 23 return null; 24 }catch(SQLException ex){ 25 ex.printStackTrace(); 26 return null; 27 }finally{ 28 try{ 29 pstmt.close(); 30 conn.close(); 31 }catch(Exception ex){ 32 33 } 34 } 35 }
display.jsp负责显示查询出的结果信息,代码如下:
1 <%@ page language="java" import="java.util.*,com.frank.obj.*" pageEncoding="ISO-8859-1"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'display.jsp' starting page</title> 13 14 <meta http-equiv="pragma" content="no-cache"> 15 <meta http-equiv="cache-control" content="no-cache"> 16 <meta http-equiv="expires" content="0"> 17 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 18 <meta http-equiv="description" content="This is my page"> 19 <!-- 20 <link rel="stylesheet" type="text/css" href="styles.css"> 21 --> 22 <% 23 EmployeeObj employeeObj=(EmployeeObj)session.getAttribute("employee"); 24 %> 25 </head> 26 27 <body> 28 <table width="80" border="15"> 29 <tr> 30 <td width="30%" align="right">EmployeeId</td> 31 <td width="70%" align="left"><%=employeeObj.getEmployeeId() %></td> 32 </tr> 33 <tr> 34 <td width="30%" align="right">EmployeeName</td> 35 <td width="70%" align="left"><%=employeeObj.getEmployeeName() %></td> 36 </tr> 37 <tr> 38 <td width="30%" align="right">Age</td> 39 <td width="70%" align="left"><%=employeeObj.getAge() %></td> 40 </tr> 41 <tr> 42 <td width="30%" align="right">Pic</td> 43 <td width="70%" align="left"><img src="displayServlet?employeeId=<%=employeeObj.getEmployeeId() %>"/></td> 44 </tr> 45 </table> 46 </body> 47 </html>
代码非常的简单,只是简单的从session中获取保存的EmployeeObj对象,然后利用jsp表达式将数据成员信息显示到页面上。但是注意粗体部分,因为我们需要将保存的图片数据读出,然后显示成图片。所以在此我们利用Img元素显示图片,而Src利用displayServlet的运行结果输出到客户端,作为图片的显示源。displayServlet包含参数employeeId,用来决定具体显示哪一员工的图片。
displayServlet通过Servlet输出流,将读取的图片数据发送到客户端,代码如下:
1 import java.awt.image.BufferedImage; 2 import java.io.IOException; 3 import java.io.InputStream; 4 import java.io.PrintWriter; 5 6 import javax.imageio.ImageIO; 7 import javax.servlet.ServletException; 8 import javax.servlet.ServletOutputStream; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import com.frank.rule.EmployeeDAO; 14 15 public class DisplayServlet extends HttpServlet { 16 17 /** 18 * Constructor of the object. 19 */ 20 public DisplayServlet() { 21 super(); 22 } 23 24 /** 25 * Destruction of the servlet. <br> 26 */ 27 public void destroy() { 28 super.destroy(); // Just puts "destroy" string in log 29 // Put your code here 30 } 31 32 /** 33 * The doGet method of the servlet. <br> 34 * 35 * This method is called when a form has its tag value method equals to get. 36 * 37 * @param request the request send by the client to the server 38 * @param response the response send by the server to the client 39 * @throws ServletException if an error occurred 40 * @throws IOException if an error occurred 41 */ 42 public void doGet(HttpServletRequest request, HttpServletResponse response) 43 throws ServletException, IOException { 44 45 response.setContentType("image/gif"); 46 int employeeId=Integer.parseInt(request.getParameter("employeeId")); 47 EmployeeDAO employeeDAO=new EmployeeDAO(); 48 InputStream is=employeeDAO.getPicById(employeeId); 49 int size=is.available(); 50 byte[] image=new byte[size]; 51 is.read(image); 52 ServletOutputStream out=response.getOutputStream(); 53 out.write(image); 54 55 } 56 57 /** 58 * Initialization of the servlet. <br> 59 * 60 * @throws ServletException if an error occurs 61 */ 62 public void init() throws ServletException { 63 // Put your code here 64 } 65 66 }
在此,调用业务类的getPicById方法得到图片数据的输入流。然后获取的输入流写到ServletOutputStream,这样可以在Servlet的输出端使用,即img的src中使用
getPicById代码如下:
1 public InputStream getPicById(int employeeId){ 2 Connection conn=null; 3 PreparedStatement pstmt=null; 4 ResultSet rst=null; 5 InputStream is=null; 6 try{ 7 Class.forName("net.sourceforge.jtds.jdbc.Driver"); 8 conn=DriverManager.getConnection("jdbc:jtds:sqlserver://localhost:1433/SampleDB","sa",""); 9 10 String strSQL="SELECT pic FROM EmployeeInfo WHERE employeeId=?"; 11 pstmt=conn.prepareStatement(strSQL); 12 pstmt.setInt(1, employeeId); 13 rst=pstmt.executeQuery(); 14 if(rst.next()){ 15 is=rst.getBinaryStream("pic"); 16 return is; 17 } 18 return null; 19 }catch(ClassNotFoundException ex){ 20 ex.printStackTrace(); 21 return null; 22 }catch(SQLException ex){ 23 ex.printStackTrace(); 24 return null; 25 }finally{ 26 try{ 27 pstmt.close(); 28 conn.close(); 29 }catch(Exception ex){ 30 31 } 32 } 33 }
注意粗体部分
好了,我们可以通过运行结果来进行验证,假设我们搜索名称为Mike的人员数据,那么这样:

点search按钮,运行结果如下:

好了,显示出了检索结果,不但包括人员的基本数据,保存到数据库中的图片数据也被读出并显示成图片。
代码只是利用jsp简单的进行体现,大家可以根据自己的需要进行改进。
浙公网安备 33010602011771号