空山雪林通用模块工作室

 

2010年9月6日

高可用性服务端的设计与实现

本文的客户端基于我们的GQT开源项目:http://cxlh.iteye.com/blog/2021463

 

本人拙见,如有不同意见,欢迎拍砖,同时献给特别有对服务端跨语言需求的程序猿们!

客户端(GQT Demo V3(服务端配套版).rar)太大请挪步到QQ群下载(群号:101189702),注明:GQT或Java,C++等;

Java工程代码请挪步下载:http://cxlh.iteye.com/blog/2074307 


总体设计思路: 

 

  1. 高可用性:每个业务服务端都是独立的个体,任何一个业务服务器Crash时,都不会影响服务,并且业务服务器可以按需增加,业务服务端使用Java代码实现,主要是为了考虑更好的数据库操作,更好的事务支持,更好的社区支持以及可用更多的开源服务,提高开发效率;
  2. 自动负载均衡:当某个接口频繁调用,增加的响应服务器自动分流接口调用压力,也就说我们的异步的请求/响应模式下,有一个Broker仲裁程序决定客户端发来的请求交由哪个Java业务服务器来处理,这个Broker程序我们采用C++代码实现;
  3. 客户端(包括桌面或移动端)网关:根据策略选取远程Socket服务器连接,Socket服务器与服务器之间的消息通讯通过地址寻址远程路由,以便连在不同Socket服务器上的用户之间可以相互通讯,典型的应用就是聊天程序;
  4. Sub/Pub类消息:客户端订阅服务端的服务,服务端有多个Pub服务器(Java编写),交由Socket服务器将客户端Sub的消息Push给Client,此时Socket服务只作为Proxy用;

  好了,其实这里只有2个C++核心组件(Socket服务器,Broker仲裁程序)和N个Java业务服务器(请求处理服务器,Pub服务器),以下介绍用法(需要一定的客户端编程知识和一些脚本只是):

客户端发送请求,异步收取,编写业务代码步骤:

 

编写Java服务端,比如我们编写一个按关键字读取股票列表等接口(依赖注入用的Spring):

@Repository @CacheNamespace(implementation = org.mybatis.caches.ehcache.EhcacheCache.class, readWrite = true) public interface StockDao { 	@Select("select SYMBOL,SHORT_NAME from `master`") 	public List<Map> listStock(); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where SHORT_NAME like '%${k}%' or SPELL_NAME like '%${k}%' or SYMBOL like '%${k}%' limit 0,10") 	public List<Map> listStockByKeyword(Map<String,String> map); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where exch_id=8") 	public List<Map> listAllSh(Map<String,String> map); 	 	@Select("select SYMBOL,SHORT_NAME from `master` where trade_date=#dt#") 	public List<Map> listStockByDate(Map<String,String> map); }

编写Java服务就这么简单:

package com.gqt.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.gqt.server.BaseReqServer;
import com.gqt.server.ReqCallBack;

public class StockServer extends BaseReqServer {
    private static Logger logger = LogManager.getLogger(StockServer.class.getName());
    
    final static Properties prop = new Properties();
    static{
        InputStream is = null
        try {
            String c_path = StockServer.class.getResource("/").getPath();
            logger.info("c_path:{}",c_path);
            is = new FileInputStream(new File(c_path+"config.properties"));
            prop.load(is);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public StockServer(String ip, String port, ReqCallBack callback) {
        super(ip, port, callback);
    }
    public static void main(String[] args) {
        logger.info("=============StockServer========");
        new Thread(){
            @Override
            public void run() {
                ReqCallBack callback = new StockCallBack();
                String ip = prop.getProperty("gqt-reqserver-ip");
                String port = prop.getProperty("gqt-reqserver-port");
                final StockServer ss = new StockServer(ip,port,callback);
                ss.startServer();
            }
        }.start();
    }
}

编写客户端C++或脚本:

gw.req("命令代码"."命令代码对应的参数列表"); //回调函数 gw.s_cb_gw.connect(function(trcode,msg){ 	log("-----------------------------------------------------------------"); 	log("<p>gqt server异步方式获取数据,回调信息:trcode=" + trcode + ",msg=" + msg+"</p>"); });

 

效果如下:

 

 

 

 

这样做的好处:

 

  1. 桌面或移动的客户端再也不用编写繁琐的网络通信相关的程序,只需要发送请求/订阅,处理响应/订阅数据包即可,也不用关心底层的数据分包合包,客户端代理,网络传输的加解密和压缩等;
  2. 客户端开发人员也几乎不用和服务端程序员沟通,通过JSON解析请求透传给Java,Java响应的数据带上包头和响应给客户端,客户端解析JSON即可;
  3. 跨语言的服务端虽然会损失一定的性能,但似乎这点ZeroMQ已做的足够好;

 

Demo程序部署步骤:

 

  1. 创建一个MySQL Demo数据库,数据库名:stock,utf-8编码,导入output下的stock.sql;
  2. 配置output下的config.properties文件,指定机器IP,配置jdbc.properties,确保数据库配置正确;
  3. 点击runStockServer.bat,运行stock的Java Demo服务器,可以开任意个;
  4. 配置gqt-server-communicator(cpp)下的config_ims.ini文件,IP地址全部换成机器IP;
  5. 启动ss_server.exe,ss_zserver.exe;
  6. 点击客户端GQT程序,配置config_ims.ini中的IP地址,切换到gateway的标签页,enjoy it!


 

posted @ 2014-05-30 16:15 徐灵 阅读(1219) | 评论 (0)编辑 收藏

也谈基于Web的含工作流项目的一般开发流程

该项目包含的通用模块代码等我有时间一并剥离贡献出来(基于WebSocket的通知引擎,工作流整合模块,自定义表单(详见这里),基于RBAC权限设计),最近太忙了,Web项目有一段时间没碰,有点生疏的感觉,主要在忙GQT项目,一套基于桌面开发的框架,详见这里,写代码写的有点手酸的感觉。

 

基于Web的含工作流的项目看起来并不如想象的那么简单,主要需求:

  1. 灵活定制工作流,并跟踪流程进度;
  2. 每个Order含有历史轨迹记录,可在历史中查看;
  3. 工作流的Action灵活,认领任务不一定非要先提取表单,因为很多节点都只有几个动作,直接按钮操作即可;
  4. 待办事宜列表在不刷新页面情况下也能变动;

项目要求:

  1. 操作简单高效;
  2. 权限细节到按钮级别;
  3. 并发数少,不超过3000个在线用户;

主要可能使用到技术:

  1. 工作流引擎,我这里选用Activiti5,很灵活好用;
  2. 权限使用Spring Security,基于标签式管理权限很方便;
  3. 通知引擎使用WebSocket,基于Flash实时通信,基于socket.io;
  4. 权限粒度基于经典的RBAC;
  5. 总体框架Spring MVC+Mybatis;

实现的WebSocket的总体思路:

  1. WebSocket Server独立于Web项目,Web Server与WebSocket Server之间的局域网通信基于简单的Socket通信,这样这个组件可以完全解耦和通用;
  2. 当Web项目要Push消息到Client时,通过Web Server的Socket Client向WebSocket Server的Socker Server发送消息,然后WebSocket Server收到消息后解码,广播到所有浏览器;

我们实现的事件通知非常简单,设定全局变量并让浏览器侦听:

var G_WebSocket=false; 
var EVENT_ORDER_CHANGE_STATUS = "orderChange";
var EVENT_ORDER_CHANGE_AMOUNT = "amountChange";
var EVENT_ORDER_CHANGE_REFUND = "refundChange";
WebSocket.init = function(callbackFunc){
socket = io.connect(connUrl, connOptions);
socket.on('connect', function() {
G_WebSocket=true;
callbackFunc("connect",null);
});
socket.on('disconnect', function() {
G_WebSocket=false;
callbackFunc("disconnect",null);
});
socket.on('clientQuit', function(obj){
G_WebSocket=false;
callbackFunc("clientQuit",obj);
});
socket.on('broadcast', function(obj) {
callbackFunc("broadcast",obj);
});
};

 

在需要侦听WebSocket接受Web Server推送消息的地方加上一个函数即可:

	WebSocket.init(function(command,jsonObj){ 		
if(command=="broadcast"){
if(jsonObj.e == EVENT_ORDER_CHANGE_STATUS){
//TODO:write your code here
}else if(jsonObj.e == EVENT_ORDER_CHANGE_AMOUNT){
//TODO:write your code here
}else if(jsonObj.e == EVENT_ORDER_CHANGE_REFUND){
//TODO:write your code here
}
}
});

 这样的结构要扩展推送服务很简单,比如按频道推送等,都可以很容易的扩展。

再看看看工作流,我们实现了activiti通用的申请提交任务流程和自定义表单功能,提取跟踪流程图功能等,这样你要设计一个新流程也变得非常简单,只需要在eclipse里划上工作流图,在后台发布,然后通过SpringMVC的RestAPI启动实例流程,申领完成任务等,如下图:



 流程走到了分支的两个节点上,这样对后续新增的工作流提供了极大的遍历。

最后说说Spring Security,基于RBAC的权限体系搭建好后(可以用在任何管理系统中),要在页面中访问一个资源,首先判断一下是否有权限,如下HTML:

<sec:authorize ifAllGranted="r_pd"> 
<a href="#">resource access here</a>
</sec:authorize>

 

<sec:authorize url="/XXX/XXX/XXX.html"> 	
<a href="XXX/XXX/XXX.html'">
<span>XXX功能</span>
</a>
</sec:authorize>

  

前台由于项目比较小,没有用到js的MVC框架,如backbone等,这里就不再记录了。

 

 

posted @ 2014-03-20 12:48 徐灵 阅读(1659) | 评论 (6)编辑 收藏

Openfire 3.7.0提供的优秀开源在线客服系统

Openfire 3.7.0开始官方为我们提供了一套优秀的在线客服系统,你可以按如下步骤安装使用这套在线客服系统:
  1. 安装和部署Openfire 3.7.0
  2. 安装fastpath插件
  3. 从openfire的svn上下载webchat源码,webchat导入到eclipse中的工程如下图:
 
这套系统为我们提供了嵌入到客户端代码的源码,客户端只需要简单的嵌入如下代码,即可显示在线客服图标:<html>
<head>
<title>Fastpath Web Chat</title>
<script language="JavaScript" type="text/javascript" src="http://www.faqee.com:7080/webchat2/jivelive.jsp"></script>
</head>
<body>
<script>
      showChatButton('demo@workgroup.nb.faqee.com');
 
</script>
</body>
</html>
但点击在线客服图标时,如下图:

客服端使用Spark接受来自访客的请求的,点击Accept,如下图:


我们为您提供了9个客服账号,请用Spark登陆,嵌入的访客代码见博客,有兴趣的朋友可以测试一下:)
服务器填入:nb.faqee.com
客服账号:vms01/vms01,vms02/vms02,……,vms09/vms09
访客嵌入代码测试地址:
http://code.faqee.com/interface/fastpath.jsp

posted @ 2011-03-09 12:51 徐灵 阅读(8161) | 评论 (12)编辑 收藏

Flash开发开源工具推荐—FlashDevelop

偶玩的版本是3.3.1,简单而华丽的外表,界面截图如下:


 

安装FD,你首先需要安装:

  1. JDK 1.6以上版本
  2. .Net运行环境
继而你就可以一路Next完成安装了……

安装完成后,你必须去adobe官方网站下载开源的Flex SDK,我这边下载的版本是:flex_sdk_3.5.0.12683_mpl

下载完成后,解压到某个目录下即可,如:F:\flex_sdk_3.5.0.12683_mpl

然后在FD中设置Flex SDK,如下图:



 
我们这边以Open Flash Chart为例,导入项目工程,点击运行,如下图:



 
你可以设置断点,运行表达式,使用起来非常方便,强烈推荐给大家使用!


已有 1 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-10-12 08:43 徐灵 阅读(243) | 评论 (0)编辑 收藏

国庆度假小记

10月5,6日去宁波附近的度假村旅游了一下,一家3人出发了,由于儿子还比较小,怕他累着,所以这次就去了九龙湖开元名都大酒店度假村,5星级的酒店,住了一晚,有点小贵,协议价后也得880元一晚,不过是无敌湖景房,超大阳台,阳台上就可以看到整个九龙湖,甚是壮观,儿子玩的开心的不得了,在酒店的花园里滑滑板车,5日早上出发,6日中午回来,在回来的路上,顺便小逛了一下慈城古镇,到宁波吃了点饭,到家就该儿子的睡觉时间了……这个国庆节3日就简单的陪儿子在东钱湖上座了下船,他很喜欢坐船的……其实时间都在不知不觉中度过,国庆长假结束了……

 

PS:附上酒店小图一张,以之纪念……

 





已有 0 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-10-07 20:29 徐灵 阅读(113) | 评论 (0)编辑 收藏

利用Spring 3实现Rest配置与开发

最近项目要用到Rest,选择了Spring 3,关于Rest的介绍:

 

 

 REST关键原则
REST定义了应该如何正确地使用(这和大多数人的实际使用方式有很大不同)Web标准,例如HTTP和URI。如果你在设计应用程序时能坚持REST原则,那就预示着你将会得到一个使用了优质Web架构(这将让你受益)的系统。总之,五条关键原则列举如下:

  1. 为所有“事物”定义ID
  2. 将所有事物链接在一起
  3. 使用标准方法
  4. 资源多重表述
  5. 无状态通信

 

Spring 3.0开始将全面支持Rest,而且配置实现起来也相当简单,利用Spring MVC在web.xml定义片段:

 

 

	<servlet>  
        <servlet-name>mydemo</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
      
    <servlet-mapping>  
        <servlet-name>mydemo</servlet-name>  
        <url-pattern>/</url-pattern>  
    </servlet-mapping> 

 

继而在Web-INF目录下增加mydemo-servlet.xml,内容如下:

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<!-- Auto scan, declare the location path -->  
	<context:component-scan base-package="com.mydemo.springmvc.rest" />  

	<!-- Using annontation -->  
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 
	
	<!-- Resolve the view, declare the prefix and suffix -->  
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
		p:prefix="/view/" p:suffix=".jsp" p:viewClass="org.springframework.web.servlet.view.JstlView" />  
	 
	<bean id="multipartResolver"  
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver"  
		p:defaultEncoding="utf-8" /> 
</beans>

 

这里我们定义了JSP文件的标签库用jstl,并启动了注解功能,并自动扫描com.mydemo.springmvc.rest下的controller,接着我们就可以在com.mydemo.springmvc.rest包下编写controller代码

并可以使用注解功能,如类似的代码如下:

 

 

@Controller
public class MyDemoController {
	private CommonDAO commonDAO;
	@Autowired
	public void setCommonDAO(CommonDAO commonDAO) {
		this.commonDAO = commonDAO;
	}

	private MyDemoController (){}
	
	@RequestMapping(value="/home", method=RequestMethod.GET)
	public String welcome(){
		return "/home";
	}
}
 

然后就可以在view目录下通过增加home.jsp来实现显示层代码的编写工作,所有的步骤就以上这些,接下去你就可以通过类似:http://localhost:8080/mydemo/home,来访问了(这里Controller通过注解的方式注入DAO以便进行数据库的访问)



已有 0 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-09-28 13:19 徐灵 阅读(564) | 评论 (0)编辑 收藏

上海出差整整一周

最近一周都在上海出差,终于还是决定到新公司发展,希望能在新的环境有另一番作为吧

 

本周主要在上海探讨产品架构,以及针对需求的概要设计,将公司的新产品有概念转化为产品,虽然新公司是个刚起步的公

 

司,但作为产品还是相当有市场潜力的,而且目前国内做同类产品的相对很少,希望能做出点成绩,也作为而立之年的小小

 

考验,加油……



已有 0 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-09-16 08:46 徐灵 阅读(115) | 评论 (0)编辑 收藏

爱要大声说出来……

今天看到首页博客上看到“喜欢一个人的理由”博文,深有感触,特别是干我们这行的,往往都比较内向,也从来不向心仪的女孩表白占了多数,读工科的总是木讷些,当初的我也一样。


我也是其中一员,曾经心仪的高中女生,自我读大学后,我也跟她保持的书信来往,记得第一次写信地址还是通过校友录知道的,很快我们成为了“笔友”,相对来说,我和写那篇博文的作者差不多,自身条件并不怎么优越,170的身高,还要打个99折,她算是个“全优女生”,成绩好,长相也不错,所以我始终没有表白,也是怕最后连“笔友”也没得做,一直维持着大学结束,她读医的,所以比我多读一年,工作后,“笔友”变成了“话友”,短信IP电话时时骚扰,在大学期间,我还为她和我的经历虚构写成了一篇侦探小说,但我比写博客的作者幸运的是,我在最后的时刻还是表白了,她没马上答复我,一周后,她成为了我的女友,2年后,她成为了我的妻子……


爱要大声说出来,要不然就会连最后的希望都没有……男女单纯的友谊能维持多久呢……我想都是用来忽悠的吧,所以应该抓住每一次机会,爱要大声说出来……



已有 5 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-09-09 11:13 徐灵 阅读(204) | 评论 (1)编辑 收藏

JDBC操控Oracle XMLDB

现在XML数据库大行其道,特别在数据交换领域,由于XML数据库本身的特点,可以大显身手,那么JDBC如何来操作XMLDB呢,我们举几个简单的例子抛砖引玉一下吧

 

 

  • 在数据库中获取XMLType类型的列值,比如存储过程返回XmlType等,代码如下:
public static String getOracleXMlType2String(Object obj){
		try{
			if(obj instanceof OPAQUE){
				StringBuffer sb = new StringBuffer();
				OPAQUE op =(OPAQUE)obj; 
				if(op!=null){
					XMLType poxml = XMLType.createXML(op);
					if(poxml!=null){
						sb.append(poxml.getStringVal());
					}
				}
				return sb.toString();
			}
			return obj.toString();
		}catch(Exception ex){
			return null;
		}
	} 

执行存储过程代码:
 Object[] res = DbUtils.ExecuteSP("{call 存储过程名(?,?)}", new Object[]{
		new SpParameter(Types.VARCHAR, "IN", "in参数", "in参数值")
		,new SpParameter(OracleTypes.OPAQUE,"OUT","x",null)}, conn);
 

 

  • 可以通过XmlType列的clob值,代码如下:
select x.sys_nc_rowinfo$.getclobval() as column_value	from xmltypeTable
 
  • 执行存错过程(存储过程中含XmlTYPE返回值)
	public static final Object[] ExecuteSP(String stmt, Object[] inparams,
			Connection connection) {
		int i = 1;
		CallableStatement st = null;
		SpParameter sp = null;
		SpParameter outp = null;
		int DataType;
		String Direction;
		String Name;
		String DataValue;

		try {
			st = connection.prepareCall(stmt);

			int oupcount = 0;

			for (i = 0; i < inparams.length; i++) {
				if (inparams[i] instanceof SpParameter) {
					sp = (SpParameter) inparams[i];

					if (sp.GetDirection().toUpperCase().equals("IN")) {
						switch (sp.GetDataType()) {
						case Types.FLOAT:
						case Types.INTEGER:
							st
									.setLong(i + 1, Long.parseLong(sp
											.GetDataValue()));
							break;

						case Types.DATE:
							st.setDate(i + 1, java.sql.Date.valueOf(sp
									.GetDataValue()));
							break;
						case Types.SQLXML:
							st.setSQLXML(i + 1, null);
							break;
						default:
							st.setString(i + 1, sp.GetDataValue());
							break;
						}
					} else {
						if(sp.getDataType() == OracleTypes.OPAQUE){
							st.registerOutParameter (i+1, OracleTypes.OPAQUE,"SYS.XMLTYPE");
						}else
							st.registerOutParameter(i + 1, sp.GetDataType());
						oupcount = oupcount + 1;
					}
				} else
					st.setObject(i + 1, inparams[i]);
			}

			st.execute();
			i = 1;

			if (oupcount > 0) {
				Object[] outps = new Object[oupcount];
				int j = 0;
				for (i = 0; i < inparams.length; i++) {
					if (!(inparams[i] instanceof SpParameter))
						continue;

					sp = (SpParameter) inparams[i];

					if (!sp.GetDirection().toUpperCase().equals("IN")) {
						DataType = sp.GetDataType();
						Direction = sp.GetDirection();
						Name = sp.GetName();

						switch (DataType) {
						case Types.FLOAT:
							DataValue = String.valueOf(st.getLong(i + 1));
							break;

						case Types.INTEGER:
							DataValue = String.valueOf(st.getInt(i + 1));
							break;

						case Types.DATE:
							DataValue = st.getDate(i + 1).toString();
							break;

						case OracleTypes.OPAQUE:
							DataValue = getOracleXMlType2String(st.getObject(i+1));
							break;
						default:
							DataValue = st.getString(i + 1);
							break;
						}

						sp.setDataValue(DataValue);
						outps[j++] = DataValue;

						// res.addElement(new SpParameter(DataType, Direction,
						// Name,
						// DataValue));
					}
				}

				return outps;
			} else {
				return null;
			}
		} catch (SQLException ex) {
			
		} finally {
			if (st != null) {
				try {
					st.close();
				} catch (Exception ex) {
					log.error(ex);
				}

			}
		}
	}
 


已有 0 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-09-06 13:21 徐灵 阅读(281) | 评论 (0)编辑 收藏

成龙大哥,麻烦请不要以这种方式再高调做善事……

 

我很疑惑,作为知名的华人演员,在“咋捐门”出来后,还要写封信给北川同学,在信中还

 

在一个劲的解释“为什么还没捐”,而且还冠冕堂皇的不会给你任何承诺钱何时能到账,号

 

称原则问题,搞个“国家·爱”大型主题活动还在一个劲的重复着唱自己的歌“国家”,越看这

 

封信就觉得越变扭!


咱能不能也和中国首善陈光标一样,做善事可以高调,但不能再高调的背后炒作,宣传自

 

己商业产品或在当地搞投资啥的……这点偶很看好陈光标同志,瞻仰一下!

新闻引用 写道
亲爱的同学们:
你们好吗?!
虽然相隔遥远,但此时此刻,在我眼前浮现的是你们一张张纯真、质朴而可爱的脸庞。曾几何时,那场突如其来的足可诅咒的天灾,夺去了你们中的许多亲人,毁了你们的家园和校园。每每想起这些我就心痛,而你们在灾难中坚强挺立,奋发读书,又让我心生感动。你们不愧是龙的传人,是国家的骄傲!
令我感到无比欣慰的是,短短两年多时间,一个新的北川拔地而起,一座新的校园又飘荡起朗朗读书声。我从网上图片中看到,新北川中学很气派,很现代,很漂亮。我由衷地为你们感到高兴。这也再一次验证了天灾不可怕,心齐力量大。人间有情,大爱无疆!
同学们还记得去年5月我们在一起时的情景吗?那一天,不,准确地说是两天,全校同学放下功课,从临时校舍里赶到那片地震残留的废墟上,全情出演由我主导的“国家·爱”大型主题活动,以纪念地震一周年。那真是一个激动人心的场景:我和你们1000名同学,一起将重400公斤、面积5000平方米的巨幅国旗缓缓展开,此举打破了一项吉尼斯纪录大全。我们还一起放声歌唱《国家》,“国是我的国,家是我的家,我爱我的国,我爱我的家……”当时你们专注凝重的表情,还有不少同学眼眶噙满泪水,都深深印刻在我的心里。当天内地和香港许多媒体记者来到现场,竞相采访报道这一盛况,让爱传遍四方,让暖流溢满人间。
作为一名华人知名演员,我时刻牢记自己承担的一份社会责任,因此一直把慈善公益事业放在重要地位。此次在北川的主题活动,就是由我亲自构思设计,我相信此举一定能够引发全社会的共鸣,吸引更多人关注灾区的重建。而我深知光有这些是不够的,我还得为大家做点实实在在的事情。所以我当场做出一个重要决定并郑重宣布:将捐献我的新作《大兵小将》部分票房援建北川中学!同学们对我所做爱心承诺报以热烈的掌声,我还深深记得。
但是同学们,时间过去了一年多,新北川中学在政府等方面的努力下已经建起来了,而我的新片子也早已上市,我承诺的捐款却并没有到位,这是实情。近些天媒体纷纷指责我,甚至用上了“诈捐”这样难听的词汇。我当然很冤,当然是事出有因。我会是言而无信的人吗?我会是说大话使小钱或者干脆拿不出钱的人吗?我很气愤,很悲哀。对于个别媒体率先造谣的行为我将采取法律手段,维护自己的声誉和权益。
不过就此事我必须亲自向同学们做以解释,因为我不允许当初面对我做下承诺时你们那1000双热切期待的眼神中产生丝毫的疑虑,那样我将于心难安。其实我的主要解释已经通过我的助手向外界发布过了,我认为是完全合乎逻辑和情理的。第一,我发布捐款承诺时,《大兵小将》还没上映呢,而任何一部片子都有一个风险问题,票房是挣是赔不好说,如果票房赔了,我拿什么捐,是吧!所以我当时主要是表达一个奉献爱心的心情与希望,并没有说绝对会捐出多少数额,这个相信大家能够理解;第二,《大兵小将》最终票房卖了1.5亿多,是赚钱了,但是属于我的那部分分红我还没有拿到手,还需要一个过程,而这个过程有可能需要两三年,所以我当初承诺时也没有说具体的落实时间,其实就是考虑到了这个因素;第三,有居心不良者说我既然是答应捐款“重建”北川中学,而片子分红又没下来,就不可以从别的地方抽调资金先救建校之急吗?我说不可以。我们搞慈善不能太随意,必须实行专项封闭运行。我许诺捐出电影部分票房,那就一言厩出驷马难追,必须按这个办,不好中途更改的。并且我理解重建不单指盖学校,比如为学校重新建立校园安全系统,不也是重建吗?这样的钱年年都要花,所以我的捐款什么时间到位,与我的承诺没有必然联系。
好了,我也解释清楚了。总之请同学们放心,我成龙做了那么多慈善项目,跨国的都做了不少,动用金额成百上千万的难以计数,岂会在牵涉地震灾害的捐款活动中背信弃义,让人所不耻。所以我一定会兑现承诺,大家只要关心接下来的动作就可以了。不过如前所述,有些原则性的东西我还是要坚持,也就是此项捐款还得等我《大兵小将》的结算下来,所以还是需要一段时间。希望大家怀着美好的心情,慢慢等待。如果有提前毕业的同学看不到我兑现承诺的那一刻,也请永远记住我的一片爱心,我爱你们!
最后,让我们从头再唱一遍《国家》,我起头:“一玉口中国,一瓦顶成家,都说国很大,其实一个家……”
同学们加油!

 

 



已有 6 人发表留言,猛击->>这里<<-参与讨论


JavaEye推荐



posted @ 2010-09-06 08:20 徐灵 阅读(172) | 评论 (0)编辑 收藏

导航

友情链接

最新评论