web开发中将上传图片压缩后以image类型存入数据库(转) 2009-03-11 17:45 转自http://blog.sina.com.cn/s/blog_4ce383f30100chmm.html 不久前,本人在一个小型java web项目开发中需要上传一个图片的同时,将其进行适当压缩,然后直接以image类型存入SQL Server数据库。之前,本人在网络上查找了好长时间,都没有找到合适的源码,要么就是存原图片,要么就是把图片压缩后存到服务器上,然后把相对路径以string类型存入数据库或以image类型存入数据库,本例与其不同的是,要求图片在内存中压缩后直接以image类型存入数据库。具体实现如下: ①首先,新建一个upload.jsp文件,用来选择需要上传的图片,源码如下: <%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage=""%> <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>上传并压缩图片</title> <style> td { font-family: "宋体"; font-size: 12px; } </style> </head> <body> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="45" align="center" valign="middle"> <form action="ImgDealServlet" method="post" enctype="multipart/form-data" name="form1"> <table border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td colspan="2" height="50"> <div align="center"> 上传并压缩图片应用 </div> </td> </tr> <tr> <td> 请选择上传的图片 </td> <td> <input type="file" name="file" /> <input type="submit" name="Submit" value="上传" /> </td> </tr> </table> </form> </td> </tr> </table> </body> </html> ②然后,创建一个servlet文件ImgDealServlet.java,用来处理图片的上传,源码如下: package servlet; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.sql.ResultSet; import util.*; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.jspsmart.upload.SmartUpload; public class ImgDealServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("GB2312"); response.setContentType("text/html; charset=GB2312"); PrintWriter out = response.getWriter(); SmartUpload mySmartUpload = new SmartUpload(); mySmartUpload.initialize(getServletConfig(),request,response); try { mySmartUpload.setAllowedFilesList("jpg,JPG,gif"); //上载文件 mySmartUpload.upload(); } catch (Exception e) { out.print("<SCRIPT language='javascript'>"); out.print("alert('只允许上传.jpg和.gif类型图片文件');"); out.print("window.location='upfile.jsp';"); out.print("</SCRIPT>"); } try { com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(0); // 若文件不存在 if (myFile.isMissing()) { out.print("<SCRIPT language='javascript'>"); out.print("alert('请先选择要上传的文件');"); out.print("window.location='upfile.jsp';"); out.print("</SCRIPT>"); } else { String myFilePath=myFile.getFilePathName(); //取得上载的文件的路径 UploadImg ui=new UploadImg(); BufferedImage tag =ui.getResizeImg(myFilePath,400,300,true); if(tag!=null){ ui.saveImgToDB(tag); } response.sendRedirect("showimg.jsp"); } } catch (Exception e) { e.toString(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } } ③之前的servlet文件中用到了一个自定义包中的类UploadImg.java,其中定义了图片处理的方法,其源码如下: package util; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import javax.imageio.ImageIO; import util.DBConnect; public class UploadImg { String myFilePath = ""; public BufferedImage getResizeImg(String path, int width, int height, boolean isResize) { String myFilePath = path; // 取得上载的文件的路径 BufferedImage srcimg, tag; tag = null; int new_w; // 压缩后大小 int new_h; boolean Resize;// 是否等比缩放 try { srcimg = ImageIO.read(new java.io.File(myFilePath)); if (isResize) {// 等比缩放 double rate1 = ((double) srcimg.getWidth(null)) / (double) width + 0.1; double rate2 = ((double) srcimg.getHeight(null)) / (double) height + 0.1; double rate = rate1 > rate2 ? rate1 : rate2; new_w = (int) (((double) srcimg.getWidth(null)) / rate); new_h = (int) (((double) srcimg.getHeight(null)) / rate); } else { new_w = width; new_h = height; } Image image = srcimg.getScaledInstance(new_w, new_h, Image.SCALE_DEFAULT); tag = new BufferedImage(new_w, new_h, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); return tag; } catch (Exception e) { e.printStackTrace(); } return tag; } public void saveImgToDB(BufferedImage bi) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); BufferedImage tag = bi; try { ImageIO.write(tag, "jpg", baos); byte[] bytes = baos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); String strsql = "update imgtest set img=? where id=1"; DBConnect dbcSelect = new DBConnect(strsql); dbcSelect.setBinaryStream(1, bis, bytes.length); dbcSelect.executeUpdate(); dbcSelect.close(); } catch (Exception e) { } } } ④上面的Upload.java文件中同样也用到了另一个自定义的数据库连接类DBConnect.java,源码如下: package util; import java.io.InputStream; import java.sql.*; public class DBConnect { private Connection conn = null; private Statement stmt = null; private PreparedStatement prepstmt = null; public static final int JADMIS_CONNECT = 3; public static final int FTFORDE_CONNECT = 2; public static final int WEBSITE_CONNECT = 1; public static final int PLATFORM_CONNECT = 0; void init() { try { Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); conn = DriverManager.getConnection("proxool.mysql"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } void init(String conName) { try { Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); conn = DriverManager.getConnection("proxool." + conName); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public DBConnect(int ConnectIndex) throws SQLException { switch (ConnectIndex) { case JADMIS_CONNECT: init("jadmis"); break; case WEBSITE_CONNECT: init("website"); break; case PLATFORM_CONNECT: init("mysql"); break; case FTFORDE_CONNECT: init("ftde"); break; } stmt = conn.createStatement(); } public DBConnect(int ConnectIndex, int resultSetType, int resultSetConcurrency) throws SQLException { switch (ConnectIndex) { case JADMIS_CONNECT: init("jadmis"); break; case WEBSITE_CONNECT: init("website"); break; case PLATFORM_CONNECT: init("mysql"); break; case FTFORDE_CONNECT: init("ftde"); break; } stmt = conn.createStatement(resultSetType, resultSetConcurrency); } public DBConnect() throws SQLException { init(); stmt = conn.createStatement(); } public DBConnect(int resultSetType, int resultSetConcurrency) throws SQLException { init(); stmt = conn.createStatement(resultSetType, resultSetConcurrency); } public DBConnect(String sql) throws SQLException { init(); this.prepareStatement(sql); } public DBConnect(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { init(); this.prepareStatement(sql, resultSetType, resultSetConcurrency); } //added by tmw 080221 public DBConnect(int ConnectIndex,String sql) throws SQLException { switch (ConnectIndex) { case WEBSITE_CONNECT: init("website"); break; case PLATFORM_CONNECT: init("ft"); break; case FTFORDE_CONNECT: init("ftde"); break; case JADMIS_CONNECT: init("mysql"); break; } this.prepareStatement(sql); } //added by tmw 080221 public DBConnect(int ConnectIndex,String sql, int resultSetType, int resultSetConcurrency) throws SQLException { switch (ConnectIndex) { case WEBSITE_CONNECT: init("website"); break; case PLATFORM_CONNECT: init("ft"); break; case FTFORDE_CONNECT: init("ftde"); break; case JADMIS_CONNECT: init("mysql"); break; } this.prepareStatement(sql, resultSetType, resultSetConcurrency); } public Connection getConnection() { return conn; } public void prepareStatement(String sql) throws SQLException { prepstmt = conn.prepareStatement(sql); } public void prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { prepstmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency); } public void setString(int index, String value) throws SQLException { prepstmt.setString(index, value); } public void setInt(int index, int value) throws SQLException { prepstmt.setInt(index, value); } public void setBoolean(int index, boolean value) throws SQLException { prepstmt.setBoolean(index, value); } public void setDate(int index, Date value) throws SQLException { prepstmt.setDate(index, value); } public void setLong(int index, long value) throws SQLException { prepstmt.setLong(index, value); } //add by sch public void setDouble(int index, double value) throws SQLException { prepstmt.setDouble(index, value); } //add by sch public void setObject(int index, Object value)throws SQLException { prepstmt.setObject(index,value); } public void setFloat(int index, float value) throws SQLException { prepstmt.setFloat(index, value); } public void setBytes(int index, byte[] value) throws SQLException { prepstmt.setBytes(index, value); } public void setBinaryStream(int index, InputStream is, int length) throws SQLException { prepstmt.setBinaryStream(index, is, length); } public void clearParameters() throws SQLException { prepstmt.clearParameters(); prepstmt = null; } public PreparedStatement getPreparedStatement() { return prepstmt; } public Statement getStatement() { return stmt; } public ResultSet executeQuery(String sql) throws SQLException { if (stmt != null) { return stmt.executeQuery(sql); } else return null; } public ResultSet executeQuery() throws SQLException { if (prepstmt != null) { return prepstmt.executeQuery(); } else return null; } public void executeUpdate(String sql) throws SQLException { if (stmt != null) stmt.executeUpdate(sql); } public void executeUpdate() throws SQLException { if (prepstmt != null) prepstmt.executeUpdate(); } public void close() throws SQLException { if (stmt != null) { stmt.close(); stmt = null; } if (prepstmt != null) { prepstmt.close(); prepstmt = null; } if (conn != null) { conn.close(); conn=null; } } } ⑤此外,由于用到了proxool数据库连接池,所以需要添加proxool.xml并修改web.xml配置文件,proxool.xml源码如下: <?xml version="1.0" encoding="ISO-8859-1"?> <!-- the proxool configuration can be embedded within your own application's. Anything outside the "proxool" tag is ignored. --> <something-else-entirely> <proxool> <alias>mysql</alias> <driver-url>jdbc:jtds:sqlserver://localhost:1433;DatabaseName=lwjtest</driver-url> <driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="sa" /> <property name="password" value="sa /> </driver-properties> <maximum-connection-count>5000</maximum-connection-count> <minimum-connection-count>5</minimum-connection-count> <maximum-active-time>60000</maximum-active-time> </proxool> </something-else-entirely> web.xml配置文件代码如下: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <!--Connecting Pool --> <servlet> <servlet-name>ServletConfigurator</servlet-name> <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class> <init-param> <param-name>xmlFile</param-name> <param-value>WEB-INF/proxool.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>Admin</servlet-name> <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Admin</servlet-name> <url-pattern>/admin</url-pattern> </servlet-mapping> <!--Connecting Pool Over --> <servlet> <servlet-name>ImgDealServlet</servlet-name> <servlet-class>servlet.ImgDealServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ImgDealServlet</servlet-name> <url-pattern>/ImgDealServlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>upfile.jsp</welcome-file> </welcome-file-list> </web-app> ⑥此外,还需要导入几个jar包,jspsmartupload.jar、jtds-1.1.jar和proxool-0.9.0RC3.jar,至于这三个包是做什么用的,我想就不用我多说了吧。 两个图片我用的都是BufferedImage类,因为不同了解流的用法,所以可能会有些不当。此外,还有一点要说明的是,如果jsp文件中字符编码格式用utf-8时,不支持图片的中文路径,改为gb2312就OK了。 由于是第一次发帖,且源码基本为本人及朋友所改写,错误及不当之处一定不少,还请大家多多指教,在此谢过!