Posted by bianbian on 2008-04-25 09:16
本文Tags: IoC, Java, Spring
这几天做了一个东西:在DAO上往数据库插入一个bean的时候,用java反射机制自动产生SQL语句,同时publishEvent触发bean更新事件,事件监听类根据配置文件处理bean并自动提交到Lucene(Solr)全文检索(主要是bean的属性跟Solr字段的对应)进行准实时的索引更新(当然bean有缓冲);反过来,检索结果有望自动转成bean丢给用户callback。
danny这个巨牛完成的基于spring的再次开发框架除了自动controller Action绑定、ResultSet自动转成bean、自动分页、自动View视图等等快捷开发功能外(Orz),现在支持自动全文检索了,而且整个过程对其他开发人员是无缝过渡的,建立全文索引不需要修改任何一处代码(其实概念上用AOP比事件监听更适合:“可热插拔”的全文检索切面,但是事件监听最大的优势是异步的,全文检索准实时索引更新这种需求用AOP同步包装一层实在是太不实际了):只要在配置文件里指定哪些数据表的bean哪些字段需要全文检索,OK。。。添加或者全记录更新的时候索引都会准实时更新——而且几乎近似热插拔。
标签:
IoC,
Java,
Spring遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Java, Technology | 1 Comment »
Posted by bianbian on 2008-04-20 03:43
本文Tags: JavaScript, 正则表达式, 解决
发信人: Net (BBS上没有什么事情是bg不能解决的), 信区: WebDesign
标 题: Re: 如何使用正则分别替换?
发信站: 南京大学小百合站 (Sun Apr 20 15:21:23 2008)
不太可能一句话搞定,不过有相对而言的解决办法:
1) 简单易懂
- function arrayReplace(str, from, to) {
- for(var i=0; i < from.length; i++)
- str = str.replace(new RegExp(from[i], "g"), to[i]);
- return str;
- }
- var from = ["A", "B", "C"], to = ["asdf", "fdsa", "......"];
- str = arrayReplace(str, from, to);
2) 勉强算一句话吧。。。
- str = str.replace(/(A|B|C)/g, function ($0, $1) {
- return {"A": "asdf", "B": "fdsa", "C": "......"}[$1]
- });
【 在 superphoenix (格云朱雀) 的大作中提到: 】
: 比如要将一个字符串中的A替换为asdf,B替换成fdsa,C替换成……
: 能不能用一个正则话就替换成功?
: 而不是写成str=str.replace(/A/g,”asdf”).replace(/B/g,”fdsa”)….
: 谢谢!
※ 来源:.南京大学小百合站 bbs.nju.edu.cn.[FROM: Net.nEt.neT.Orz]
标签:
JavaScript,
正则表达式,
解决遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | 1 Comment »
Posted by bianbian on 2008-04-20 01:08
本文Tags: binary, bug, pack, php, struct, unpack, 二进制, 数据, 解决
尽管php是用C语言开发的,不过令我不解的是php没有提供对结构体struct的直接支持。
不过php提供了pack和unpack函数,用来进行二进制数据(binary data)和php内部数据的互转:
- string pack ( string $format [, mixed $args [, mixed $...]] )
- //Pack given arguments into binary string according to format.
-
- array unpack ( string $format, string $data )
- //Unpacks from a binary string into an array according to the given format.
其中,$format跟perl里的pack格式类似,有如下一些(中文是我加的,有不准确的欢迎提出):
a NUL-padded string,即“\0”作为“空字符”的表示形式
A SPACE-padded string,空格作为“空字符”的表示形式
h Hex string, low nibble first,升序位顺序
H Hex string, high nibble first,降序位顺序
c signed char,有符号单字节
C unsigned char,无符号单字节
s signed short (always 16 bit, machine byte order)
S unsigned short (always 16 bit, machine byte order)
n unsigned short (always 16 bit, big endian byte order)
v unsigned short (always 16 bit, little endian byte order)
i signed integer (machine dependent size and byte order)
I unsigned integer (machine dependent size and byte order)
l signed long (always 32 bit, machine byte order)
L unsigned long (always 32 bit, machine byte order)
N unsigned long (always 32 bit, big endian byte order)
V unsigned long (always 32 bit, little endian byte order)
f float (machine dependent size and representation)
d double (machine dependent size and representation)
x NUL byte,实际使用的时候作为跳过多少字节用,很有用
X Back up one byte,后退1字节
@ NUL-fill to absolute position,实际使用的时候作为从开头跳到某字节用,很有用
实际使用发现:C里的“\0”(即字符串终止符)在php里并不是终止符,而是作为了字符串的一部分。因此,必须对“\0”进行特殊处理,才能进行struct和php内部数据的完美互转。比如 char name[10]; 如果实际数据是“62 69 61 6E 00 62 69 61 6E 00”,在C语言里第5个位置有终止符,name应该是“bian”;而用了unpack转换以后在php里的name却是“bian\0bian\0”。
一开始我用了strpos函数找到“\0”的位置,然后进行substr截取:
- $name = substr($name, 0, strpos($name, "\0"));
不过很Faint的事情发生了,不知道是strpos的bug还是substr的bug(其实测试一下就知道,懒得试),有些字符串没问题,有些字符串却只能得到空值(即$name == ”)。很是郁闷,后来找了个strtok函数,这下没有问题了:
- $name = strtok($name, "\0");
难为大家看了那么多,下面写个完整的php读取二进制数据流(C语言结构体struct数据)文件的示例代码:
首先是C的struct定义示例,为了演示,我就写个简单点的,实际对照上面那个$format格式表应该没有问题:
- struct BIANBIAN {
- char name[10];
- char pass[33];
- int age;
- unsigned char flag;
- };
比如有个“bianbian.org”文件,内容就是上面的N个BIANBIAN结构体构成的。读取的php代码:
- //下面根据struct确定$format,注意int类型跟机器环境有关,我的32位Linux是4个长度
- $format = 'a10name/a33pass/iage/Cflag';
- //确定一个struct占用多少长度字节,如果只是读取单个结构体这是不需要的
- $length = 10 + 33 + 4 + 1;
- //也可以用fopen + fread + fclose,不过file_get_contents因为可以mmap,效率更高
- $data = file_get_contents('bianbian.org', 'r');
- for ($i = 0, $c = strlen($data); $i < $c; $i += $length) {
- $bianbian = unpack("@$i/$format", $data);
- //reference传递是php 5才支持的,如果用php4,得用其他办法
- foreach ($bianbian as &$value) {
- if (is_string($value)) {
- $value = strtok($value, "\0");
- }
- }
- print_r($bianbian);
- }
- //输出为array,即类似:
- Array
- (
- [name] => 'bianbian'
- [pass] => 'bianbian.org'
- [age] => 100
- [flag] => 0
- )
- ...
pack应该跟unpack相反。
标签:
binary,
bug,
pack,
php,
struct,
unpack,
二进制,
数据,
解决遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Technology, php | 4 Comments »
Posted by bianbian on 2008-04-15 11:08
本文Tags: FTP, ftp4j, FTPClient
ftp4j是个很年轻的开源项目,但是试用后发现很好很强大,如果你找一个纯java的FTP库,要支持socks4,socks4a,socks5,http代理,就是他了!
比apache的FTPClient(不支持代理)、半商业的edtFTPj(PRO支持代理,但是要$,而且是系统变量级的代理,不能单个指定)等好用多了,而且是LGPL协议,源码质量很高。(不过如果你需要FTPS及SFTP,那ftp4j不支持)
jar包只有50多k,地址在这里:ftp4j
使用代理的代码:
- import java.util.ArrayList;
- import it.sauronsoftware.ftp4j.FTPClient;
- import it.sauronsoftware.ftp4j.FTPFile;
- import it.sauronsoftware.ftp4j.connectors.SOCKS4Connector;
- ......
- //ftp4j使用socks4代理连接FTP示例,by http://bianbian.org
- FTPClient ftp = new FTPClient();
- SOCKS4Connector socks4 = new SOCKS4Connector("127.0.0.1", 1080);
- ftp.setConnector(socks4);
- ftp.connect("an.ip.or.host", 21);
- ftp.login("anonymous", "bianbian@bianbian.org");
- ftp.setCharset("gbk");
- //list files
- FTPFile[] list = ftp.list();
- for(FTPFile file : list) {
- System.out.println(file);
- }
- ftp.disconnect(true);
标签:
FTP,
ftp4j,
FTPClient遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Java, Technology | 2 Comments »
Posted by bianbian on 2008-04-09 09:16
本文Tags: php, UTF-8, 乱码, 解决
php 5的流读取函数好像默认编码是UTF-8,以前在php 4里直接file_get_contents()读取gb2312编码的正常,到了5就乱码了。网上的解决办法说抓取后用iconv()转码。看后我就觉得不对劲:一个是不一定编译了iconv库,更大的问题是编码都跟流转换的时候有关(如果用了iconv实际上php转了两次码:流 -> UTF-8 -> GB2312):这不是白忙乎了吗?
仔细看了下php的文档(不知道大家都是怎么写代码的,其实文档上很清楚啊),上面关于fopen()及file_get_contents()都提到了“默认是UTF-8,但是用户可以用stream_default_encoding()或者用户自定义上下文属性改变编码”(If unicode semantics are enabled, the default encoding of the read data is UTF-8. You can specify a different encoding by creating a custom context or by changing the default using stream_default_encoding().)。于是用stream_default_encoding(’gb2312′);测试:但是faint的是,这个函数不存在?!似乎php 6才支持。不过天无绝人之路,还有“用户自定义上下文属性”可以用。
经过更仔细的看文档,最后解决了这个问题:
- //设置流的编码格式,这是文件流(file),如果是网络访问,file改成http
- $opts = array('file' => array('encoding' => 'gb2312'));
- $ctxt = stream_context_create($opts);
- file_get_contents(文件名, FILE_TEXT, $ctxt);
标签:
php,
UTF-8,
乱码,
解决遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Technology, php | No Comments »
Posted by bianbian on 2008-04-09 11:13
本文Tags: JSON, struct
上次讨论了C的struct结构体与JSON交互,并提出了能否自动把struct转为JSON的问题。
今天我总算解决了这个问题,虽然中间也想过传参数给一个函数集中处理,不过都是比较麻烦。我写了一个脚本,自动生成把struct的成员插入json_object的函数,底下页面有演示:auto generate function of C struct to JSON:
标签:
JSON,
struct遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C/C++, Technology | 4 Comments »
Posted by bianbian on 2008-04-07 01:28
本文Tags: BBS, Firefox, IE, JavaScript, 脚本
最近发现个别网友访问小百合BBS会出现如下提示:
见到此文字可能是由于浏览器禁用了活动脚本或者脚本有误
请启用脚本支持后刷新本页;若仍有问题,请点击这里提问
原理:使用Javascript动态输出框架结构(好处是能缓存静态化网页,区别guest用户和登录用户)。因此,一旦这步出现错误,框架结构未建立成功,那么就会显示body里的提示内容。
原因:
(1)浏览器版本不支持。目前小百合BBS支持IE5.5(不保证全部功能有效),完美支持IE6+、Firefox 2.0+、Opera 9+等。如果您的浏览器不在此列,并且测试正常,欢迎反馈。
(2)浏览器脚本引擎未启用。您可以点击这里测试:如果能弹出“脚本启用”,那说明这项没有问题;否则,请修改设置如下:
Firefox:
IE:
(3)脚本有误。可能性不是很大,除非刚好碰到更新的脚本确实存在错误。基本上我都会测试以后才放上去。不过万一你怀疑是这个问题,可以telnet方式到sysop版看看,如果其他人都没问题那基本就只是您的问题了。
(4)浏览器缓存内的脚本版本过旧。因为浏览器缓存脚本文件(这样不需要每次都下载,加快速度),如果服务器端已经更新了脚本文件,而您的浏览器缓存因为各种原因没有更新,可能也会导致这个问题。请清空浏览器缓存后刷新测试:
Firefox:
IE:
(5)校内用户访问BBS请关闭代理服务器。
(6)浏览器或系统部分DLL(动态链接库)功能因为病毒或木马的原因失效(Windows系统),请点此下载修复程序,保存后运行,然后重新打开浏览器测试。
如果还有问题,请留言将您的操作系统、浏览器(基本是IE出问题)及版本、杀毒软件等告知。另外推荐使用Firefox:
标签:
BBS,
Firefox,
IE,
JavaScript,
脚本遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | 36 Comments »
Posted by bianbian on 2008-04-06 04:01
本文Tags: BBS, memcached, 优化
尤其是点击率,是网站静态化最麻烦的地方之一:每个用户的每次点击都会改写.DIR文件,也是负担
而且除了看一眼没有其他用处,而且没有办法保证不作弊(blog点击率作弊尤其多)
我想了个办法:tmpfs+数据库(比如MySQL)
1)把所有点击率以日志的形式记录到tmpfs(ramdisk)某文件log.tmp(点一次存一行)
格式:bbs BoardName FileName UserId IP
blog BlogUserId FileName UserId IP
an Path UserId IP
因为是内存操作,非常快
2)10分钟crontab把log.tmp改名log.10,然后另外启动程序分析log.10
去除UserId和IP相同的重复记录(10分钟内同ip同id重复点击只算一次)
把结果一次insert到MySQL,因为是multi insert,即使log很大,其实是非常快的
3)进入数据库以后就好办了,可以出各种统计:
1小时内热门,12小时内热门,24小时内热门,本周热门。。。。。。
这块统计(数据挖掘)其实是目前基于文件系统的BBS最缺的地方,自己写会很辛苦
这块结果输出可以用memcached优化,10分钟从数据库跑一次SQL即可
这样.DIR就不需要改变,而且可以把.DIR部分cache到内存里,结合libevent,有数据改写reload一次
唯一的缺点是显示的时候要从数据库内取,必须memcached,而且10分钟才会更新一次
不过比起带来的好处来看,是微不足道的
针对其他日志的数据挖掘:除了能出各种统计图表外,对于遍历试密码的可以直接从iptables过滤
我准备等我忙完毕业的事情好好实现一下。
标签:
BBS,
memcached,
优化遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Technology | No Comments »
Posted by bianbian on 2008-04-06 01:36
本文Tags: AJAX, Firefox, JavaScript, XMLHttpRequest, 二进制, 数据
译者注:原来想用JS直接处理C丢过来的struct数据,具体可以查看:[原] C的struct和JSON交互。
经过千辛万苦的查找,找到了这篇文章(作者应该比我更辛苦):Downloading Binary Streams with Javascript XMLHttpRequest
把关键点翻译如下(不过我还没有测试):
利用XMLHttpRequest的overrideMimeType方法设置charset为x-user-defined。
- //fetches BINARY FILES synchronously using XMLHttpRequest
- load_url = function(url) {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
- var req = new XMLHttpRequest();
- req.open('GET',url,false);
- //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
- req.overrideMimeType('text/plain; charset=x-user-defined');
- req.send(null);
- if (req.status != 200) return '';
- return req.responseText;
- }
-
- var filestream = load_url(url);
- var abyte = filestream.charCodeAt(x) & 0xff;
IE不支持overrideMimeType方法,不过有评论者说VBScript可以实现:
- Dim xhr
- Set xhr = CreateObject("Microsoft.XMLHTTP")
- xhr.Open "GET", "folder.bin", False
- xhr.setRequestHeader "Accept-Charset", "x-user-defined"
- xhr.setRequestHeader "Content-Type", "application/pdf"
- xhr.send Null
标签:
AJAX,
Firefox,
JavaScript,
XMLHttpRequest,
二进制,
数据遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | No Comments »
Posted by bianbian on 2008-04-04 02:22
本文Tags: BBS, memcached
libevent
http://www.monkey.org/~provos/libevent/
memcached
http://www.danga.com/memcached
libmemcached
http://tangent.org/552/libmemcached.html
memcachedb (新浪博客技术团队,赞一个)
http://memcachedb.org/
ncache (同上)
http://code.google.com/p/ncache/
标签:
BBS,
memcached遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C/C++, Technology | No Comments »
Posted by bianbian on 2008-04-02 09:16
本文Tags: SQL, 数据库
SQL语句的需求真是无止境,今天又有一个:需要保留数据表内最后N条记录。
这个需求还是经常碰到的:
比如实时更新的滚动新闻,只需要保留最后的N条,过期的就删除;或者临时上载文件存放表,每天只允许保留N个文件,过期的就连文件一起删除(数据库存放文件路径方式,除了删除记录,还要删除文件——意味着需要取出将被删除的过期记录)。
因为事先不知道总记录长度,常规做法应该select count(*)一遍,然后获得要删除的记录条数。
不过为了提高数据库性能,应尽量减少查询结果返回次数——其实就是能不能一句SQL搞定?
- //删除记录,假设N为100
- DELETE FROM table WHERE id NOT IN ( SELECT id FROM table ORDER BY id DESC LIMIT 100 );
-
- //取出过期记录
- SELECT * FROM table WHERE id NOT IN ( SELECT id FROM table ORDER BY id DESC LIMIT 100 );
标签:
SQL,
数据库遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in Database, Technology | No Comments »
Posted by bianbian on 2008-03-31 10:09
本文Tags: Firefox, IE, Mouse, Wheel, 滚轮, 鼠标
滚轮IE和Firefox的代码不一样:
IE是mousewheel事件,Firefox是DOMMouseScroll事件
事件属性,IE是event.wheelDelta,Firefox是event.detail
属性的方向值也不一样,IE向上滚 > 0,Firefox向下滚 > 0
- //滚轮放大或缩小,基于Prototype 1.6
- var scrollfunc = function(event) {
- var direct = 0;
- if (event.wheelDelta) {
- direct = event.wheelDelta > 0 ? 1 : -1;
- } else if (event.detail) {
- direct = event.detail < 0 ? 1 : -1;
- }
- zoom(direct);
- };
- Event.observe(document, 'mousewheel', scrollfunc);
- Event.observe(document, 'DOMMouseScroll', scrollfunc); //firefox
标签:
Firefox,
IE,
Mouse,
Wheel,
滚轮,
鼠标遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | No Comments »
Posted by bianbian on 2008-03-26 02:32
本文Tags: bug, IDL, IDLgrClipboard, 剪贴板
经过运行剪贴板监视器程序,我确认这是IDL的bug:如果用VC等其他语言调用IDL绘图,IDL并不能通过IDLgrClipboard对象将绘图结果保存到系统剪贴板(而在IDL的编辑器环境下运行,剪贴板是能得到绘图结果的)。
下面是英文描述:
IDLgrClipboard not works in callable mode (I use VC++ to execute IDL procedure to draw some plots, and copy the result to system clipboard). After running a system-clipboard-viewer-tool, I conclude it must be a bug (I tested with IDL6.2, IDL7.0).
oClipbrd = OBJ_NEW(’IDLgrClipboard’, DIMENSIONS=windowSize)
oClipbrd->Draw, oView
It works well under IDL-workbench, but when call from VC++, everything else goes OK except clipboard is empty.
解决办法:只好制定FILENAME参数,将结果保存到文件:
Finally, I have no choise but to save the drawing to a file, and it works:
oClipbrd->Draw, oView, FILENAME=’tempout.bmp’
标签:
bug,
IDL,
IDLgrClipboard,
剪贴板遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C/C++, ENVI & IDL, Technology | No Comments »
Posted by bianbian on 2008-03-25 10:03
本文Tags: FY2C, 云图
模仿Google Map(图片切片载入在此平台不需要实现):
支持IE、Firefox等,支持鼠标移动、鼠标双击放大(左键)缩小(右键)、鼠标滚轮放大缩小
云图实时处理和发布(因为在学校内网,实时版本大家不能看到啦)
这里贴下演示地址(只有最后两个时次的图片):FY2C实时云图平台演示
标签:
FY2C,
云图遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in C/C++, JavaScript, Meteorology, Technology | No Comments »
Posted by bianbian on 2008-03-25 01:57
本文Tags: JavaScript, prototype, this
发信人: Net (BBS上没有什么事情是bg不能解决的), 信区: WebDesign
标 题: Re: Javascript问题
发信站: 南京大学小百合站 (Tue Mar 25 01:16:03 2008)
Javascript里的this和其他OO语言不一样
Javascript其实并不适合做OO,其实OO也并不适合Javascript
扯远了。。。。。。
this你就当“执行函数的宿主”理解。因此在一串函数的执行过程中,this不停地在变。
- A = {
- member: "OK",
- method: function () {
- alert(this.member);
- }
- };
- B = A.method;
-
- A.method(); //弹出"OK". A是宿主,this.member == A.member
- B(); //弹出undefined. window(缺省)是宿主,this.member == window.member
为了解决这个问题,很多框架对此进行了包装。
比如Prototype,用bind,实际是动态生成一个function,把宿主作为动态function的执行者,这样对用户来说,this似乎没有变化。
- bind: function() {
- if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
- var __method = this, args = $A(arguments), object = args.shift();
- return function() {
- return __method.apply(object, args.concat($A(arguments)));
- }
- }
实际只要明白this是执行者的指针,一切都可迎刃而解。
标签:
JavaScript,
prototype,
this遵守创作共用协议,转载请链接形式注明来自
http://bianbian.org 做人要厚道
相关日志
Posted in JavaScript, Technology | No Comments »