彻底解决SSH架构下的图片存取问题

搞完2个J2EE项目后,现在回到学校,见经常有人问如何来处理J2EE中对图片的DB存取,今天借学校的这个有点名气的论坛.略微发表下我对这中问题的解决看法.希望大家踊跃顶贴.
  基本的就不说了,这里直接进入正题,由于图片的binary码很大,往往在存数据库的时候都会采用java.sql.Blob类型,这是技术规范下统一的观点,而具体操作需要借助于java.IO(Input/Output)技术来实现.
首先:建立好数据表 user,字段为:  id(varchar 32,primaryKey),username(varchar 20),photo(blob)
2.  在Spring Ioc容器中配置Hibernate以及对它的声明式事物代理 spring.cfg.xml
<?xml version encoding="GBK" ?>
  <!DOCTYPE beans
  PUBLIC -//SPRING//DTD BEAN//EN"
  "http://www.springframework.org/dtd/spring-bean.dtd">
<beans>
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
   <value>com.mysql.jdbc.Driver</value>
   </property>
  <property name="url">
   <value>jdbc:mysql://192.168.1.100:3306/mydbms</value>
  </property>
  <property name="username">
   <value>root</value>
  </property>
  <property name="password">
   <value>***</value>
  </property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref local="datasource"/>
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    </props>
   </property>
  <property name="mappingResources">
   <list>
     <value>user.hbm.xml</value>
   </list>
  </property>
</bean>
<bean id="userDAO" clas="test.userDAO">
   <property name="sessionFactory">
     <ref local="sessionfactory"/>
   </property>
  </bean>
<bean id="tansactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory">
   <ref local="sessionFactory"/>
  </property>
</bean>
<!--配制代理-->
<bean id="user" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager">
    <ref local="tansactionManager"/>
  </property>
  <property name="target">
    <ref local="userDAO"/>
  </proeprty>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
  <props>
     <prop key="set*">PROPAGATION_REQUIRED</prop>
     <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
     <prop key="delete*">PROPAGATION_REQUIRED,readOnly</prop>
     <prop key="update*">PROPAGATION_REQUIRED,readOnly</prop>
   </props>
</property>
</bean>
</beans>

3.定义Hibernate映射文件 user.hbm.xml
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-dtd-3.0.dtd">
<hibernate-mapping>
<class name="test.user" table="user">
   <id name="id" unsaved-value="false">
    <generator class="uuid.hex"/>
   </id>
   <property name="username" type="string" column="username"/>
   <property name="photo" type="blob" column="photo"/>
  </class>
</hibernate-mapping>

4.编写实体Bean user.java
package test;
public class user implements java.io.Serializable{
  private String id,username;
  private java.sql.Blob photo;
  public void setId(String id){
   this.id=id;
  }
  public String getId(){
   return this.id;
}
public void setUsername(String username){
  return this.username;
}
public String getUsername(){
  return this.username;
}
public void setPhoto(java.sql.Blob photo){
  this.photo=photo;
}
public java.sql.Blob getPhoto(){
return this.photo;
  }
}

5 编写DAO层  userDao.java
package test;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
public class userDao extends HibernateDaoSupport{
private static Logger log=Logger.getLogger(userDao.class);
static{
   BasicConfigurator.configure();
}
  public void setUser(user user){
   getHibernateTemplate().save(user);
}
public void updateUser(user user){
  getHibernateTemplate().update(user);
}
public void deleteUser(user user){
  getHibernateTemplate().delete(user);
}
public user getUserByPrimaryKey(String id){
  return getHibernateTemplate().get(user.class,id);
}
public java.util.List getAllUsers(){
return getHibernateTemplate().find("from user");
  }
}

6.编写添加照片的用户注册JSP页:  registry.jsp
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uti="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html:html lang="true">
<html:base />
<head><head>
<body>
  <html:form action="/registry" method="post">
  UserName:<html:text property="username"/>
  Photo:<html:file property="photo"/>
  <html:submit value="registry"/>
  </html:form>
</body>
</html:html">

7.编写显示图片的页 view.jsp
<@% taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html:html>
<body>
  <img src="http://192.168.1.100:8080/test/servlet/photo?user=<c:out value="${user}"/>">
</body>
</html:html>

8.实现Struts MVC
8.1: 注册实现: ActionForm
   package test.mvc;
   import org.apache.struts.action.ActionForm;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   public class registryForm extends ActionForm{
     private String id,username,photo;
    //省略对属性的setter and getter
   }

  registryAction.java
package test.mvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
public class registryAction extends Action{
  public ActionForward execute(ActionMapping mapp,ActionForm form,HttpServletRequest req,HttpServletResponse res)throws Exception{
  WebApplicationContext context=WebApplicationContextUtils.getRequiredWebApplicationContext(this.servlet.getServletContext());
  registryForm Form=(registryForm)form;
  java.io.FileInputStream is=new java.io.FileInputStream(new java.io.File(Form.getPhoto()));
  java.sql.Blob blob=org.hibernate.Hibernate.createBlob(is);
  userDao dao=(userDao)context.getBean("user");
  user user=new user();
  user.setUsername(Form.getUsername());
  user.setPhoto(blob);
  dao.setUser(user);
  req.setAttribute("user",user);   //把VO对象传递给下一站
  return mapp.findForward("registryOK");
     }
}

8.编写处理相片的servlet   photo.java
package test.support;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import java.io.InputStream;
import java.io.IOException
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;

public class photo extends HttpServlet{
private static Logger log=Logger.getLogger(photo.class);
static{
    BasicConfigurator.configure();
}
public void init(ServletConfig config)throws ServletException{
   super.init(config);
}
public void service(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOExceotion{
  res.reset();
  res.setContentType("image/jpeg");
  ServletOutputStream sop=res.getOutputStream();
  if(req.getParameter("user")==null){
    log.error("could not find Object user !");
    return;
   }
user user=(user)req.getParameter("user");
InputStream is=user.getPhoto().getBinaryStream();
byte[] bts=new byte[is.available()];
sop.write(bts);
   }
}

Struts.cfg.xml这里稍微懂点Struts框架的人都会配置,我就懒得多写了,逻辑流程是:
    regisry.jsp------------------>registryAction--------------------->view.jsp
这样只要注册了registry页,将会自动来到view.jsp.同时在view.jsp显示注册时的图片,只要传给photo这个servlet的参数user对象是持久对象.就能打出它的图片出来,本架构设计的有点粗糙,没有实现高层抽象,但相对弹性还是蛮大的,主要核心组件(photo.java和Action之间并不依赖.)
这里有个最重要的问题就是: servlet的response只能做一种方式的响应,换句话说就是用了PrintWriter后就不能用ServletOutputStream,否则它就要抗议了,它俩之间任意选一种,注意区别,Printwriter是打印流,用来把信息输到控制台,而ServletOutputStream则是用来传输数据,在实际中要根据他们的不同功能做出不同的选择.
  这2天发了几个帖子,怎么不见人顶??

 

http://bbs.star-bbs.net/viewthread.php?tid=36886

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值