在不能直面处直面,于不可承受中承受。越是命悬一线,越不轻言放弃。越是绝地生还,越拥有生命尊严。余震不断的大地,请停止再一次晃动,让那些死难的灵魂以安息,给等待救援的人以时间。那些担负救援任务的人们,请与死神争夺生命,与时间拼抢意念,比提前一秒更提前抵达,以百倍努力更加倍努力。那些掩埋于废墟之下的每一个微弱的呼吸与心跳,请你们一定要挺住,一定要坚信,一定要得救。我们希望在经过七十二小时之后,生命依然拥有迹象,拥抱依然拥有温暖,泪水依然拥有方向。
...
ubuntu
(2232 unread)
All things about ubuntu.
在不能直面处直面,于不可承受中承受。越是命悬一线,越不轻言放弃。越是绝地生还,越拥有生命尊严。余震不断的大地,请停止再一次晃动,让那些死难的灵魂以安息,给等待救援的人以时间。那些担负救援任务的人们,请与死神争夺生命,与时间拼抢意念,比提前一秒更提前抵达,以百倍努力更加倍努力。那些掩埋于废墟之下的每一个微弱的呼吸与心跳,请你们一定要挺住,一定要坚信,一定要得救。我们希望在经过七十二小时之后,生命依然拥有迹象,拥抱依然拥有温暖,泪水依然拥有方向。
...
最近在我们这里在进行办公网规范化管理,其中一个方案就是用ftp的方式来代理邮件分发文件的方式,上传数据采用ftp方式,而实际的分发下载直接通过Apache的目录索引来下载,这其中有一些比较特殊的文件,需要使用密码来保护,因为用户众多,这个密码需要给用户自己修改,所以就采用了mod_auth_mysql+mysql来实现目录的相关认证(之所有没有用auth_bdb,因为Ubuntu的auth_bdb模块默认没有携带mysql驱动)。下面是安装和配置方法...
最近在我们这里在进行办公网规范化管理,其中一个方案就是用ftp的方式来代理邮件分发文件的方式,上传数据采用ftp方式,而实际的分发下载直接通过Apache的目录索引来下载,这其中有一些比较特殊的文件,需要使用密码来保护,因为用户众多,这个密码需要给用户自己修改,所以就采用了mod_auth_mysql+mysql来实现目录的相关认证(之所有没有用auth_bdb,因为Ubuntu的auth_bdb模块默认没有携带mysql驱动)。下面是安装和配置方法:
1、先安装mod_auth_mysql模块:
[bash] sudo apt-get install libapache2-mod-auth-mysql
2、启用mod_auth_mysql模块:
[bash] cd /etc/apache2/mods-enabled sudo ln -s ../mods-available/auth_mysql.load
3、假设您有个/sec目录需要特殊权限控制,在Apache配置文件或者.htaccess中:
[bash]
#Auth_MySQL_Info 需要连接的Mysql服务器IP 用户名 密码
Auth_MySQL_Info localhost apache apache_2008
#如果所有的目录认证使用同一数据库:
Auth_MySQL_General_DB htpasswd
<Directory /sec>
Options Indexes FollowSymLinks MultiViews
AuthType Basic
#注意下面两行事关闭缺省的Basic认证,不然会报打开认证文件错:pcfg_openfile() called with NULL filename
AuthUserFile /dev/null
AuthBasicAuthoritative off
AuthName "Security Area"
AuthMYSQL on
AuthMySQL_Authoritative on
AuthMySQL_Password_Table user_info
AuthMySQL_Group_Table user_info
AuthMySQL_Empty_Passwords off
#这里使用了明文的密码方式,如果要使用MySQL password()的方式,请用AuthMySQL_Encryption_Types Plaintext
#不过在Ubuntu中的libapache2-mod-auth-mysql不是采用Plaintext方式,
#apache会直接stack smashing,详细的情况可以看:https://bugs.launchpad.net/ubuntu/+source/libapache-mod-auth-mysql/+bug/150649
AuthMySQL_Encryption_Types Plaintext
AuthType Basic
#允许组为sec的用户访问
require group sec
</Directory>
4、创建用于认证的用户表
[sql]
create table user_info(
username VARCHAR(20),
passwd VARCHAR(50),
groups VARCHAR(20),
primary key (username)
)ENGINE=MyISAM;
insert into user_info values('u1','pass','sec');
然后,您就可以直接维护这个表来管理用户了
详细的mod_auth_mysql的使用文档,请看这里
最近在Eclipse邮件列表讨论的火热的E4计划,大家不知道是否注意到?不清楚的朋友可以看这里的报道。这个咱不多说,作为一个Flexer我们关注另外一个东西:SWT Flex,这个的很显见,就是可以将SWT直接编译成FLEX SWF,也就是说以后基于SWT开发的eclipse RIA应用,可以直接将前台发布为Flash,当E4正式出炉的时候,这绝对会掀起一个巨大的波澜...
最近在Eclipse邮件列表讨论的火热的E4计划,大家不知道是否注意到?不清楚的朋友可以看这里的报道。今天看到Eclipse 放出来的一个DEMO,实在是够震撼的,估计下面这个将Eclipse WEB化是截图,已经够您消化一下了:

这个咱不多说,作为一个Flexer我们关注另外一个东西:SWT Flex,这个的很显见,就是可以将SWT直接编译成FLEX SWF,也就是说以后基于SWT开发的eclipse RIA应用,可以直接将前台发布为Flash,当E4正式出炉的时候,这绝对会掀起一个巨大的波澜!就等着看热闹了!
下面是一个典型的SWT HelloWord:
[java]
package org.eclipse.swt.e4.examples.helloworld;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.FillLayout;
public class SWTHelloWorld {
public SWTHelloWorld() {
// TODO - Initialize the Java runtime by referencing the System class.
// Note that line cannot be remove.
System.out.println("Start");
final Display display = new Display(new DeviceData());
Shell shell = new Shell(display);
shell.setText("SWT Shell");
shell.setLayout(new FillLayout());
Label label = new Label(shell, SWT.NONE);
label.setText("Hello World");
shell.open();
shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
display.dispose();
}
});
}
public static void main(String[] args) {
new SWTHelloWorld();
Display display = Display.getCurrent();
while (!display.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
}
}
其编译成FLEX输出后的SWF大家可以看这里
官方的Demo里面还有其他的一些示例,其中SWT组件与Flex控件直接的对应Demo也许您比较感兴趣。
另外,还有一个E4还支持将swt编译为dojo,这样您只需要使用SWT来编写您的应用,然后就可以作为一般的Java应用,又可以发布为RIA的flash应用,又可以发布为传统的Ajax的html应用,真TNND太强大了!别的解决方案还干什么吃呢?!不得不承认,这是一个非常吸引人的解决方案,相信真的发布的时候会有很多人转过去的,难道eclipse准备一统天下了?
最近Ubuntu 8.04修改了系统字体配置文件的构成,将原来的/etc/fonts/language-selector.conf分解成了四个文件,分别对应到/etc/fonts/conf.d/下的29-language-selector-zh.conf、69-language-selector-zh-cn.conf、99-language-selector-zh.conf和CJK_aliases,而我们经常修改的sans字体渲染顺序在69-language-selector-zh-cn.conf文件中...
最近Ubuntu 8.04修改了系统字体配置文件的构成,将原来的/etc/fonts/language-selector.conf分解成了四个文件,分别对应到/etc/fonts/conf.d/下的29-language-selector-zh.conf、69-language-selector-zh-cn.conf、99-language-selector-zh.conf和CJK_aliases,而我们经常修改的sans字体渲染顺序在69-language-selector-zh-cn.conf文件中,所以如果您发现系统字体显示不对,可以直接调整69-language-selector-zh-cn.conf,按照您喜欢的字体顺序调整好后,重启X后,系统的字体应该就恢复了。
但是这时候可能您的Flash里面的中文还是乱码或者和系统的字体不一致,这个的解决方法很简单,将/etc/fonts/conf.d/49-sansserif.conf删除即可,这个文件为在所有非sans-serif、serif字体中附加sans-serif,删除它后就Flash里面的字体配置就和外部系统的字体一致了。另外如果这样修改后还有乱码的话,试试调整下69-language-selector-zh-cn.conf里面的中文字体顺序。

今天看《世界历史》,今天说的是巴黎红色革命,片尾放的是国际歌,不小心就拨动了多年前的记忆,一下子抑制不住把唐朝的歌给全找出来疯狂的听了,我是从《国际歌》开始认识唐朝,从《梦回唐朝》开始痴迷上他们的,从《飞翔鸟》开始进入摇滚的《天堂》的...

今天看《世界历史》,今天说的是巴黎红色革命,片尾放的是国际歌,不小心就拨动了多年前的记忆,一下子抑制不住把唐朝的歌给全找出来疯狂的听了,我是从《国际歌》开始认识唐朝,从《梦回唐朝》开始痴迷上他们的,从《飞翔鸟》开始进入摇滚的《天堂》的,在《送别》中告别我的学生生涯, 今天一晚上听下来,至今还久久不能平静,相信很多朋友和我一样,提起唐朝,应该都有很多美好的回忆吧?!不过大家有听过唐朝唱的《明月千里寄相思》不?
也许这个夜晚,这个唐朝即将要出新专辑的时候,让我们在《月梦》里唱起《明月千里寄相思》。
夜色茫茫 罩四周天边新月如钩 回忆往事恍如梦 重寻梦境何处求 人隔千里路悠悠 未曾遥问星已稀 请明月带问候 思念的人儿泪常流 夜色朦朦 夜未尽周遭寂寞宁静 桌上寒灯光不明 伴我寂寞苦孤零 人隔千里无音讯 却待遥问终无凭 请明月代传信 寄我片纸儿慰离情 人隔千里路悠悠 未曾遥问星已稀 请明月带问候 思念的人儿泪常流
“再没有比工资更重要的问题了”,
“因为这个国家的大多数人都是靠工资生活的,他们生活水平的提高决定着这个国家的繁荣”。
“工资担负着工人在车间之外的全部负担,以及年老后他不能劳动时的生活。同时他也是一个有家庭的人,他也许是孩子们的父亲,他必须凭他挣的钱把孩子们培养成才。我们必须考虑到所有这些事实,让孩子们有衣可穿、有房可住,让他们受到教育,给他们生活的各种小享受”
可能很多人想象不到这些话会出自近百年前、老牌“民营企业家”美国福特汽车公司创始人福特先生之口。福特先生这些话现在读来仍然让人对他肃然起敬并富有意义!
摘录自三一重工总裁向文波先生的妙文:《没有比工资更重要的问题了》,一个有责任心的企业家的对国内的那些无良的企业家及为他们代言的无耻官员的最响亮耳光!推荐大家都拜读下。
mx.controls.Label组件有一个很有用的特性,那就是如果其要显示的文本长度大于组件的宽度时候,会自动截断文本,并在文本后面添加上...表示文本还有未显示部分,而且还会显示一个包括完整文本内容的ToolTip,所以将Label设置为DataGrid的Renderer,可将该特性用于在DataGrid里面截断过宽的Header文本或用于截断显示不下的单元格内容...
mx.controls.Label组件有一个很有用的特性,那就是如果其要显示的文本长度大于组件的宽度时候,会自动截断文本,并在文本后面添加上...表示文本还有未显示部分,而且还会显示一个包括完整文本内容的ToolTip,所以将Label设置为DataGrid的Renderer,可将该特性用于在DataGrid里面截断过宽的Header文本或用于截断显示不下的单元格内容,而当用户鼠标移到列上的时候不需要调整列宽,又可以通过Tooltip查看到单元格实际内容,是不是很方便啊?!
以下是个示例代码:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white">
<mx:XML id="xmlDP">
<nodes col1="root">
<node col1="mx.controls.Label:用于显示文本" col2="Label 组件" />
<node col1="mx.core.Application:mx应用核心" col2="核心组件" />
<node col1="测试" col2="测试" />
</nodes>
</mx:XML>
<mx:DataGrid id="dataGrid"
dataProvider="{xmlDP.node}"
width="250"
height="200">
<mx:columns>
<mx:DataGridColumn dataField="@col1"
headerText="Flex组件名称"
itemRenderer="mx.controls.Label"
headerRenderer="mx.controls.Label"/>
<mx:DataGridColumn dataField="@col2"
headerText="Flex组件详细说明,包括用法等"
itemRenderer="mx.controls.Label"
headerRenderer="mx.controls.Label" />
</mx:columns>
</mx:DataGrid>
</mx:Application>
刚刚在FlexCoder看到的消息,Flex SDK项目组正在想办法提高Flex4中的文本性能,所以他们想更多的了解我们是在Flex应用中是如何使用文本的,如果您不介意您的项目被分析的话,请帮助Flex项目组收集以下统计信息,具体步骤如下...
刚刚在FlexCoder看到的消息,Flex SDK项目组正在想办法提高Flex4中的文本性能,所以他们想更多的了解我们在Flex应用中是如何使用文本的,如果您不介意您的项目被分析的话,请帮助Flex项目组收集以下统计信息,具体步骤如下:
我相信更多的参与将会对Flex 4的文本处理性能的提高有极大的帮助,所以条件允许的话,请大家都参与下。
让我们一起期待Flex 4的盛装登场。
Flex3发布了,因为FlexBuilder for Linux并没有正式发布,对于我们这些在Linux平台下工作的人来说,就只有下载Flex 3 SDK了,有SDK其他也就没什么了,现在的FlexBuilder for Linux alpha 2还是用得挺顺手的,可是官方提供的SDK是不包括Data Visualization components的,这就是说Flex 3中的AdvancedDataGrid和图表相关的东西使用官方的Flex 3 SDK是不能使用的,不过还好FlexBuilder 3 Profession里面包含的SDK是完整的,里面有Data Visualization components,所以我们可以直接使用FlexBuilder 3 Profession中的SDK就可以了。当然也可以直接通过以下方法将Data Visualization component相关的文件拷贝到官方提供的SDK里面来增加Data Visualization component的支持...
Flex3发布了,因为FlexBuilder for Linux并没有正式发布,对于我们这些在Linux平台下工作的人来说,就只有下载Flex 3 SDK了,有SDK其他也就没什么了,现在的FlexBuilder for Linux alpha 2还是用得挺顺手的,可是官方提供的SDK是不包括Data Visualization components的,这就是说Flex 3中的AdvancedDataGrid和图表相关的东西使用官方的Flex 3 SDK是不能使用的,不过还好FlexBuilder 3 Profession里面包含的SDK是完整的,里面有Data Visualization components,所以我们可以直接使用FlexBuilder 3 Profession中的SDK就可以了。当然也可以直接通过以下方法将Data Visualization component相关的文件拷贝到官方提供的SDK里面来增加Data Visualization component的支持:
将FlexBuilder 3 Profession里面包含的SDK直接复制到官方SDK的对应目录就可以了:
大家要懒得为了这么几个文件,去下载400多M的FlexBuilder 3文件,大家可以直接点这里下载我从FlexBuilder 3 中剥离出来的文件。下载后直接解压到Flex 3 SDK安装目录即可,例如:
[bash] tar xzf flex3_dataVisualzationC.tar.gz -C /path/to/sdk3
另外,如果那个朋友使用compc编译lib的时候出现如下错误:
[bash] Locking assertion failure. Backtrace: #0 /usr/lib/libxcb-xlib.so.0 [0xb5364767] #1 /usr/lib/libxcb-xlib.so.0(xcb_xlib_unlock+0x31) [0xb53648b1] #2 /usr/lib/libX11.so.6(_XReply+0xfd) [0xb53b929d] #3 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0xb54bb8ce] #4 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0xb5498067] #5 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so [0xb5498318] #6 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/xawt/libmawt.so(Java_sun_awt_X11GraphicsEnvironment_initDisplay+0x2f) [0xb549861f] #7 [0xb5cf2e9d] #8 [0xb5cebedd] #9 [0xb5cebedd] #10 [0xb5ce9249] #11 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/client/libjvm.so [0x621c40d] #12 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/client/libjvm.so [0x6310378] #13 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/client/libjvm.so [0x621c2a0] #14 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/client/libjvm.so(JVM_DoPrivileged+0x363) [0x6272153] #15 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/libjava.so(Java_java_security_AccessController_doPrivileged__Ljava_security_PrivilegedAction_2+0x3d) [0xb7d0496d] #16 [0xb5cf2e9d] #17 [0xb5cebd77] #18 [0xb5ce9249] #19 /usr/lib/jvm/java-6-sun-1.6.0.04/jre/lib/i386/client/libjvm.so [0x621c40d] java: xcb_xlib.c:82: xcb_xlib_unlock: Assertion `c->xlib.lock' failed.
这是JRE的libxcb的link的一个Bug,大家可如下解决:
[bash] sudo sed -i 's/XINERAMA/FAKEEXTN/g' /usr/lib/jvm/java-6-sun/jre/lib/i386/xawt/libmawt.so
昨天激动人心的Flex 3终于发布了,因为Flex3的编译多了很多选项,其附带的Flex Ant Task也进行了更新,我们原来的Flex Ant Task增强版在Flex3上不能工作了,所以今天迁移代码的时候顺便把原来的增强版也做了相应的升级...
昨天激动人心的Flex 3终于发布了,因为Flex3的编译多了很多选项,其附带的Flex Ant Task也进行了更新,我们原来的Flex Ant Task增强版在Flex3上不能工作了,所以今天迁移代码的时候顺便把原来的增强版也做了相应的升级。
这个版本相对官方的版本就是在Mxmlc和Compc任务上增强了<token/>的支持,使用方法如下:
到这里下载Flex Ant Task增强版 For Flex3,下载后解压里面的flexTasks_feiy.jar到您的项目根目录,在Ant build.xml里面,如下定义taskDef:
[xml]
<taskdef resource="flexTasks.tasks" classpath="${basedir}/flexTasks_feiy.jar" />
然后在Mxmlc和Compc里面如下增强token:
[xml]
<token name="basedir" value="${basedir}"/>
另外Flex3编译需要更多的内存,所以如果使用Ant编译的时候,可能会出现如下错误:
[bash]
[exec] [mxmlc] Loading configuration file /home/feiy/workspace/Pumila_V2/flex-config-3.0.xml
[exec] [mxmlc] Error: Java heap space
[exec] [mxmlc]
[exec] [mxmlc] java.lang.OutOfMemoryError: Java heap space
这是因为mxmlc任务使用的内存操作的Ant缺省允许的最大值,可以使用先通过如下方法加大Ant最大使用内存:
[bash] export ANT_OPTS=-Xmx500M
然后再执行就可以了。
更详细的使用帮助,请查看这里
经过长时间的Beta后,Flex开源后的第一个版本Flex3正式发布了!
Flex 3已经来了,Flex 4还有多远:)
缺省事件处理器是用于在组件内部对某些事件进行缺省动作相应的,这在很多组件里面都是很普遍的,这样组件可以触发某些事件,缺省对该触发的事件进行处理,比如可关闭的窗口中,我们点击顶部X关闭按钮,TitleWindow内部的缺省关闭事件处理器对该事件进行响应,执行关闭当前窗口的操作。这样存在一种情况,有时候我们需要在关闭窗口前先提示用户将要关闭窗口,是否继续等类似的提示,如果用户确认需要关闭,那么就关闭,否则不关闭,对于后面的一种情况,我们需要避免缺省的事件处理器的执行,这样的情况,同样发生在我们自行开发的一些Flex组件中,所以今天我们来说说如何创建一个可被取消的缺省事件处理器...
缺省事件处理器是用于在组件内部对某些事件进行缺省动作相应的,这在很多组件里面都是很普遍的,这样组件可以触发某些事件,缺省对该触发的事件进行处理,比如可关闭的窗口中,我们点击顶部X关闭按钮,TitleWindow内部的缺省关闭事件处理器对该事件进行响应,执行关闭当前窗口的操作。这样存在一种情况,有时候我们需要在关闭窗口前先提示用户将要关闭窗口,是否继续等类似的提示,如果用户确认需要关闭,那么就关闭,否则不关闭,对于后面的一种情况,我们需要避免缺省的事件处理器的执行,这样的情况,同样发生在我们自行开发的一些Flex组件中,所以今天我们来说说如何创建一个可被取消的缺省事件处理器。
首先我们要在组件外部自己定义对事件的处理器,而且这个处理器要先于缺省的事件处理器执行,也就是说如果我们在组件内部的事件处理器的优先级要是低于外部的处理器的。对于我们组件外部的事件处理器来说,要有某些方法可以停止缺省的事件处理器的处理,具体的实现有四个步骤:
下面是演示代码,在组件的内部,我们定义了一个“alarm”事件,和一个该缺省的事件处理用于声告触发“alarm”事件:
[java]
package
{
import flash.events.Event;
import mx.controls.Alert;
import mx.core.EventPriority;
import mx.core.UIComponent;
[Event( name="alarm", type="flash.events.Event" )]
public class MyComponent extends UIComponent
{
public function MyComponent()
{
// 为"alarm"事件添加缺省事件监听. 这里的关键点为
// 该时间的优先级为:DEFAULT_HANDLER. 这是一个低优先级以使
// 得普通的事件监听可以先执行,使得用户可以通过调用
// event.preventDefault()来取消事件的缺省处理行为。
addEventListener( "alarm", handleAlarm, false, EventPriority.DEFAULT_HANDLER, true );
}
/***
* 一个简单方法,触发一个可被取消带缺省事件处理的事件。
*/
public function triggerAlarm():void
{
// 创建一个新的alarm事件。这里的关键点为构造函数的第三个参数,
// 该参数表示该事件可以通过event.preventDefault()来被取消。
dispatchEvent( new Event( "alarm", false, true ) );
}
/**
* "alarm"事件的缺省处理
*/
protected function handleAlarm( event:Event ):void
{
// 检测该事件是否被其他的事件监听屏蔽了缺省处理行为
if ( !event.isDefaultPrevented() )
{
// 事件没有被取消,所有继续缺省的事件处理
Alert.show( "MyComponent内部Alarm事件缺省处理,handleAlarm" );
}
}
} // end class
} // end package
下面是一个简单的测试代码,我们定义了一个alarm事件的监听,在其内部调用event.preventDefault()来取消该事件的缺省行为执行:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" xmlns:local="*">
<mx:Script>
<![CDATA[
protected function handleAlarm( event:Event ):void
{
// 为了演示意图,我们在界面上有一个标记,
// 用来表示我们是否要屏蔽缺省事件处理的执行
if ( preventToggle.selected )
{
trace( "Default behavior is prevented" );
event.preventDefault();
}
else
{
trace( "We didn't prevent the default behavior, so we'll see the alert from MyComponent." );
}
}
]]>
</mx:Script>
<mx:Button label="触发事件" click="myComp.triggerAlarm();" />
<mx:CheckBox id="preventToggle" label="禁止缺省行为?" selected="true" />
<local:MyComponent id="myComp" alarm="handleAlarm( event );" />
</mx:Application>
怎么样很简单吧,这是一个简单但是很有用的技巧,创建可被取消的缺省事件行为是Flex组件开发的一个重要部分,更详细的描述大家可以查看这里
在第一部分我们已经准备好了所有的后台代码,接着我们来进行Flex端的开发。首先,为了代码分离的考虑,我们将后台Django服务配置的设置单独存放在services-config.xml文件里面...
Flex端的编写
在第一部分我们已经准备好了所有的后台代码,接着我们来进行Flex端的开发。
首先,为了代码分离的考虑,我们将后台Django服务配置的设置单独存放在services-config.xml文件里面:
[xml]
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="ananasService" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="ananasAmf">
<channels>
<channel ref="ananasChannel"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="ananasChannel" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://127.0.0.1/ananas/gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
注意,其中<endpoint />里面的uri地址就是我们前面在Django的urls.py中定义的PyAMF网关访问URL地址一致。
下面是一个简单的Flex的测试代码:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="getAllDepartment()">
<mx:Script>
<![CDATA[
import mx.rpc.AsyncToken;
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
private function getAllDepartment():void{
var token:AsyncToken=djangoService.getAllDepartments();
token.addResponder(new AsyncResponder(AfterGetDeps,falutHandler));
}
[Bindable]
private var depAC:Array;
private function AfterGetDeps(result:Object, token:Object=null):void{
var evt:ResultEvent=result as ResultEvent;
depAC=evt.result as Array;
}
private function falutHandler(error:Object, token:Object=null):void{
var evt:FaultEvent=error as FaultEvent;
Alert.show(evt.message.toString());
}
[Bindable]
private var userAC:Array;
private function doQueryUser():void{
var token:AsyncToken=djangoService.getDepAllUsers(dep_cb.selectedItem.id);
token.addResponder(new AsyncResponder(AfterGetUsers,falutHandler));
}
private function AfterGetUsers(result:Object, token:Object=null):void{
var evt:ResultEvent=result as ResultEvent;
userAC=evt.result as Array;
}
]]>
</mx:Script>
<mx:RemoteObject
id="djangoService"
destination="ananasAmf"
showBusyCursor="true"/>
<mx:Panel title="用户管理">
<mx:DataGrid dataProvider="{userAC}">
<mx:columns>
<mx:DataGridColumn dataField="id" headerText="员工号" width="100"/>
<mx:DataGridColumn dataField="name" headerText="姓名" width="200"/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar>
<mx:ComboBox id="dep_cb" dataProvider="{depAC}" labelField="name"/>
<mx:Button label="查询" click="doQueryUser()"/>
</mx:ControlBar>
</mx:Panel>
</mx:Application>
注意其中,<RemoteObject/>的destination="ananasAmf"与我们前面的services-config.xml中定义的<destination id="ananasAmf">一致。
注意编译以上程序的时候,请使用“-services services-config.xml”参数加载Service配置。
以上是我们完整的演示了Django与Flex的完整交互过程,使用的全开源的技术手段,这样的开发方案对于用户来说,不需要购买任何额外的应用服务器,部署成本是及其低廉的,是不是很有吸引力,再而,因为都是开源的实现,碰任何难点您都可以深入源码的内部去寻求解决之道,真正可以做到随需而变。
PS:基于开源自由的精神,如果您对开源产品源码做了任何的有益的修改,请及时回馈社区!
最近应客户要求,一个面板需要可调整宽度,编码到是很简单,就是找不到合适的Resize的Cursor,所有就想想到DataGrid调整列宽度的时候不是会显示一个Resize光标吗,那么是不是可以和DataGrid用一样的Cursor呢,一查API,DataGrid里面用的是stretchCursor Style,而这个stretchCursor默认值是mx.skins.halo.DataGridStretchCursor,可是mx.skins.halo并没有这个所谓的DataGridStretchCursor,TNND,trace了下,竟然是[class _DataGridStyle__embed_css_Assets_swf_cursorStretch_1564262968]...
最近应客户要求,一个面板需要可调整宽度,编码到是很简单,就是找不到合适的Resize的Cursor,所有就想想到DataGrid调整列宽度的时候不是会显示一个Resize光标吗,那么是不是可以和DataGrid用一样的Cursor呢,一查API,DataGrid里面用的是stretchCursor Style,而这个stretchCursor默认值是mx.skins.halo.DataGridStretchCursor,可是mx.skins.halo并没有这个所谓的DataGridStretchCursor,TNND,trace了下,竟然是[class _DataGridStyle__embed_css_Assets_swf_cursorStretch_1564262968],而Flex框架里面的Default.css的定义又是:
[css]
DataGrid
{
stretchCursor: Embed(source="Assets.swf",symbol="cursorStretch");
}
看样子是官方的文档有问题了,不过,这倒没关系,不能直接应用,绕下就是了,通过DataGrid获取就是了,下面是获取并设置Cursor的代码:
[java]
import mx.managers.CursorManager;
import mx.managers.CursorManagerPriority;
import mx.controls.DataGrid;
...
var dg:DataGrid=new DataGrid();
this.addChild(dg);
stretchCursorClass = dg.getStyle("stretchCursor");
this.removeChild(dg);
CursorManager.setCursor(stretchCursorClass,CursorManagerPriority.HIGH);
只所有要先addChild又removeChild,是因为只有将DataGrid添加到Disaplay中才会实例化stretchCursor。
最近在着手下一个项目的准备工作,我之前的项目后台都是用Coldfusion的,Coldfusion的开发速度很快而且可靠,但是Coldfusion的价格太高了,无形会增加用户的部署成本,再而,现在做的项目除了后台部分都是搭建在开源自由的软件平台上的,如MySQL、Linux、Flex等,既然要切换后台,那更换的方向也是如此,本来想用Java的,可最近我发现自己有点缺少激情了(项目做多了、很多都在重复,没什么挑战性、没了新鲜感了,所有激情就欠奉了,要不是有五脏六腑需要祭奠,鬼才做这些商业项目呢)。最近社区讨论得最多的轻量的快速开发框架就是ROR和Django,ROR是好,可惜是源于日本鬼子的东西,我这人向来愤青,自然不选了,Django源于Python,Python有如此丰富的类库及其广泛的应用,而且即将迎来里程碑版本Python3000的发布,再加上我Python荒废多时正想重新拾掇起来,所有就选中了这个Django作为后台的框架。至于Flex与Django的通信,我用的PyAmf,之所以选用他,是因为这个支持Flex的RemoteObject...
最近在着手下一个项目的准备工作,我之前的项目后台都是用Coldfusion的,Coldfusion的开发速度很快而且可靠,但是Coldfusion的价格太高了,无形会增加用户的部署成本,再而,现在做的项目除了后台部分都是搭建在开源自由的软件平台上的,如MySQL、Linux、Flex等,既然要切换后台,那更换的方向也是如此,本来想用Java的,可最近我发现自己有点缺少激情了(项目做多了、很多都在重复,没什么挑战性、没了新鲜感了,所有激情就欠奉了,要不是有五脏六腑需要祭奠,鬼才做这些商业项目呢)。最近社区讨论得最多的轻量的快速开发框架就是ROR和Django,ROR是好,可惜是源于日本鬼子的东西,我这人向来愤青,自然不选了,Django源于Python,Python有如此丰富的类库及其广泛的应用,而且即将迎来里程碑版本Python3000的发布,再加上我Python荒废多时正想重新拾掇起来,所有就选中了这个Django作为后台的框架。至于Flex与Django的通信,我用的PyAmf,之所以选用他,是因为这个支持Flex的RemoteObject。
下面是项目的准备阶段手稿,基本来自于各项目的官方文档。
假定
本文基于Ubuntu Linux,开发环境已经安装Python、mod_python、subversion、apache、MySQL等环境。相关的安装大家可以参照各自的官方文档,这里给出Ubuntu下的安装方法(Python默认已经安装不需要安装):
[bash] sudo apt-get install apache2 libapache2-mod-python Subversion mysql-server mysql-client
另外,我们创建一个目录存放我们项目相关的文件:
[bash] mkdir -p ~/works/Ananas
后续我们将使用$work_root来指代该目录。
Django的安装及相关开发环境的搭建
Django目前才出于开发过程中,其API还在陆续完善中,其实作为实际产品的应用是有风险的,当前的版本是0.96,不过我用的是svn的开发版本,以便官方有更新能够快速更新。
首先,通过一下命令下载最新的Django代码(请确保您的系统已经安装Subversion):
[bash] cd $work_root mkdir -p server&& cd server svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
接着将Django加载到Python解析路径中:
[bash] sudo ln -s $work_root/server/django-trunk/django \ `python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`/django
接着将django-admin.py添加到系统路径中,以便后续使用方便
[bash] sudo ln -s $work_root/server/django-trunk/django/bin/django-admin.py /usr/local/bin
以后如果要更新Django,直接使用如下方法更新:
[bash] cd $work_root/server/django-trunk svn update
大家可以访问这里查看安装过程的官方说明。
创建Django工程
现在我们可以开始创建Django的工程了:
[bash] mkdir $work_root/server/src&&cd $work_root/server/src django-admin.py startproject ananas
以上我们首先创建了一个src目录,该目录为你的Django工程根目录,接着创建一个项目ananas,初始的结构如下:
[bash]
ananas/
__init__.py
manage.py
settings.py
urls.py
其中,manage.py是工程管理工具,settings.py则是项目的相关参数设置,而urls.py则是Django的url解析表
接着我们就可以启动Django 开发服务器了:
[bash] cd $work_root/server/src/ananas python manage.py runserver
以上命令会启用一个Django内置的用python实现的轻量web Server,考虑到我们最终要部署到Apache上,及分布开发的情况,我们这里不使用这个方法,而是使用下面Apache+mod_python的方式。
Django的mod_python配置
首先,激活Apache的mod_python模块:
[bash] sudo a2enmod mod_python
接着,修改apache配置文件,在集中添加Django相关的配置:
[bash] sudo vi /etc/apache2/sites-enabled/000-default
添加在</VirtualHost>前添加如下内容:
[bash]
<Location "/ananas/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE ananas.settings
PythonDebug On
PythonPath "['/path/to/project'] + sys.path"
</Location>
其中,/path/to/project要替换成您的项目根目录,也就是$work_root/server/src/,在本文中实际的配置应该是:
[bash]
<Location "/ananas/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE ananas.settings
PythonDebug On
PythonPath "['/home/feiy/works/Ananas/server/src'] + sys.path"
</Location>
以上配置表示,对于/ananas的访问,使用django.core.handlers.modpython来处理,其中的PythonDebug On,打开调试功能,方便我们开发过程的程序调试,实际生产上需要关闭它。
另外,在末尾添加如下内容:
[bash] MaxRequestsPerChild 1
该配置强制Apache对于每个请求都重新载入配置,以便我们的Python代码更新后,不需要重启Apache。该配置对Apache性能有影响,实际生产上需要删除它。
接着,启动apache:
[bash] sudo /etc/init.d/apache2 start
如果您配置正常的话,这时候访问[127.0.0.1],将会看到如下画面:

该部分官方的详细说明可以查看这里
配置Django数据库访问
接着我们来配置Django连接MySQL,编辑settings.py文件,修改其中的如下选项:
[python] DATABASE_ENGINE = '' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. DATABASE_NAME = '' # Or path to database file if using sqlite3. DATABASE_USER = '' # Not used with sqlite3. DATABASE_PASSWORD = '' # Not used with sqlite3. DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
文件里面已经说的很清楚了 ,这个分别对应你要使用什么类型数据库服务器、要连接的数据库名、用户名、密码、数据库服务器主机地址、端口。分别安装您的实际数据库连接情况设置好就可以了。
接着修改INSTALLED_APPS部分:
[python]
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
)
这个部分表示在我们的Django实例中激活了那些应用,一个应用可以用于多个工程,默认的四个应用,分别对应是认证系统、内容识别、session框架和一个但Django对应多个站点的框架。
您可以根据需要添加或删除应用,比如我们这里不需要认证系统,那么直接将其修改如下:
[python]
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
)
接着,执行如下命令,为这些应用创建必要的表结构等:
[bash] python manage.py syncdb
创建我们自己的应用
现在,我们已经搭建好了Django开发环境——创建了一个工程ananas,现在我们来创建我们实际的应用。
使用如下命令创建一个应用:
[bash] python manage.py startapp users
以上将在当前目录创建一个users目录,其内容如下:
[bash]
users/
__init__.py
models.py
views.py
其中,models.py用于定义我们的数据库模型,将其修改如下:
[python]
from django.db import models
class Department(models.Model):
name = models.CharField(max_length=80)
def __unicode__(self):
return self.name
class User(models.Model):
id=models.CharField(max_length=8,primary_key=True)
name = models.CharField(max_length=40)
dep = models.ForeignKey(Department)
def __unicode__(self):
return self.name
以上定义了两个表,一个是部门表、一个用户表,用户表的dep字段是指向Department的外键。关于Django里面model的定义说明请查看这里
接着在settings.py中激活我们的users应用(应用名称为:ananas.users),将其中的INSTALLED_APPS修改如下:
[python]
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'ananas.users',
)
返回到工程根目录,执行以下命令,自动创建表结构:
python manage.py syncdb
以上会自动创建两个表:users_department和users_users。
初始数据的写入
现在我们可以利用Django提供的API来方便的写入我们的一些初始数据。
运行以下命令,进入交互的Python Shell:
[bash] python manage.py shell
接着输入如下命令:
[python] #导入我们前面定义的model类 >>> from ananas.users.models import Department,User #创建两个部门 >>> dep1=Department(name='前台接待部门') >>> dep1.save() >>> dep2=Department(name='资信调查部门') >>> dep2.save() #验证是否创建成功 >>> Department.objects.all() [<Department: 前台接待部门>, <Department: 资信调查部门>] #创建三个用户,分别对应两个部门 #获取部门一 >>> dep1=Department.objects.get(name='前台接待部门') #当前该部门没有任何用户 >>> dep1.user_set.all() [] >>> dep1.user_set.create(id='0001',name='feiy') <User: feiy> >>> dep1.user_set.create(id='0002',name='feng') <User: feng> >>> dep1.user_set.all() #验证是否创建成功 [<User: feiy>, <User: feng>] #获取部门二 >>> dep2=Department.objects.get(name='资信调查部门') #当前该部门没有任何用户 >>> dep2.user_set.all() [] >>> dep2.user_set.create(id='0003',name='eshangrao') <User: eshangrao> #验证是否创建成功 >>> User.objects.all() [<User: feiy>, <User: eshangrao>, <User: feng>]
怎么样,Django里面数据访问很方便吧,更多的Django API信息请查看这里
搭建Flex和Django的桥梁:PyAmf的安装
以上我们已经准备好了后台环境,创建了初始的数据,那么我们的Flex程序如何与Django交互呢,答案是PyAmf,这个是Python的Amf实现,通过他,Flex就可以使用Amf的方式和Python程序交互。值得一提的是,这个支持Amf3。
PyAmf目前的稳定版本是0.1,和前面安装Django一样的考虑,我们也安装svn的开发版本
[bash] cd $work_root/server svn co http://svn.pyamf.org/pyamf/trunk pyamf-trunk cd pyamf-trunk sudo python setup.py develop
接着在我们的Django工程目录下创建一个amfgateway.py文件,内容如下:
[bash]
from pyamf.remoting.gateway.django import DjangoGateway
from ananas.users.models import Department,User
def getAllDepartments(request):
return Department.objects.all()
def getDepAllUsers(request,depID):
dep=Department.objects.get(id=depID)
return dep.user_set.all()
def updateUser(request,userID,userName,depID):
user=User.objects.get(id=userID)
user.name=userName
user.depID=depID
usersGateway = DjangoGateway({
'getDepAllUsers': getDepAllUsers,
'getAllDepartments':getAllDepartments,
'updateUser':updateUser
})
以上定义了一个userGateway Amf网关,提供了三个分别获取所有部门、用户和更新用户信息的方法。
接着打开$work_root/server/src/ananas/urls.py,定义AMF网关的访问URL,用于Flex端访问。
[python]
from django.conf.urls.defaults import *
urlpatterns = patterns('',
# Example:
# (r'^ananas/', include('ananas.foo.urls')),
# Uncomment this for admin:
# (r'^admin/', include('django.contrib.admin.urls')),
(r'^ananas/gateway/', 'ananas.amfgateway.usersGateway'),
)
以上定义对/ananas/gateway的访问,使用usersGateway进行处理。(注意,这个urls.py是Django里面的最经典的东西,这样可以使用正则表达式,定义非常灵活的URL处理)
未完,待续...
自从上次接到公安局网监支队的电话后,我已经尽量不在这里谈论实事,不议国事了,可是有些话如鲠在喉、不吐不快。 这个春节,去女朋友老家拜年,春运汽车调价(TNND,以前叫春运涨价,现在伟大的。。说春运不涨价,所有人家现在叫调价了),本拉70的现在100了,这也倒没什么,上了车,一路拉,好家伙,超载不算,我车站的票价100,可路上上来的旅客却要210,爱坐不坐,更过分的是竟然正在吃奶的小孩也要买票,据说是因为他是超载,如果被抓了,核定超载是按人头计算的?!都当乘客是傻的...
自从上次接到公安局网监支队的电话后,我已经尽量不在这里谈论实事,不议国事了,可是有些话如鲠在喉、不吐不快。 这个春节,去女朋友老家拜年,春运汽车调价(TNND,以前叫春运涨价,现在伟大的。。说春运不涨价,所有人家现在叫调价了),本拉70的现在100了,这也倒没什么,上了车,一路拉,好家伙,超载不算,我车站的票价100,可路上上来的旅客却要210,爱坐不坐,更过分的是竟然正在吃奶的小孩也要买票,据说是因为他是超载,如果被抓了,核定超载是按人头计算的?!都当乘客是傻的!
这那里是买票啊,简直就是抢劫啊!是什么造成这样的局面的呢?!我想这和现行的所谓道路专营制度有关,所谓专营就是,某一条线路的运营是由某个公司向相关管理部门按每年多少钱买断,所谓线路运营费,然后这条线路就是该公司独家运营了,别的公司是不能在这个线路上营运的,然后这些所谓的公司再贿赂我们所谓的物价部门,批准一个价格浮动范围很大的所谓核定票价(这个范围有多荒唐,只有我们伟大的物价部门才能核定得出来),然后一个合法的垄断就出现了,既然是垄断,那么要收多少票价就是他说了算了,爱坐不坐,那么基本上就是之前的车匪路霸向。。买下路,然后就可以合理的抢劫了!
就说那么多,大过年的,这不和谐的声音也许该给和谐掉...