存档

‘Java’ 分类的存档

org.hibernate.SessionException: Session is closed! 异常解决方法

2010年4月29日 IT北瓜 6 条评论

刚刚在程序中出现了org.hibernate.SessionException: Session is closed! 这个异常,查看Firebug控制台,还能发现有这样的异常信息org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction;记录一下解决方法。

程序代码如下:

public boolean activityUpdate(Activity activity) throws Exception {

	Session session = null;
	Transaction tran = null;

	boolean r = false;

	try{
		//创建sql
		String sql1 = "delete from Activityfilm where activityid=" + activity.getId();//删除活动影片数据
		String sql2 = "delete from Activityclient where activityid=" + activity.getId();//删除活动客户数据

		//获得session
		session = this.getSession();
		//开始事务
		tran = session.beginTransaction();
		//执行删除操作
		int del_1 = session.createSQLQuery(sql1).executeUpdate(), del_2 = session.createSQLQuery(sql2).executeUpdate();
		System.out.println("del_1: "+ del_1 + "###del_2: " + del_2);
		//更新活动
		session.update(activity);
		if(del_1 > 0 && del_2 > 0){
			r = true;
		}else{
			r = false;
		}
		System.out.println("r: "+ r);
		tran.commit();
		if(!r){//执行回滚
			System.out.println("执行回滚#####################");
			tran.rollback();
		}
	}catch(Exception ex){
		if(tran != null){
			System.out.println("执行回滚@@@@@@@@@@@@@@@@@@@@@");
			tran.rollback();
		}
		ex.printStackTrace();
	}finally{
		if(tran != null){
			System.out.println("设置事务为null");
			tran = null;
		}
		if(session != null){
			System.out.println("关闭session$$$$$$$$$$$$$$$$$");
			session.close();//执行这一行总是报异常:org.hibernate.SessionException: Session is closed! 
		}
	}
	System.out.println("返回: "+ r);
	return r;

}

引用网上的资料:

先看看SessionFactory.getCurrentSession与openSession的区别

1. 如果使用的是getCurrentSession来创建session的话,在commit后,session就自动被关闭了,

    也就是不用再session.close()了。但是如果使用的是openSession方法创建的session的话,

    那么必须显示的关闭session,也就是调用session.close()方法。这样commit后,session并没有关闭

/*2. getCurrentSession的使用可以参见hibernate\hibernate-3.2\doc\tutorial\src项目

3. 使用SessionFactory.getCurrentSession()需要在hibernate.cfg.xml中如下配置:

   * 如果采用jdbc独立引用程序配置如下:

    <property name="hibernate.current_session_context_class">thread</property>

   * 如果采用了JTA事务配置如下

    <property name="hibernate.current_session_context_class">jta</property>*/

将以上程序中的:

//获得session
session = this.getSession();

修改为:

//获得session
session = this.getHibernateTemplate().getSessionFactory().openSession();

这样异常就解决了。

Struts2常见异常与分析处理【不断更新】

2010年1月18日 IT北瓜 1 条评论

      1、ognl.OgnlException: target is null for setProperty

      分析处理:

      在action中有:

private transient Filmrlspack filmrlspack;
/**
 *这里省略了getter、setter方法的代码
 */

      提交数据的表单代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<form method="post" name="wmfForm" id="wmfForm" action="">
<span id="wmf-msg"></span>
<table width="700" border="0" cellspacing="0" cellpadding="0" class="sample">
  <tr>
    <td>影片发行版名称:</td>
    <td><input type="text" readonly="readonly" name="Filmrlspack.filmname" value="<%=request.getParameter("filmname") %>" /></td>
    <td>业务类型:</td>
    <td><input type="hidden" name="businesstypeID"  value="<%=request.getParameter("businesstypeID") %>" /><input type="text" name="businesstypeName" readonly="readonly" value="<%=request.getParameter("businesstypeName") %>" /></td>
  </tr>
  <tr>
    <td>出品单位:</td>
    <td><input type="text" name="Filmrlspack.manufacture" /></td>
    <td>出品年代:</td>
    <td><input type="text" name="Filmrlspack.manufacturedate" /></td>
  </tr>
  <tr>
    <td>导演:</td>
    <td><input type="text" name="Filmrlspack.directors" /></td>
    <td>主演:</td>
    <td><input type="text" name="Filmrlspack.leaderact" /></td>
  </tr>
  <tr>
    <td>语种:</td>
    <td><input type="text" name="Filmrlspack.langtype" /></td>
    <td>是否主语种:</td>
    <td><input type="checkbox" name="Filmrlspack.maintype" value="1" checked="checked" /></td>
  </tr>
  <tr>
    <td>影片描述:</td>
    <td colspan="3"><textarea rows="5" cols="75"  name="Filmrlspack.filmname" ></textarea></td>
  </tr>
</table>
</form>

      其中很多字段为非必填字段,若什么都不填提交到action中为null,报以上异常。

      把action中的

private transient Filmrlspack filmrlspack;
/**
 *这里省略了getter、setter方法的代码
 */

      改成

private transient Filmrlspack filmrlspack = new Filmrlspack();
/**
 *这里省略了getter、setter方法
 */

      就可以了。

      2、Caused by: There is no result type defined for type ‘redirect-action’ mapped with name

      分析处理:

      在struts.xml中配置如下:

<global-results>
	<result name="login" type="redirect-action">redirectLoginAction</result>
</global-results>

       报以上异常,用的Struts2包版本为2.1.8.1,后来查看了jar包中的struts-default.xml,发现type中没有redirect-action这一类型,而是变成了redirectAction,把type=”redirect-action”改成type=”redirectAction”就不会有这个异常了。

      (2010年1月19日更新)

      3、待更新…

      分析处理:

JDK1.6存储空间信息计算

2010年1月15日 IT北瓜 没有评论

      在JDK6.0之前,获取剩余存储空间是很困难的事情,需要借助Java本地调用JNI才能做到,在JDK6.0之后引入了获取可用存储空间的3个方法。

/**
 * @ 功能 返回此抽象路径名指定的分区总存储空间大小,以字节为单位;如果此抽象路径名没有指定分区,则返回 0L。
 * @ return Long
 */
public long getTotalSpace()
/**
 * @ 功能 返回此抽象路径名指定的分区中未分配的字节数。
 * @ return Long
 */
public long getFreeSpace()
/**
 * @ 功能 返回此抽象路径名指定的分区上可用于此虚拟机的字节数。
 *             若有可能,此方法将检查写权限和其他操作系统限制,
 *             因此与 getFreeSpace() 相比,此方法能更准确地估计可实际写入的新数据数。
 *             分区上的可用字节数;如果抽象路径名没有指定分区,则返回 0L。
 *             在此信息不可用的系统上,此方法等效于调用 getFreeSpace()。
 * @ return Long
 */
public long getUsableSpace()

测试类:

package com.io;

import java.io.File;

public class Test {

	public static void main(String[] arges){
		File fi=new File("D:\\电影");

		System.out.println("总分区大小="+fi.getTotalSpace());
		System.out.println("剩余分区大小="+fi.getFreeSpace());
		System.out.println("剩余分区大小="+fi.getUsableSpace());

	}
}
分类: Java 标签: ,

Hibernate常见异常与分析处理(收集整理)

2010年1月7日 IT北瓜 没有评论

1.    net.sf.hibernate.MappingException

分析处理:

当出现net.sf.hibernate.MappingException: Error reading resource:…异常时一般是因为映射文件出现错误。
当出现net.sf.hibernate.MappingException: Resource: … not found是因为XML配置文件没找到所致,有可能是放置目录不正确,或者没将其加入hibernate.cfg.xml中。

2.    net.sf.hibernate.PropertyNotFoundException

分析处理:

当出现net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class …时,原因一般是因为XML映射文件中的属性与对应的Java类中的属性的getter或setter方法不一致。

3.    org.hibernate.id.IdentifierGenerationException

分析处理:

当出现org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():异常时,一般是因为<id>元素配置不正确,<id>元素缺少其子元素<generator></generator>的配置引起。

<id>元素映射了相应数据库表的主键字段,对其子元素<generator class="">,其中class的取值可以为increment、identity、sequence、hilo、nativ-e……等,更多的可参考hibernate参考文档,一般取其值为native。

4.    a different object with the same identifier value was already associated with the session

分析处理:

当出现a different object with the same identifier value was already associated with the session时,一般是因为在hibernate中同一个session里面有了两个相同标识但是是不同实体。

有如下几种解决方案:
(1)使用session.clean(),如果在clean操作后面又进行了saveOrUpdate(object)等改变数据状态的操作,有可能会报出"Found two representations of same collection"异常。
(2)使用session.refresh(object),当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因为该方法是从hibernate的session中去重新取object,如果session中没有这个对象,则会报错所以当你使用saveOrUpdate(object)之前还需要判断一下。
(3)session.merge(object),Hibernate里面自带的方法,推荐使用。

5.    SQL Grammer Exception,Could not execute JDBC batch update

分析处理:

当出现SQL Grammer Exception,Could not execute JDBC batch upd-ate异常时,一般是由如下问题引起:
(1)SQL语句中存在语法错误或是传入的数据有误;
(2)数据库的配置不合法,或者说是配置有误。较容易出现的有数据表的映射文件
(,hbm.xml文件)配置有误;Hibernate.cfg.xml文件配置有误;
(3) 当前的数据库用户权限不足,不能操作数据库。以是以Oracle 数据库为例,这种情况下在错误提示中会显示java.sql.BatchUpdateException: ORA-01031: ins-ufficient privileges这样的信息。

6.  Caused by: org.dom4j.DocumentException: Invalid byte 2 of2-byte UTF-8 sequence. Nested exception: Invalid byte 2 of2-byte UTF-8 sequence.

分析处理:

如果出现这行错误说明你的XML配置文件有不规范的字符,检查下。

7.  hibernate/Hello_Bean.hbm.xml

分析处理:

如果出现这行错误说明你的hibernate的XML配置文件有错

8.  net.sf.hibernate.HibernateException: JDBC Driver class not f-ound: org.gjt.mm.mysql.Driver:

分析处理:

没有找到数据库驱动程序

9.  The database return no natively generate indentity value

分析处理:

主键没有添加增量

10.  net.sf.hibernate.PropertyValueException:not-null property ref-erences a null or transient

分析处理:

value:com.pack.Rordercontent.异常产生原因:Rordercontent对象的非空属性Rordertable引用了一个临时对象。

11.  net.sf.hibernate.TransientobjectException:objiect references an unsaved transient instance – save the transient instance before flushing: com.pack.Rordertable

分析处理:

持久化对象的某个属性引用了一个临时对象Rordertable

12.   net.sf.hibernate.PropertyNotFoundException

分析处理:

当出现net.sf.hibernate.PropertyNotFoundException: Could not find a setter for pr-operty name in class …时,原因一般是因为XML映射文件中的属性与对应的Java类中的属性的getXXX或setXXX方法不一致。

13.  tce of my chapter.pack6.Rordertable altered from 1 to 100:

分析处理:

企图修改处于持久化状态的对象的OID。修改了处于持久化对象的OID在Session清理缓存时就会抛出此异常(对象处于持久化状态时。不允许程序随意修改它的OID。注意:无论java对象处于临时状态、持久化状态还是游离状态,应用程序都不应该修改它的OID。因为,比较安全的做法时,在定义持久化类时,吧他的setId()方法设为private类型,禁止外部程序访问该方法)。

14.  net.sf.hibernate.MappingException: Unknown entity class:未知的实体类

分析处理:

Hibernate把持久化类的属性分为2种:值(Value)类型和实体(Entity)类型。值类型和实体类型最重要的区别是前者没有OID,不能被单独持久化,它的声明周期依赖于所属的持久化类的对象的声明周期,组件类型就是一种值类型;而实体类型有OID,可以被单独持久化。

15.   net.sf.hibernate.QueryException: undefined alias

分析处理:

我猜想出项这种错误的原因有很多种:可能是大小写问题,还有其他很多种可能

16.   net.sf.hibernate.NonUniqueResultException:

分析处理:

检索单个对象时,查询结果包含多个对象,但没有调用setMaxResult(1)方法

17.  net.sf.hibernate.QueryException: Not all named paramete-rrs have been set

分析处理:

使用setProperties()方法:用于把命名参数与一个对象的属性值绑定时,对象中没有匹配的名字相同的属性。

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition.

2009年12月31日 IT北瓜 没有评论

昨天遇到这个异常“org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction definition.”大概意思是说试图在只读模式下向数据库插入内容。由于出现这个异常的时候刚好要下班了,所以今天才把这个异常解决了,在这里记录一下。

由于博客上没有装代码高亮插件,都是用Windows Live Writer写文章,现在的这个电脑上没安装Windows Live Writer,所以一下内容引用代码的部分就没办法高亮显示了,不过涉及的代码不多,讲究着吧~~~

问题分析:上面的异常总的来说是由于lazy机制引起的,我们知道懒加载问题一般都是通过配置OpenSessionInViewFilter来解决。原先web.xml中配置OpenSessionInViewFilter部分的代码如下:

<filter>
<description>处理Hibernate的懒加载问题</description>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

解决方法:其实异常信息中已经很清楚的告诉我们解决方法了,异常中说到需要把session改为FlushMode.COMMIT(或者FlushMode.AUTO),抑或去掉Spring事务配置中的readOnly。这里Leeo选择将session改为FlushMode.COMMIT的方式。具体做法是自己写一个类继承org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,代码如下:

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

public class OpenSessionInViewFilter extends
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter {
/**
* we do a different flushmode than in the codebase
* here
*/
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.COMMIT);
return session;
}
/**
* we do an explicit flush here just in case
* we do not have an automated flush
*/
protected void closeSession(Session session, SessionFactory factory) {
session.flush();
super.closeSession(session, factory);
}

}

然后只要把原先web.xml中的

<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter改为刚刚写的类的包路径就可以了,即:

<filter-class>
com.frscs.util.OpenSessionInViewFilter
</filter-class>

分类: Hibernate, Java, Spring 标签:

struts2 Action中获取request, response对象的方法

2009年12月29日 IT北瓜 没有评论

struts2 Action中获取request, response对象的方法

ActionContext ctx = ActionContext.getContext();

HttpServletRequest request = (HttpServletRequest)ctx.get(ServletActionContext.HTTP_REQUEST);

HttpServletResponse response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE);

分类: Java, Struts2 标签:

java中从含反斜杠路径截取文件名的方法

2009年12月19日 IT北瓜 没有评论

      例如:获取到的文件路径为C:\Documents and Settings\Leeo\My Documents\logo.gif

      现在想要取得图片的名称logo.gif,我们知道反斜杠“\”是转义字符,所以不能直接

String temp[] = filePath.split("\");//filePath的值就是上面的文件路径

      来分割文件路径,而应该这样写

/*
 *java中\\表示一个\,而regex中\\也表示\,
 *所以当\\\\解析成regex的时候为\\
 **/
String temp[] = filePath.split("\\\\");

      在Linux系统中

System.getProperty("file.separator", "\\")

      输出为“/”,而在Windows系统中输出为“\”,所以要兼容两者可以这么写

String temp[] = filePath.replaceAll("\\\\","/").split("/");

      获取文件名称的完整代码如下:

String temp[] = filePath.replaceAll("\\\\","/").split("/");
String fileName = ""
if(temp.length > 1){
    fileName = temp[temp.length - 1];
}
分类: Java 标签: , ,

Struts2 jQuery Plugin

2009年12月18日 IT北瓜 没有评论

Leeo本人一直很喜欢jQuery这个优秀的js框架。刚刚在Google搜索jqGrid结合Struts2使用的时候,无意中发现这这么一个插件“Struts2 jQuery Plugin”,貌似很不错,以后有空要研究研究,这里暂时做个记录,方便日后查阅。

作者博客:http://www.jgeppert.com/

项目地址:http://code.google.com/p/struts2-jquery/

实例地址:http://www.weinfreund.de/struts2-jquery-showcase/index.action

分类: Struts2, jQuery, 插件推荐 标签:

Struts2+FlashFileUpload文件上传并生成缩略图和添加水印

2009年11月6日 IT北瓜 21 条评论

      以前用过SWFUpload,功能确实很强大。javaeye上有人发布了这样一篇文章step-by-step多文件WEB批量上传(swfupload)的完美解决方案有兴趣的朋友可以看一下。Leeo觉得SWFUpload稍微不足的就是界面的定制,总感觉自己定制出来的界面有点难登大雅之堂。下面Leeo为大家介绍一下,如何使用FlashFileUpload这个Flash组件来实现多文件上传,并且通过java程序自动生成缩略图和添加水印,FlashFileUpload定制出来的界面还是挺漂亮的(PS:这个界面是Leeo从UUShare上弄下来的,^_^),先来Show一张效果图:

      从上面的图片从可以看出中间有个水印(PS:本博客的Logo),这并不是用Photoshop之类的软件弄上去的,而是通过下面将要讲到的java程序自动添加的,效果很不错,(*^__^*) 嘻嘻……好,正式开始吧…

      第一步:当然是获取flashfileupload.swf这个Flash组件啦,大家可以从这里下载,或者其他什么途径得到都行

      第二步:编写上传页面的代码如下:

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
  String uploadType = (String)request.getParameter("uploadType");
  Long filmid = Long.parseLong((String)request.getParameter("filmid"));
  //out.print(uploadType);
  //out.print(filmid);
%>
<object id="fileUpload"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab#version=10,0,22,87"
    height="310" width="500" align="middle"
    classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000">
    <param name="_cx" value="13229" />
    <param name="_cy" value="8202" />
    <%
        if("Video".equals(uploadType)){
    %>
    <param name="flashvars" value="fileTypeDescription=允许视频格式&fileTypes=*.asx;*.asf;*.mpg;*.wmv;*.3gp;*.mp4;*.mov;*.avi;*.flv;*.wmv9;*.rm;*.rmvb&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>" />
    <%
        }else{
    %>
    <param name="flashvars" value="fileTypeDescription=JPG格式图片&fileTypes=*.jpg;*.jpeg&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>" />
    <%
        }
    %>
    <param name="movie" value="flashfileupload.swf?ver=20090520" />
    <param name="src" value="flashfileupload.swf?ver=20090520" />
    <param name="wmode" value="transparent" />
    <param name="play" value="0" />
    <param name="loop" value="-1" />
    <param name="quality" value="high" />
    <param name="salign" value="lt" />
    <param name="menu" value="-1" />
    <param name="base" value="" />
    <param name="allowscriptaccess" value="sameDomain" />
    <param name="scale" value="noscale" />
    <param name="devicefont" value="0" />
    <param name="embedmovie" value="0" />
    <param name="bgcolor" value="" />
    <param name="swremote" value="" />
    <param name="moviedata" value="" />
    <param name="seamlesstabbing" value="1" />
    <param name="profile" value="0" />
    <param name="profileaddress" value="" />
    <param name="profileport" value="0" />
    <param name="allownetworking" value="all" />
    <param name="allowfullscreen" value="true" />
    <%
        if("Video".equals(uploadType)){
    %>
    <embed src="flashfileupload.swf?ver=20090520"
        flashvars="fileTypeDescription=允许视频格式&fileTypes=*.asx;*.asf;*.mpg;*.wmv;*.3gp;*.mp4;*.mov;*.avi;*.flv;*.wmv9;*.rm;*.rmvb&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>"
        quality="high"
        wmode="transparent"
        width="500"
        height="310"
        name="fileUpload"
        align="middle"
        allowscriptaccess="samedomain"
        type="application/x-shockwave-flash"
        pluginspage="http://www.macromedia.com/go/getflashplayer">
    </embed>
    <%
        }else{
    %>
    <embed src="flashfileupload.swf?ver=20090520"
        flashvars="fileTypeDescription=JPG格式图片&fileTypes=*.jpg;*.jpeg&completeFunction=UploadComplete()&fileSizeLimit=3000000&totalUploadSize=10240000&accounttype=0&uploadPage=flashupload!Upload.action;jsessionid=${session.id}?uploadType=<%=uploadType %>-<%=filmid %>"
        quality="high"
        wmode="transparent"
        width="500"
        height="310"
        name="fileUpload"
        align="middle"
        allowscriptaccess="samedomain"
        type="application/x-shockwave-flash"
        pluginspage="http://www.macromedia.com/go/getflashplayer">
    </embed>
    <%
        }
    %>
</object>

说明:其中主要的是flashvars这个参数的设置(PS:Leeo本人对这里的设置也仅仅是略知一二)

fileTypeDescription:允许上传文件的类型描述

fileTypes:允许上传的文件类型

completeFunction:上传完成后调用的js函数

fileSizeLimit:文件大小限制

totalUploadSize:一次性上传文件总大小限制

accounttype:这个没搞清楚怎么用,如果哪位知道的请告知一声,谢谢…

uploadPage:上传文件的请求路径,跟在它后面的是一些用户附加的数据。其中网上有网友说可以;jsessionid=的形式传递session,Leeo没有做测试。?uploadType=是程序中需要的一些附加数据,这里本来需要两个变量的,之所以把它写到一个变量里,然后用“-”隔开两个变量值,就像代码中的<%=uploadType %>-<%=filmid %>,是因为我们知道通常通过url传参是用“&”号隔开的,但这里却不能这么做,因为整个flashvars就是用“&”来隔开不同参数的,如果附加的数据也用“&”隔开就会被截断,得不到我们想要的数据,所以这里用一种比较马虎的解决方法,利用“-”号把不同变量值连接起来,然后在服务器端的java代码中用split("-")再把它们分割开来

    第三步:配置struts.xml文件,如下:

<package name="ajaxfileupload" namespace="/" extends="ajaxfileupload-default">
	<action name="flashupload" class="leeo.action.FlashfileuploadAction">
		<result name="success" type="httpheader">
			<param name="status">200</param>
		</result>
	</action>
</package>

特别说明:这里还用到了ajax-file-upload-plugin-0.4.0.jar(PS:Struts2中用ajxa方式上传文件需要的jar包)

      第四步:编写action类代码,如下:

/** 文件对象 */
private transient File[] Filedata;
/** 文件名 */
/** 文件对象 */
private transient File[] Filedata;
/** 文件名 */
private transient String[] FiledataFileName;
/** 文件内容类型 */
private transient String[] FiledataContentType;

/**
 * 区分是上传海报、剧照、片花
 * **/
private transient String uploadType;

public String Upload() throws Exception {
	System.out.println("FiledataFileName length:" + FiledataFileName.length);
	System.out.println("uploadType:" + uploadType);
	String[] type_filmid = uploadType.split("-");
	System.out.println("filmid:" + type_filmid[1]);

	Film f = filmService.findFilmById(new Long(type_filmid[1]));
	//原文件存放路径  
	String OriginalImageDirectory = ServletActionContext.getServletContext().getRealPath("/UploadFile/" + type_filmid[0] + "/OriginalImage") + System.getProperty("file.separator", "\\");
	for(int i = 0; i < Filedata.length; i ++){
		System.out.println("Filedata["+i+"]:" + Filedata[i]);
		System.out.println("FiledataFileName["+i+"]:" + FiledataFileName[i]);
		System.out.println("FiledataContentType["+i+"]:" + FiledataContentType[i]);

        //在指定目录创建文件
        String newname = FileUpload.getFileName(FiledataFileName[i]);
        File bigFile = new File(OriginalImageDirectory, newname);
        //把要上传的文件copy过去 
        FileUpload.copy(Filedata[i], bigFile);

        if(!"Video".equals(type_filmid[0])){
        	//缩略图存放路径
			String ThumbnailsDirectory = ServletActionContext.getServletContext().getRealPath("/UploadFile/" + type_filmid[0] + "/Thumbnails") + System.getProperty("file.separator", "\\");
			//生成缩略图
			FileUpload.scaleImage(OriginalImageDirectory + newname, ThumbnailsDirectory + newname, 180, 200);
			//设置数据库海报字段路径

			String waterImgFile = ServletActionContext.getServletContext().getRealPath("/UploadFile") + System.getProperty("file.separator", "\\");
	        // 给大图添加文字水印  
	        //FileUpload.watermark(bigFile);  
	        // 给大图添加图片水印,可以是gif或png格式  
	        FileUpload.imageWaterMark(bigFile, waterImgFile);
			File smallFile = new File(ThumbnailsDirectory, newname);
			// 给大图添加文字水印  
	        //FileUpload.watermark(smallFile);  
	        // 给大图添加图片水印,可以是gif或png格式  
	        FileUpload.imageWaterMark(smallFile, waterImgFile);
        }

        /*
         * 操作数据库部分
         * */
        if("Poster".equals(type_filmid[0])){
        	f.setFPoster(newname);
        	filmService.modFilm(f);
        }else if("Still".equals(type_filmid[0])){
        	FilmStill fs = new FilmStill();
        	fs.setFsPath(newname);
        	fs.setFilm(f);
        	filmService.addFilmStill(fs);
        }else if("Video".equals(type_filmid[0])){
        	FilmVideo fv = new FilmVideo();
        	fv.setFvPath(newname);
        	fv.setFilm(f);
        	filmService.addFilmVideo(fv);
        }
	}
	return SUCCESS;
}

public File[] getFiledata() {
	return Filedata;
}

public void setFiledata(File[] filedata) {
	this.Filedata = filedata;
}

public String[] getFiledataFileName() {
	return FiledataFileName;
}

public void setFiledataFileName(String[] filedataFileName) {
	this.FiledataFileName = filedataFileName;
}

public String[] getFiledataContentType() {
	return FiledataContentType;
}

public void setFiledataContentType(String[] filedataContentType) {
	this.FiledataContentType = filedataContentType;
}

public String getUploadType() {
	return uploadType;
}

public void setUploadType(String uploadType) {
	this.uploadType = uploadType;
}

其中,操作数据库部分的代码跟这个例子无关,可以省去。

      第五步:要用到的其他类的代码(PS:这部分代码来自互联网)

      1:FileUpload.java用于生成缩略图、添加水印、生成无重复的文件名

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.imageio.ImageIO;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class FileUpload {

	private static final int BUFFER_SIZE = 16 * 1024;
	private static final String WATER_TEXT = "文字水印";
	private static final String WATER_IMG_NAME = "logo.png";

	/*生成无重复文件名*/
    public static String getFileName(String name){

		SimpleDateFormat df =new SimpleDateFormat("yyyyMMddHHmmss");
		Date date = new Date();
		String filename=null;
		if(!"".equals(name) && name != null){
			filename=df.format(date) + RandomNum.random2() + name.substring(name.lastIndexOf("."), name.length());
		}
		System.out.println("filename is:"+filename);
		return filename;
	}

    /*上传文件*/
	public static void copy(File src, File dst) {
        try {
            InputStream in = null;
            OutputStream out = null;
            try {
                in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
                out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE);
                byte[] buffer = new byte[BUFFER_SIZE];
                while (in.read(buffer) > 0) {
                    out.write(buffer);
                }
            } finally {
                if (null != in) {
                    in.close();
                }
                if (null != out) {
                    out.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

	/*生成缩略图*/
	public static String scaleImage(String fromFileStr, String saveToFileStr, int formatWideth, int formatHeight) throws Exception {
		ScaleImage is = new ScaleImage();
		try {
			is.saveImageAsJpg(fromFileStr, saveToFileStr, formatWideth, formatHeight);
        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "error";
        }
        return "ok";
	}

	/**
	     * 添加文字水印
	     *
	     * @return
	     * @throws Exception
	     * @throws Exception
	     */
	    public static void watermark(File img) throws Exception {
	        System.out.println("[watermark file name]--" + img.getPath());
	        try {  

	            if (!img.exists()) {
	                throw new IllegalArgumentException("file not found!");
	            }  

	            System.out.println("[watermark][img]--" + img);  

	            // 创建一个FileInputStream对象从源图片获取数据流  
	            FileInputStream sFile = new FileInputStream(img);  

	            // 创建一个Image对象并以源图片数据流填充  
	            Image src = ImageIO.read(sFile);  

	            // 得到源图宽  
	            int width = src.getWidth(null);
	            // 得到源图长  
	            int height = src.getHeight(null);  

	            // 创建一个BufferedImage来作为图像操作容器  
	            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	            // 创建一个绘图环境来进行绘制图象  
	            Graphics2D g = image.createGraphics();
	            // 将原图像数据流载入这个BufferedImage  
	            System.out.println("width:" + width + " height:" + height);
	            g.drawImage(src, 0, 0, width, height, null);
	            // 设定文本字体  
	            g.setFont(new Font("宋体", Font.BOLD, 28));
	            String rand = WATER_TEXT;
	            // 设定文本颜色  
	            g.setColor(Color.blue);
	            // 设置透明度  
	            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
	            // 向BufferedImage写入文本字符,水印在图片上的坐标  
	            g.drawString(rand, width - (width - 20), height - (height - 60));
	            // 使更改生效  
	            g.dispose();
	            // 创建输出文件流  
	            FileOutputStream outi = new FileOutputStream(img);
	            // 创建JPEG编码对象  
	            JPEGImageEncoder encodera = JPEGCodec.createJPEGEncoder(outi);
	            // 对这个BufferedImage (image)进行JPEG编码  
	            encodera.encode(image);
	            // 关闭输出文件流  
	            outi.close();
	            sFile.close();  

	        } catch (IOException e) {
	            e.printStackTrace();
	            throw new Exception(e);
	        }
	    }  

	    /**
	     * 添加图片水印
	     *
	     */
	    public static void imageWaterMark(File imgFile, String waterFilePath) throws Exception {
	        try {
	            // 目标文件  
	            Image src = ImageIO.read(imgFile);
	            int wideth = src.getWidth(null);
	            int height = src.getHeight(null);
	            BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
	            Graphics2D g = image.createGraphics();
	            g.drawImage(src, 0, 0, wideth, height, null);  

	            // 水印文件 路径  
	            String waterImgPath = waterFilePath + WATER_IMG_NAME;
	            System.out.println("waterImgPath--" + waterImgPath);
	            File waterFile = new File(waterImgPath);
	            Image waterImg = ImageIO.read(waterFile);  

	            int w_wideth = waterImg.getWidth(null);
	            int w_height = waterImg.getHeight(null);
	            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
	            g.drawImage(waterImg, (wideth - w_wideth) / 2, (height - w_height) / 2, w_wideth, w_height, null);
	            // 水印文件结束  

	            g.dispose();
	            FileOutputStream out = new FileOutputStream(imgFile);
	            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
	            encoder.encode(image);
	            out.close();
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	    }
}

      2:RandomNum.java用于生成无重复随机数

import java.util.Random;

public class RandomNum {

	public static int[] random1() {
		Random r = new Random();
		int temp1, temp2;
		int send[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
		int len = send.length;
		int returnValue[] = new int[22];
		for (int i = 0; i < 22; i++) {
			temp1 = Math.abs(r.nextInt()) % len;
			returnValue[i] = send[temp1];
			temp2 = send[temp1];
			send[temp1] = send[len - 1];
			send[len - 1] = temp2;
			len--;
		}
		return returnValue;
	}
	public static int[] random2() {
		int send[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
		int temp1, temp2, temp3;
		Random r = new Random();
		for (int i = 0; i < send.length; i++){// 随机交换send.length次
			temp1 = Math.abs(r.nextInt()) % (send.length - 1); // 随机产生一个位置
			temp2 = Math.abs(r.nextInt()) % (send.length - 1); // 随机产生另一个位置
			if (temp1 != temp2) {
				temp3 = send[temp1];
				send[temp1] = send[temp2];
				send[temp2] = temp3;
			}
		}
		return send;
	}
}

      到此,本应用实例的代码就完成了,赶紧体验一下吧。。。

eclipse 3.5在线汉化图解

2009年10月29日 IT北瓜 没有评论

      最近想学一下Google 网页工具包(Google Web Toolkit),于是装了eclipse3.5,由于本人E文实在有点对不起老师,还是中文界面看起来舒服。装完就赶紧把它给汉化了,虽然手动下载中文包汉化也很简单,但我还是喜欢在线升级的方式,这种方式方便日后升级。以下是在线汉化的过程图解:

      启动eclipse,依次打开Help——>Install New Software…,在弹出窗口中点击Add…按钮,填写如下对话框:

      说明:Name项可以随便填,Locations填写http://download.eclipse.org/technology/babel/update-site/galileo,点OK…按钮。耐心等待其自动检索…

      在检索出来的结果中选择如下图:

      点击Next…按钮,再一次耐心等待中…

      出现如下检索结果:

      再次点击Next…按钮,并接受相关协议说明,如下:

      点击Finish…按钮,接下来就是等待自动安装了,安装完毕询问是否重启eclipse,当然选择Yes…,重启之后就可以见到熟悉的中文界面了,舒服…