使用Struts2上传图片存取到Mysql中并读取出来显示在页面上
李顺利
Google 标签: 李顺利;Struts;图片;存取;存入;显示;Mysql;数据库;Blob
索引... 1
关键词... 1
序... 2
准备工作... 2
开发环境... 3
流程和主要代码... 3
创建数据库... 3
整合SSH.. 4
主要代码(知识)... 5
程序截图... 12
分享和下载... 14
 
李顺利,Struts,图片,存取,存入,显示,Mysql,数据库,Blob,
         实际上,写完多文件上传和下载文章的时候,类似的想法就已经有了,一直没有实际把它整理好,今天也终于把这方面的一些经验分享给大家了。
         本文涉及到的需求(功能点)大致有:
1.       如何上传图片,并把图片存入数据库(Mysql)中;
2.       从数据库中读取图片并显示在页面中
注:本文使用的是单纯的Struts2 + Spring + Hibernate,图片操作并没有使用Servlet。
 
         本文全部使用Annotation来整合SSH,运用了文件上传和表单验证等知识,这些知识都可以在我以前写的博文中获取到,包括
1.       Struts2下多文件的上传与下载
http://www.blogjava.net/lishunli/archive/2010/01/07/308614.html
 
2.       使用Annotation并对DAO层封装具有分页功能的S2SH整合实例
http://www.blogjava.net/lishunli/archive/2010/03/10/315055.html
http://www.blogjava.net/lishunli/archive/2010/03/12/315231.html
 
3.       如何自定义Struts2表单验证后的错误信息显示格式/样式
http://www.blogjava.net/lishunli/archive/2010/10/17/335384.html
http://www.blogjava.net/lishunli/archive/2010/01/07/308609.html
 
         如果大家对上面的知识有所欠缺的话和想学习的话,也请大家Google或者看我的blog。谢谢。
 
 Struts 2.1.8.1 + Hibernate3 + Spring3+ Mysql5 + Tomcat 7.0.2+ Myeclipse 8.6
 
本文会使用User对象(包括username、password、picture等属性),对应Mysql数据库的创建脚本如下:
    
        
            | /* Source Server         : Local Source Server Version : 50140 Source Host           : localhost:3306 Source Database       : test   Target Server Type    : MYSQL Target Server Version : 50140 File Encoding         : 65001   Date: 2010-11-13 23:23:37 */   SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `user` -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (   `id` int(100) NOT NULL AUTO_INCREMENT,   `username` varchar(100) NOT NULL,   `password` varchar(100) NOT NULL,   `picture` longblob,   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8; | 
    
(请注意pictrue的类型)
 
这个步骤请参考使用Annotation并对DAO层封装具有分页功能的S2SH整合实例。
 
1、  User 类
实际上很简单,写出来,主要是让大家知道这里面图片是使用的是什么类型
    
        
            | @Entity @Table(name = "user", catalog = "test") public class User implements java.io.Serializable {      private static final long serialVersionUID = 4230186551226007292L;        private Integer id;      private String username;      private String password;      private Blob picture;            /**       * 省略构造方法和set、get方法       */   } | 
    
 
2、  AddUserAction类
在add user action,就是真正的把User对象(包括图像)save到Mysql中。其中这里使用了Struts2的Annotation,请注意 InterceptorRefs 中 params 的写法。
关键的代码也就是使用hibernate的createBlob方法来把File类型转换成Blob类型。
Blob blob = Hibernate.createBlob(..)
 
    
        
            | @Controller @Scope("prototype") @Results( { @Result(name = "success", location = "/index.jsp"), @Result(name = "input", location = "addUser.jsp") }) @InterceptorRefs(value = {          @InterceptorRef(value = "fileUpload", params = { "maximumSize", "1048576", "allowedTypes","image/bmp,image/x-png,image/png,image/gif,image/jpeg,image/jpg,image/pjpeg" }), @InterceptorRef(value = "defaultStack") }) public class AddUserAction extends ActionSupport {      private static final long serialVersionUID = -4829467290275994251L;        private User user;      private File image;        @Resource(name = "org.usc.services.userService")      private IUserService userService;            /**       * 省略 set、get方法和validate验证       */        @Override      public String execute() throws Exception {          if (image != null) {               FileInputStream fin = new FileInputStream(image);// File 转 InputStream               Blob blob = Hibernate.createBlob(fin);// InputStream 转 Blob               user.setPicture(blob);          }            userService.save(user);            return SUCCESS;      } } | 
    
 
3、  addUser.jsp 
这个就是一个普通的Input界面,很简单。想说一下,这里使用了表单验证后信息显示的技术,详情请见如何自定义Struts2表单验证后的错误信息显示格式/样式,也请注意这里使用了文件上传控件,所以要设置enctype="multipart/form-data"。
 
    
        
            | <s:form action="add-user" method="post" theme="simple" enctype="multipart/form-data">      UserName<s:textfield name="user.username"></s:textfield>      <font color="red"> *<s:property value="fieldErrors['user.username'][0]" /> </font>      <br>            PassWord<s:password name="user.password"></s:password>      <font color="red"> *<s:property value="fieldErrors['user.password'][0]" /> </font>      <br>                 Image<s:file name="image"></s:file>      <font color="red"><s:property value="fieldErrors['image'][0]" /> </font>      <br>      <s:submit value="Submit" /><s:reset value="Reset"></s:reset> </s:form> | 
    
 
4、  GetAllUserAction 类
很简单,不想贴代码了,主要是通过Dao查找所有的User,再放到List<User> userList,Struts在调用此Action的使用,通过Iterator List来显示所有的User。
注意:我这里仅使用了List,并没有使用把List放到request中,Struts会通过s:iterator来迭代List,只要我们提供Get List 方法即可。
<s:iterator value="userList" id="user" status="count">
 
5、  GetImageByIdAction 类
这个类应该是本文的难点和重点,实际上,代码很简单的,请大家注意一下几点
1)  使用Result type“Stream” :type = "stream" ;
2)  Result params 中设置 contentType 和inputName参数,其中
contentType  = image/jpeg
inputName  = image
inputName 是Action可以通过相关的method获得InputStream。
 
注意:下载文件这里不使用contentType,而是使用contentDisposition参数,详情请见 Struts2下多文件的上传与下载
<param name="contentDisposition">attachment;filename="${fileName}"</param>
(Action可以通过Get,Set FileName()来设置和获得文件名)
         
         实际上这部分的代码是参考以前某位朋友写的使用Struts2 生成验证码的例子,参考下面的网站
struts2 实现图片验证码
不好意思,现在记不清作者和网站,所以贴上的网址不知道是否是原创或者就是原创,如果有朋友知道,请联系我,我会更新链接的,谢谢,也很感谢这位朋友的无私奉献。
 
    
        
            | @Controller @Scope("prototype") @Results( { @Result(type = "stream", params = { "contentType", "image/jpeg", "inputName", "image" }) }) public class GetImageByIdAction extends ActionSupport {        private static final long serialVersionUID = 207987943720580274L;        private Integer id;        @Resource(name = "org.usc.services.userService")      private IUserService userService;        public Integer getId() {          return id;      }        public void setId(Integer id) {          this.id = id;      }        public void setUserService(IUserService userService) {          this.userService = userService;      }        /**       * 注意这里的方法名,和上面配置params中inputName是一致的,Struts会调用此方法(也可以使用Method配置其他方法)       * @return       * @throws Exception       */      public InputStream getImage() throws Exception {          InputStream imageStream = userService.find(id).getPicture().getBinaryStream();                    return imageStream;      }   } | 
    
 
6、  allUser.jsp
这个JSP也算知识点比较多,包括一下几点
1)  Action如何取得Image显示在页面上
通过调用get-image-by-id.action来获取图片
2)  list如何Iterator
<s:iterator value="userList" id="user" status="count">
// 注意value
3)  Table可以限制每行显示多少条记录
         <s:if test="#count.index % 6 == 0">
              <tr>
         </s:if>
         <s:if test="(#count.index + 1) % 6 == 0">
              </tr>
         </s:if>
// 每行显示6 条记录
(延伸,也可以控制只显示多少条,给个链接,显示所有的条数)
4)  如果标题长了,省略多余的字,避免表格撑大
<td width="800" height="120" style="width: 200px; word-break: break-all" align="center">
<div style="width: 200x; height: 20px; border: 1px; overflow: hidden; text-overflow: ellipsis">
(单元格固定宽带,不是随着内容的变化而变化)
5)  如果没找到图片的话,选择默认图片显示
<img … onerror="javascript:this.src='images/default.png'" />
 
    
        
            | <s:form action="get-all-user" method="post" theme="simple">      <s:if test="userList.size">          <table width="75%" align="center">               <s:iterator value="userList" id="user" status="count">                    <s:if test="#count.index % 6 == 0">                        <tr>                    </s:if>                      <td width="800" height="120" style="width: 200px; word-break: break-all" align="center">                        <a href="http://www.blogjava.net/lishunli/" target="_blank">                             <img src="<%=basePath + "get-image-by-id.action?id="%><s:property value="#user.id"/>" width="100" height="100" alt="照片"                                  title="<s:property value="#user.username" />" onerror="javascript:this.src='images/default.png'" />                         </a>                        <div style="width: 200x; height: 20px; border: 1px; overflow: hidden; text-overflow: ellipsis">                             <s:property value="#user.username" />                        </div>                    </td>                      <s:if test="(#count.index + 1) % 6 == 0">                        </tr>                    </s:if>               </s:iterator>          </table>      </s:if> </s:form> | 
    
 



 
本文全部使用的是Annotation(包括Struts2的所有配置),如果需要使用xml但又觉得转化成xml配置有困难的话,可以Google,或者联系我。谢谢。
本篇文章还是可以延伸的,可以做成上传文件,再判断文件类型,例如是Image类型的,就显示出来,如果是Txt等类型,可以提供下载。后续…或者Ending…
 
源码在Google Code上
https://usc.googlecode.com/svn/ImageUseStruts2AndMysql
 
源码和相关参考提供下载
    Via http://pan.baidu.com/s/1ntulO4D
    
(源码和所需Jar)
文 件 名:ImageUseStruts2AndMysql.zip
其中 ImageUseStruts2AndMysql.zip 有下面的文件

 
 
如果有什么建议或意见可以通过微博 http://weibo.com/lishunli(左上侧直接加关注) 或 QQ:506817493 或 Email:leeshunli@qq.com 或 MSN:lishunli@live.com(QQ白天经常不在线,建议微博或者MSN 交流,谢谢),大家一起交流学习。
     这篇博文是基于(Struts2下多文件的上传与下载)以前写的,如果有什么不明白的地方,也可以前往看看,谢谢。
      最后弱弱地说一下,如果可以的话,转载请提供原URL,谢谢。
 
 
顺利写于2010年11月14日
 
博客中的一些下载已经放到了百度云了,请根据需要下载。【点我去百度云下载】
最后弱弱地说一下,如果可以的话,转载请提供出处(
),谢谢。
 
	posted on 2010-11-14 01:43 
李顺利 阅读(13325) 
评论(16)  编辑  收藏