e61i新玩法 – Mobile Web Server

在e61i上搭建自己的mobile网站,然后可以用PC在任何地方连接你的e61i.可以方便的共享,只是似乎速度比较慢.

1.下载 MobileWebServer 下载
2.如果已经有装S60的Python,要先删除.然后再安装 MobileWebServer
3.需要注册一个用户,然后email验证.同时提供一个二级域名,如: zhangv.mymobilesite.net
4.用e61i连接网络,启动MobileWebServer,用之前注册的用户登录

这样就可以通过Internet访问你的手机的共享资源了.截图看这里.当然需要先登录. 你可以通过设置启动guest.如果你总是时刻都在线而又有很多有趣的东西共享给其他人.这是个不错的选择.或者你喜欢用一个web的界面来操作你的e61i,比如你把手机丢在家里而手机的webserver是启动的,那你照样可以在办公室里通过你的e61i发送短信,共享文件,查看通讯录…更牛x的是可以创建一个手机的blog,当朋友访问你的手机site的时候可以随时看到你的最新动态.

未知的问题:
1.安全性还不知道,可能现在使用无线的用户不多吧
2.在手机上运行这个webserver是不是会占用太多的资源

最近在读的书

<<少即是多>> Seth Godin

虽然这本书很”畅销书”,因为里面的152个妙想大多数都颇有启发性,至少对我. 另外很重要的一点就是他们都很短小,很适合现在大多数”沉迷”快餐文化的可怜人(包括我).

<<中国人的精神>> 辜鸿铭

认识你自己

<<丑陋的中国人>> 柏杨

第二遍,时刻提醒自己

<<5分钟和陌生人成为朋友>>

发现自己在社交方面有点问题,有点像宅男方向发展

Playin’ with E61i

  • 邮件(Email)

Mail For Exchange ->用于Exchange邮件
GmailMobile -> 收Gmail的客户端
BlackBerry Connect ->没用过还
可以通过配置imap来收gmail邮件。似乎更好

  • 无线(WIFI,WLAN)

Fring ->可以通过skype,msn,googletalk,ICQ,twitter或sip服务进行语音通话
Gizmo ->费用不详

  • 软件(Software)

ScreenSnap ->屏幕截取
Google Maps Mobile ->google地图手机版
Opera Mini ->Opera网络浏览器,还是觉得e61i自己的浏览器好用一点.有备无患.用Gmail有问题,而且速度慢
FaceWarp ->变脸,比较好玩
DivxPlayer ->视频播放器
CorePlayer ->我觉得比divx播放器好一点,不过对我来说都差不多,因为并不常用
掌上书院 ->看书的,可以收藏,添加书签,在线下载…支持图片
QReader ->更好地看书软件,速度快使用方便,界面清爽,只是不支持图片
Handy Clock ->强大的时间管理工具,包括世界时钟,世界地图,我主要用闹钟
Handy Profile ->情景模式管理,定时,自定义切换规则
Handy Taskman ->任务管理
AgileMessenger ->all in one的im工具,支持yahoo,msn,googletalk
F-Secure ->防火墙,有备无患
MobyExplorer -> 文件管理器,同时支持ftp
Resco Photo Viewer ->图片管理
Putty -> e61i连接ssh
iSkoot ->e61i上的skype客户端,通过一个本地的网关来连接skype,应该是只支付本地电话费.香港可以,目前不确定国内是否支持.到mosh下载
smart2go ->地图下载,不需要网络连接(不同于googlemap).下载了上海和北京的地图却看不到详细的街道名.
MGtalk ->开源的jabber/googletalk客户端,虽然界面不是很美观,但是因为不像fring那样的proxy client,所以要安全一些.同时还有gmail提醒功能.
Talkonaut ->很棒的im工具,支持gtalk和msn。但是不支持中文输入。
ZTA4 ->最好的输入法
MsnMessenger ->官方的移动客户端,但在香港使用有问题,国内使用GPRS正常.
MoFire -> 我自己写的在手机上发布blog的工具

  • 游戏(Game)

S-Tris2 ->俄罗斯方块
Snake ->Nokia的经典游戏,这个是3250的下载页面,可用
iNES ->FC(红白机)模拟器
vNES ->经典的symbian上fc模拟器,建议大家去买,国产的共享软件,只有25rmb。ines好像是30美刀
古墓丽影 ->还用说吗
SkyForceReloaded -> 傲气雄鹰,如果用nokia不知道这个游戏就有点土了
MicroPool -> 桌球
Chinese Chess -> 象棋,电脑有点笨,操作起来稍显麻烦。
上面的三个到s60.s80.cn下载

  • 在线(online)

GoogleReader -> Google在线rss阅读器
GoogleCalendar -> Google日历
Flickr -> 照片管理
Youtube -> 16亿,e61i内置的浏览器因为没有flash内建支持所以没有办法看

  • 关注(keep watching)

Deepfish -> 微软的mobile浏览器

  • 资源(Resources)

SymbianV3
Series60v3.com
My(and your) E61
Nokia E61 Blog
Wendong’s Smart Phone Weblog
Eseries
MOSH
推荐!
S60下载推荐

最后更新2008-2-1

AOP与OOP

(最初发布在JavaResearch.org,现在整理好放到自己的地方.)

作者:Narayanan A.R. June 15, 2005
翻译:ZhangV 2005-06-28
原文出自:DevX.com
原文链接:http://www.devx.com/Java/Article/28422/0/page/1

首先你要明确的一点,AOP和OOP是两种不同的认识事物的角度,并不是说有了AOP就不要用OOP.AOP所关注的是传统OOP不能优雅解决的问 题.(程序员通常都是完美主义者,当解决某个问题不优雅的时候,那就意味着不完美.)下面将就一个简单的例子来说明他们到底如何的不同.

作为一个使用OOP多年的人来说,当我听说AOP可以解决一些OOP一直都不能优雅地解决的问题时,我觉得应该去探个究竟了.对两种技术的比较最能给我们实际应用提供见解.这里我设计了一个例子:一个OOP应用,其中某些方面适合使用AOP.

本文展示了一个简单的例子.一开始介绍了问题域,然后分别给出传统OOP的解决方法与结合了AOP解决方法.后者使用了 JDK5.0,JUnit,和 AspectWerkz.最后我会说明如何编写代码.读完本文后,我希望你能知道AOP到底是什么,用来解决什么样的问题.

问题域描述
一个软件公司雇佣一个程序员,指定给他一个业务部门并要求他随时向经理报告.当团队成员完成他们的目标时,经理会给他们相应的奖金.公司所需要的方案必须能够增加一个新的雇员并给当前的员工增加奖金.为了方便,我们用CSV文件存储数据.


图1 解决方案模型

类Manager(经理)继承自类Employee,包含一个额外的属性,Managing Project.一个部门可能包含很多员工.多个部门构成了公司.暂不考虑公司这样的一个类,因为它在问题域之外.

解决方案设计
以下流程图描述了解决方案设计.


图2 对象之间的交互(增加一个新的员工,指派给他一个部门和经理)

出于简单的考虑,本文只关注必需的细节.你也可以深入代码得到你想要的其他信息.
下载
EmployeeServiceTestCase, 一个JUnit测试用例,模拟一个最终用户,创建新员工记录,指派部门和经理.它获取所有可用的部门和经理数据并显示在图形界面上.为了实例化域对象 BusinessUnit和Manager,获得的记录将传递给工厂类.之后,通过给EmployeeService传递一个引用来创建一个 Employee对象.这个服务类使用EmployeeFactory创建对象,并把这个对象传给EmployeeRepository 来进行持久化操作.

应用程序中需要面向哪些”Aspect”
到目前为止,对模型和设计的讨论还限于一个较抽象的层面.现在,我转向这个应用的其他方面 – 这对理解AOP的价值至关重要.

操作所需的资源

<pre lang=”java”>

public static Set findAllBusinessUnits() throws RepositoryException {
Set businessUnits = new HashSet();
try {
FileReader businessUnitFile = null;
BufferedReader bufferedBusinessUnitFile = null;
try {
businessUnitFile = new FileReader(FILE_NAME);
bufferedBusinessUnitFile = new BufferedReader(businessUnitFile);
String businessUnitRecord;
while((businessUnitRecord = bufferedBusinessUnitFile.readLine()) != null) {
BusinessUnit businessUnit = BusinessUnitFactory.createBusinessUnit(businessUnitRecord);
businessUnits.add(businessUnit);
}
} finally {
if(bufferedBusinessUnitFile != null) {
bufferedBusinessUnitFile.close();
}
if(businessUnitFile != null) {
businessUnitFile.close();
}
}
} catch(IOException ioe) {
String message = “IOError. Unable to find Business Unit records”;
logger.log(SEVERE, message, ioe);
throw new RepositoryException(message, ioe);
}

logger.log(INFO, “Manager Records returned:” + businessUnits.size());
return businessUnits;
}
</pre>

上面的代码通过FileReader和BufferedReader来读取CSV文件中的业务数据.
应用程序重复地从资源文件中取得数据然后在操作完成后释放. 我们会发现:去掉程序的这两个”Aspect”将提高代码的可读性并达到一个更好的设计,因为去掉这些”多余”的东西,剩下的代码才是这个方法真正的精 髓.这个方法的作用是读取业务单位数据.所以不应该也不需要去知道”如何获取和释放资源以及这个过程中出现的异常”这个”切面”.同样地,使用AOP处理 异常也变得不同.(后面将详细介绍)

持久层
传统的OOP使用持久化类(repository classes)来持久应用程序的持久层.即:

<coolcode lang=”java” linenum=”off”>
public class EmployeeRepository {

public static void createEmployee(Employee employee) throws RepositoryException {
//使用print writer把数据放入csv文件
}

public static String findEmployeeRecordById(String id) throws RepositoryException {
//使用file reader来获得指定id的员工数据
}

public static Employee findEmployeeById(String id) throws RepositoryException {
//使用该方法获取员工数据,Employee对象由工厂类创建
}

public static void updateEmployee(Employee employee) {
//更新员工数据
}
}
</coolcode>

类EmployeeService 使用一个EmployeeRepository给应用中相关雇员提供服务,在一个企业应用中,从域模型 (domain model)中去掉持久层代码是一种设计上的改进.模型设计者和程序员就可以关注各自的业务逻辑和持久层处理.后面你将会看到如何通过 AOP来达到这样的效果.

日志
删除用于调试的日志代码将会极大地改进代码的可读性.考虑下面的代码片断:

1.
2. public Employee createEmployee(String name,
3. String contactNumber,
4. BusinessUnit businessUnit,
5. Manager manager)
6. throws EmployeeServiceException {
7. String id = createNewEmployeeId();
8. Employee employee =
9. EmployeeFactory.createEmployee(id, name, contactNumber, businessUnit, manager);
10. try {
11. EmployeeRepository.createEmployee(employee);
12. } catch(RepositoryException re) {
13. String message = “Created employee successfully:” + employee;
14. logger.log(SEVERE, message);
15. throw new EmployeeServiceException(message, re);
16. }
17. logger.log(INFO, “Created employee successfully:” + employee);
18. return employee;
19. }

上面的代码里包含了一个致命错误和一个成功信息.输出日志这一”Aspect”同样可以移到业务模型外独立实现.

异常处理
异常处理的例子我这里不再赘述,但这节已经通过上面的代码讨论了潜在的问题.当你调用EmployeeRepository 对象的 createEmployee 方法时,你可能会得到一个RepositoryException异常.传统的解决方法是,在这个类中处理.另一种方法是,当 RepositoryException 异常被抛出时createEmployee 方法返回null,catch块中的其他逻辑可以在类外处理这一错误.
错误处理在不同的情况中也会不同.但是,通过AOP可以区分开每种情况.

图3

图3中描述了AOP方法的设计以及在一个更抽象的层次上类间的交互.你可以通过对比图1和图3来更好地理解AOP.
程序的目的是通过BusinessUnit对象读取CSV文件中的记录然后填入类BusinessUnitService 中的map.使用AOP来填充这个map有点类似后门(backdoor)方法 — 控制被委派给BusinessUnit 来读取存储介质中的记录.

AOP就是定义一些切入点(pointcut)和处理方法(advice).一个”切入点”是源代码中一个执行点.前面的例子定义了一个”切入点” — 类 BusinessUnitService中的findBusinessUnits方法.一个”处理方法”顾名思义就是当执行到某个”切入点”时的一块代 码.类BusinessUnitPersistentAspect 包括advice方法findAllBusinessUnits,该方法从存储介质中载入数据,然后使用工厂类创建BusinessUnit 对象.然后这个对象被加入map,map对象的引用通过 BusinessUnitService 对象获得.”切入点”和”处理方法”组成了所谓的”aspect”.

为了读取存储介质中的数据,OOP方法通过一个DAO类来做.而AOP中,你只要定义一个”切入点”和相应的”处理方法”来读取数据.AOP框架会以advice的形式注入代码,既可以在执行期也可以在编译期.

总而言之,当类BusinessUnitService 中的findAllBusinessUnits 方法被调用时,AOP框架会在”切入点”处注入处理方法,通过BusinessUnit 对象预先读取数据来填充map对象.这样,持久层方面的代码就可以移到业务代码之外了.

新方法里的”Aspect”

本节讨论如何用AOP为应用程序的各个”切面”建模

操作资源

类BusinessUnitPersistenceAspect 的持久方法使用了一个buffered reader.你甚至可以定义”切面”的”切面”,但为了简单,这里只关注类的查找方法.

1.
2. @Aspect(“perJVM”)
3. public class BufferedFileReaderAspect {
4.
5. @Expression(“execution(* org.javatechnocrats.aop.withaop.aspects.BusinessUnitPersistenceAspect.find*(..))”)
6. Pointcut businessUnitPersistenceAspect;
7.
8. // 其他”切入点”定义
9.
10. @Expression(“businessUnitPersistenceAspect ||
11. employeePersistenceAspect ||
12. managerPersistenceAspect”)
13. Pointcut allPersistencePointcuts;
14.
15. private Map<Class, String> fileNames;
16.
17. public BufferedFileReaderAspect() {
18. System.out.println(“BufferedFileReaderAspect created”);
19. fileNames = new HashMap<Class, String>();
20. fillFileNames();
21. }
22.
23. @Before(“allPersistencePointcuts”)
24. public void assignReader(JoinPoint joinPoint) throws Throwable {
25. System.out.println(“assignReader advice called”);
26. Object callee = joinPoint.getCallee();
27. IBufferedFileReaderConsumable bufReaderConsumable = (IBufferedFileReaderConsumable)callee;
28. Class persistenceClass = callee.getClass();
29. String fileName = fileNames.get(persistenceClass);
30. FileReader fileReader = new FileReader(fileName);
31. BufferedReader bufferedReader = new BufferedReader(fileReader);
32. bufReaderConsumable.setBufferedReader(bufferedReader);
33. }
34.
35. @AfterFinally(“allPersistencePointcuts”)
36. public void releaseReader(JoinPoint joinPoint) throws Throwable {
37. //释放buffered reader等资源
38. }
39. //其他方法
40. }

上面的代码试图为每一个方法创建”切入点”– 所有以find开头的方法.无论何时这些方法被调用,assignReader方法都会被提前执行.这里它获取被调用的类实例然后设置新建的BufferedReader.

同样地,在releaseReader 方法里,代码会预先关闭buffered reader集合.本节只解释@before和@
AfterFinally 这两个”切入点”.(以J2SE 5.0的标记定义).另外,你也可以在方面定义的xml文件中声明他们.你可以查看例程源代码中的aop.xml文件.

下载

持久化

前面提到,OOP方法使用BusinessUnit 来为应用的持久层填充Map.在下面的高亮代码中(@before一行,以及while循环代码 – 译者注),当BusinessUnitService 中的方法findAllBusinessUnits 被调用时”处理方法 “findAllBusinessUnits 也将被调用.

1.
2. @Aspect(“perJVM”)
3. public class BusinessUnitPersistenceAspect implements IBufferedFileReaderConsumable {
4.
5. private BufferedReader buffFileReader;
6.
7. @Before(“execution(Collection org.javatechnocrats.aop.withaop.BusinessUnitService.findAllBusinessUnits())”)
8. public void findAllBusinessUnits(JoinPoint joinPoint) throws Throwable {
9. System.out.println(“findAllBusinessUnits advice called”);
10. Map<String, BusinessUnit> businessUnits =
11. ((BusinessUnitService)joinPoint.getThis()).getBusinessUnits();
12. String businessUnitRecord;
13. while((businessUnitRecord = buffFileReader.readLine()) != null) {
14. BusinessUnit businessUnit = BusinessUnitFactory.createBusinessUnit(businessUnitRecord);
15. businessUnits.put(businessUnit.getId(), businessUnit);
16. }
17. }
18.
19. public void setBufferedReader(BufferedReader buffFileReader) {
20. System.out.println(“BusinessUnitPersistenceAspect.setBufferedReader called”);
21. this.buffFileReader = buffFileReader;
22. }
23.
24. public BufferedReader getBufferedReader() {
25. System.out.println(“BusinessUnitPersistenceAspect.getBufferedReader called”);
26. return this.buffFileReader;
27. }
28. }

“处理方法”从数据存储中读取记录,使用工厂类创建一个BusinessUnit实例.然后这个实例被加入到Map.该Map掌管程序的所有持久化”aspect”.

日志
本文中的例子没有包含一个完整的日志AOP解决方案.但是,它为java.lang.Object类的toString方法定义了一个”切入点”来获取类 的调试信息.因此,域中的类不需要实现toString方法.通常情况下你可能需要为每一个类都要实现toString方法.

1.
2. @Aspect(“perJVM”)
3. public class LoggingAspect {
4.
5. @Around(“execution(String org.javatechnocrats.aop.withaop..*.toString())”)
6. public Object toStringAdvice(JoinPoint joinPoint) throws Throwable {
7. System.out.println(“toStringAdvice called”);
8. String toString = (String)joinPoint.proceed();
9. Object target = joinPoint.getThis();
10. Field fields[] = target.getClass().getDeclaredFields();
11. List members = new ArrayList(fields.length + 1);
12. members.add(toString);
13. for(Field field : fields) {
14. field.setAccessible(true);
15. Object member = field.get(target);
16. members.add(field.getName() + “=” + member);
17. }
18. return members.toString();
19. }

你也可以用这个样例代码完成错误处理”切面”.

深入源代码

为了理解样例需求的OOP设计,请参看源代码并思考以下几个问题:
下载

* 首先分析oldway包中EmployeeServiceTestCase 类中的代码
* 查看testEmployeeCredit 方法
* 搞懂业务类Employee和BusinessUnit
* 学习 service,repository和factory这些概念.这些是业务驱动设计的主要概念.
* 更深入地理解oldway包中的service,repository和factory类

而AOP地理解则应该是:
* 分析newway包中EmployeeServiceTestCase 类
* 查看service,repository和factory类,基本和前一种差不多.只是你要让”处理方法”截获程序的执行流程.
* 研究aspect类学习”切入点”的定义

要执行程序,你需要做的工作:
* 下载AspectWerkz 2.0 http://aspectwerkz.codehaus.org/
* 设置以下的环境变量:
set JAVA_HOME=c:Program FilesJavajdk1.5.0
set ASPECTWERKZ_HOME=C:aw_2_0_2
set PATH=%PATH%;%ASPECTWERKZ_HOME%bin
set CLASSPATH=
C:aw_2_0_2libaspectwerkz-2.0.RC2.jar;C:aw_2_0_2libaspectwerkz-jdk5-2.0.RC2.jar; classes;C: junit3.8.1resourceslibjunit.jar
* 解压缩源代码和其他文件
* 编译Java文件,但不要编译测试用例否则你调试时会遇到一个错误.
* 进行离线调试.假设你把文件解压缩到c:aop ,类文件解压到c:aopclasses,在c:aop目录下执行以下命令:
% ASPECTWERKZ_HOME%binaspectwerkz -offline etc/aop.xml -cp classes classes
* AOP框架会修改类来注入必要的字节码
* 编译测试用例,使用JUnit运行它.

后记
当你完成了上面的这些工作,你应该有以下的领悟:
* 程序中的交叉关联
* 关于AOP中”切面”的含义
* 如何用AOP来把程序业务层中的交叉关联分离出来,使用”切入点”和”处理方法”
* OOP和AOP时在程序控制流上的不同

从本文你应该也得到一种看待实际开发的新视角.你应该有信心使用AOP来改进项目中的设计,建模,提高代码的重用性.至少,你可以开始使用AOP来处理日志,错误和持久化.

个人觉得,AOP的学习曲线相对较陡,尤其在理解定义”切入点”的句法时.理想的情况是,使用OOP来设计业务模型,使用AOP把业务模型中的交叉关联移出,从而使代码简洁并提高可读性.

AOP的一个缺点是会使调试变得困难,因为不同于OOP,程序流变的复杂了,交互是由编译期或执行期决定.我准备将来做一些自动化工具来解决这个问题.

啥是Spring

(最初发布在JavaResearch.org,现在整理好放到自己的地方.)

有人说spring aop+ spring ioc, 才~~~是spring
简单一点,是一个容器. 什么容器,容纳什么?是对象,或者说bean的容器.
那为什么叫轻量级容器呢?相对于EJB container,使用spring不需要写符合容器规范的代码,即容器不会”侵入”了你的代码.

这 个容器会提供你的应用(程序)中用到的所有对象,并对这些对象进行统一的生命周期管理和组装.在通常的开发中,我们在需要某个对象的时候只是 new MyObject(). 在Java中,这样没有什么不好,因为gc会打理好”善后”工作,是系统级的. 而用spring,在需要某个对象 时,只要向容器请求相应的对象,spring会找到并准备好这些对象并提供给你.她也会打理好”善后”工作,但是是在应用级的.
另一方面,spring还会帮助你打理对象之间的依赖关系.
比如原来的做法:

class A{
}
class B{
A a ;
public B(){ a = new A();}
}

而使用spring的做法
class A{
}
class B{
A a;
public B(){}
void setA(A a){this.a=a}
A getA(){return this.a}
}
(希望你不要单纯地认为spring会写很多代码)
但 从前一个方面,你可能觉得spring只是一个对象容器.从这里你就应该看出,spring是bean容器,因为spring需要你的类符合bean规 范:相应于每一个成员域,都需要提供setter和getter方法.spring要使用这些方法来注入依赖关系,也就是 dependence injection, 或者inversion of control. 我个人觉得还是di更容易理解,直到现在我还是要考虑 怎么去向别人很好的解释ioc.控制反转(倒转),我的理解是就如同上面的两个例子里看到的,依赖(控制)不在体现在代码逻辑里(如第一个例子),而是在 配置文件里,而在代码中我们只提供注入点(也就是setter和getter).

希望我对IoC的概念的讲解能够给你一些启发.
你 可能要问了,为什么我要这样做呢?原来的做法有什么不妥的地方么?没有什么不妥,只是两种理念而已,没有绝对的好还是不好,但我还是给你我的解释–我理 解的IoC的好处,希望有所帮助.通常在程序设计的时候,我们在需要某些功能时,会相应的去设计一些方法,然后根据OO去将方法和一成员变量组成一个类. 实际上,我们最终设计出的程序是:一组类的实例互相交互完成某个特定的任务.
除了一些核心的业务方法,以外我们还要做组装对象的工作.比如我有了 一个工厂,里面有很多机器,机器在开动时要装配相应的模具.那么在工厂的生产过程中, 首先我要有工厂,机器,模具这样三个类.然后我的”动作”有:装 配,开机.通常的做法我们要做装配,然后再去开机.而用spring,我们只是专注于开机.这样我们就把装配这个动作抽离出了核心的”生产过程”.当某些 机器改变了装配模具时,不在需要修改核心业务代码.这就是解耦.如:

public class Production{
public static void main(String[] args){
Factory factory = (Factory)BeanFactory.getBean(“factory”);
factory.launchProduction();
}
}

class Factory{
Machine machine1,machine2;
void launchProduction(){
machine1.start(); machine2.start();
}
// setters and getters
}

class Machine{
Tool tool;
void start(){
}
// setters and getters
}

在launchProduction()方法中只需要开动每台机器即可.而不需要每次都装配机器.装配的工作交给了别人.现在只要按下start按钮.生产就开始了!要是原来:

void launchProduction(){
machine1 = new MachineA();
machine1.setTool(new ToolA());
machine2 = new MachineB();
machine2.setTool(new ToolB());
machine1.start();
machine2.start();
}

这就是工作分工,是不是感觉轻松了许多?从此以后,我们都是面向构件去开发,而不需要过多地在代码中体现构件之间的依赖关系.

AOP
推荐你看一下<<effective enterprise java>>的第一章,对AOP有很清晰,易懂的解释.其实AOP并非很艰深晦涩的概念,但是从架构角度去理解她的重要性可能不是我这样的new fish一时半会儿可以领悟到的.
我这里只是想说,有些概念你要知道是怎么回事,但理解到多深,除了天赋以外更多的是经验和悟.所以不要心急.–像是在自我解嘲.
也许在不知不觉中你就使用了很多AOP的概念,比如servlet里的filter,比如在写一个command类时,给她的调用类在每次调用command时前后加上:preProcess和postProcess…
我不想解释太多,<<eej>>的解释已经足够.

Hope helps.

OSGi 技术

作者:OSGi.org
翻译:ZhangV 2006-03-13
原文出自:OSGi.org
原文链接:http://www.osgi.org/osgi_technology/index.asp?section=2

简介

OSGi 规范为网络化的服务定义了一个标准的,面向组件的计算环境.给网络设备添加OSGi服务平台,使之可以有能力在网络的任何地点管理软件组件的生命周期.组 件可以在运行期间被安装,更新或删除,无需打断设备的其他操作.软件组件是可以动态查找和使用其他组件的库或程序.软件组件可以通过购买或自行开发. OSGi联盟已经开发了许多标准的组件接口,诸如HTTP服务器,配置,日志管理,安全,用户管理,xml等等这些常用功能.可以从不同的提供商那里获得 这些即插即用的兼容实现.

软件组件体系正面临一个日益凸现的问题:大量需要开发和维护的配置.而标准化的OSGi组件体系极大的简化了这个配置过程.

框架
OSGi规范的核心组件是OSGi框架.他为应用提供了一个被称为包捆(bundle)标准环境.OSGi包括这样四层:
L0.执行环境
L1.模块
L2.生命周期管理
L3.服务注册表
此外还包含一个安全系统.

执行环境就是Java环境.J2SE,CDC,CLDC,MIDP等都是合法的执行环境.OSGi同时根据核心定义(foundation profile)和一个最简版本制定了一个标准的执行环境.
模块层定义了类装载策略.OSGi框架是一个强大的类装载模型.以Java为基础但加入了模块化的思想.在Java中,只有一个包含了所有的可用类和资源类路径.OSGi的模块层还为一个模块提供了私有类以及模块之间的连接.
生命周期层将包捆动态地安装,启动,停止,更新和卸载,包捆依赖于模块层的类装载但提供了一套API来在运行期管理所有的模块.扩展的依赖机制用于确保正确模块依赖关系.
服 务注册表为包捆提供一个互操作模型实现动态性.包捆可以通过传统的类共享来互操作,但是类共享在当动态安装和卸载代码时会表现得很不稳定.服务注册表提供 了一个易于理解的模型来在包捆之间共享对象.大量的事件被定义于处理服务之间的交互.服务如同Java对象一样,可以代表任何事物.许多服务和对象是一样 的,像http服务器,服务就是现实中的一个对象,比如一个附近的蓝牙电话.

安全是建立在Java和Java2安全模型之上.语言级的限 制避免了许多可能出现的隐患(The language by design limits many possible constructs). 比 如,病毒常用的缓冲区溢出是不可能的.访问修饰符可以限制代码的可见性.OSGi通过”允许私有类”扩展了这一模型,在标准Java中不包含这种机制. Java2安全模型提供一个易理解的模型来检查代码对资源的访问权限.OSGi加入了完全的对访问请求动态管理.

标准服务

在框架之上,OSGi联盟制定了许多服务.服务由一个Java接口定义.包捆可以实现这个接口并把实现注册到服务注册表.服务的用户可以从服务注册表中找到他,或者对服务的加入或取消做出反应.
以下各部分给出OSGi release 3服务的一个简单介绍.更多资料可以找OSGi服务平台release 3的书籍或PDF下载.要注意每个服务都是先被抽象地定义然后由不同厂商独立实现.

框架服务

OSGi 框架提供一个权限管理服务(permission admin service ),一个包管理服务(package admin servie),和一 个启动级别服务(start level service).这些服务是可选的 and direct the orperation of the Framework(不知道怎么译).
• 访问管理(Permission Admin) – 当前或将来的包捆的访问权限可以通过这个服务来操作.
• 包管理(Package Admin) – 包捆之间共享类和资源.包捆的更新可能需要系统重新更新包捆之间的依赖关系.该服务提供系统实际包的共享状态并刷新共享的包.如,取消或者重新计算依赖关系.
• 启动级别(Start Level) – 启动级别是一个包捆的集合,这个集合中的包捆必须一同运行或者要在其他服务启动之前初始化.启动级别服务设置当前的启动级别,制定某个包捆的启动级别,查看当前设置.

系统服务

系 统服务提供横向功能(horizontal function),这些在每个真实的系统中都是存在的.比较常见的有,日志服务 (Log Service),配置管理服务(Configuration Admin Service),设备访问服务 (Device Access Service),用户管理服务(User Admin SErvice),IO连接服务 (IO Connector Service)和参数选择服务(Preferences Service).
• 日志服务 – 信息,警告,调试信息的纪录,或者处理错误.他接收日志纪录信息然后分配他们给其他订阅了这些信息的包捆
• 配置管理服务 – 该服务提供一个易伸缩的动态模型来设置和获得配置信息
• 设备访问服务 – 设备访问是配置一个驱动器到一个新设备并自动下载实现该驱动器的包捆的机制
• 用户管理服务 – 该服务使用一个用户信息数据库(私有和公有)来鉴权和授权.
• IO连接服务 – 实现了CDC/CLDC的javax.microedition.io包作为一个服务.该服务允许包捆提供新的,可选协议方案.
• 参数选择服务 – 提供属性数据库的访问.和Windows的注册表或Java的Preferences类.

协议服务
OSGi联盟定义了以下外部协议服务:
• Http服务 – 一个servlet容器.包捆可以提供servlet.OSGi的动态更新机制服务平台使得Http服务变得非常诱人,加入新的servlet而不需要重启.

• UPnp 服务 – 通用即插即用(Universal Plug and Play)是一个正在兴起的用于用户电子设备的标准,OSGi UPnP 将一个 UPnP网络设备映射到服务注册表.或者,将一个服务映射到UPnP网络(该服务在release 3中被推荐).
• Jini服务 – Jini是一个网络协议,用于在网络上发现Jini服务并下载执行.(该服务在release 3中被推荐).

其他服务
• 关联管理服务(Wire Admin Service) – 通常包捆会自己建立查找服务的规则.但是在很多情况下,这是一个发布时需要考虑的问题.因此关联管理服务会通过一个配置文件把不同的服务连接起来.使用消费者和生产者的概念来达到对象之间的互操作.
• XML解析服务 – 允许一个包捆定位一个解析器并使用相应的属性.与JAXP兼容.

结论
OSGi规范的适用范围很广.因为它通过一个很简单的层使得同一个虚拟机的Java组件高效率的交互.通过一个扩展的安全模型来使组件运行在一个安全的环境中.通过恰当的访问限制,组件可以被重用和组合.OSGi 框架还提供了一个扩展的部署机制来让这种交互可行,安全.

各 个领域构建在OSGi之上的中间件的大量出现,这就给OSGi软件组件创造了一个很大的软件市场. The rigid definition of the OSGi Service Platform enables components that can run on a variety of devices, from very small to very big.

采用OSGi规范可以降低软件开发成本,同时提供新的商业机会.

进一步阅读
OSGi Service Platform, Release 3下载:
http://www.osgi.org/osgi_technology/download_specs2.asp?section=2
或买书:
https://secure.inventures.com/osgi/sales/R3Book_order_form.asp

OSGi联盟的技术白皮书:
http://www.osgi.org/documents/osgi_technology/osgi-sp-overview.pdf
更深入介绍OSGi的白板白皮书(whiteboard whitepaper):
http://www.osgi.org/documents/osgi_technology/whiteboard.pdf

有点迷失

突然有点迷失了,一不小心步入外包这行,感觉自己距离梦想似乎越来越远.也许是一直都不清楚自己”到底”适合做什么吧. 这个问题直到这刻仍然不能给自己一个满意的答案.

一直以来觉得软件这一行应该是google,ms那样 –  实现一个想法(不一定要多伟大),做出人人都喜欢的东西 . 可能是这段时间的工作性质的关系,整天的作一些毫无生趣的事情.辞职的想法每半分钟从脑中闪过一次.但是当清醒一些的时候,就像现在,我又会问自己:ok,如果辞职了,你打算干什么?不要告诉你要去读书吧,我知道当你看了研究生的那些华而不实的课程设计以后,你就不会想去浪费一年或者两年的时间了.

那我到底可以做什么?到底可以怎样去改变自己的现状. –  难道我真的还怕改变吗?

SpringWebFlow – 重用与抽象框架

作者:Edmon Begoli May 5, 2005
翻译:ZhangV 2005-07-22
原文出自:DevX.com
原文链接:http://www.devx.com/webdev/Article/28041/0/page/1

Spring WebFlow是一个全新的Web框架,她带给我们一种全新且高度结构化的Web应用构建方法.让我们来看看她的一些特性.
Spring框架正准备推出一种新的技术.在下一个版本中(1.3,预计在2005年夏天发布)Spring将正式将Spring WebFlow整合进来.Spring WebFlow是一个及其优秀的Web开发框架,用于在Web应用内部创建和配置可重用的Web流程.

熟悉Spring的人可能先入为主地以为Spring WeFlow和SpringMVC没有什么区别.那就错了.Spring MVC是一个轻量级的Web开发框架,而Spring WebFlow 则提出一种全新的视角.她使得Web架构师们可以将精力集中在Web应用开发的抽象层次上:Web流程的逻辑结构和Web事件条件的定义.此外,她还提出许多新的概念.(稍后会介绍到)

本文将回顾这一个新框架前的一些关键概念,用一个经典的用户登录例子来分析流程标记语言的主要组成元素并向您解释为什么WebFlow如此诱人.(读者必需要有Spring 1.2基础).

Spring WebFlow 概念和组件
作为一个Web框架,WebFlow无论在理论上还是在实际开发上都有诸多优点.深厚的软件工程学架构保证了他的稳定性,同时,其组件合理,易于理解,易于使用.
事实上,它更适合中大型应用的开发,因为它的组件模型专门针对架构重用,高效管理性和可配置性进行了优化.

用例研究
本文以一个常见的web应用流程作为示例, 一个身份认证流程,讲解它的一些代码片断.一个Web认证的全过程包括:登录表单,注册表单,认证action,注册action,以及对这些action的结构修饰.这个例子用来展示那些修饰登录表单的组件的配置.

自动操作架构
Spring WebFlow以有限状态机(Finite State machine)的概念为基础.Web应用内部的用户交互行为和事务被建模为一般的状态机,这是一种非常流行的软件工程建模方法.(见图1).自动机为基础的设计是一种很好的设计方法,同时正在越来越收到应用架构的青睐 — 因为它在对Web交互行为建模时显得相对清晰且严谨.

WebFlow的核心组件
一个Spring WebFlow应用中包含一个或多个流程,通常每个流程包括执行Action的动作状态(ActionStates),显示状态(ViewStates),跳转动作(Transitions).

流程
一个流程是一个预先定义好的用户交互行为的集合,表示为一个由动作状态和显示状态构成的树,状态之间通过跳转联系.
下面的登录注册是一个webflow的例子,包含了一些典型的构件,例如loginForm,ActionState,transition.这些构件通过一个XML文件描述:
<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE webflow PUBLIC “-//SPRING//DTD WEBFLOW//EN”
“http://www.springframework.org/dtd/spring-webflow.dtd”>
<webflow id=”LoginSequence” start-state=”loginForm”>

<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>

<view-state id=”formView” view=”enterCredentials”>
<transition on=”submit” to=”bindAndValidateForm”/>
</view-state>

<end-state id=”successView” view=”displayMain”/>
这个流程以loginForm开始,以”successView”结束(修饰主页面”displayMain” 的组件.流程可以通过XML文档配置,或者AbstractFlowBuilder的子类.

动作状态(ActionStates)

ActionStates对用户事件或其他事件进行响应.ActionStates自身又可以包含其他可执行的Action和transition.下面的代码配置了”loginForm”这个ActionState.

<action-state id=”loginForm”>
<action bean=”loginFormAction”/>
<transition on=”success” to=”formView”/>
</action-state>

动作(Actions)

Action是ActionState可以连接,重用,声明调用的最小单位.Action继承自AbstractAction类,该类实现了doExecuteAction方法.这个方法的参数:RequestContext,WebFlow(其中封装了所有流程相关的数据).loginForm动作状态通过Spring的自动装配特性调用LoginFormAction动作.doExecute
Action方法被自动调用,同时可以处理一些登录准备,预先装入等操作.

public LoginFormAction extends AbstractAction{

protected Event doExecuteAction(RequestContext context)
throws Exception{
//perform some login specific setup operations

}//end method

}//end class

显示状态(ViewState)

ViewState初始化对显示组件(jsp,tile等)的修饰操作.下面是一个ViewState的配置代码
<view-state id=”formView” view=”enterCredentials”>
<transition on=”submit” to=”bindAndValidateForm”/>
</view-state>
当来自loginForm的ActionState返回一个”success”时,这个ViewState将会被调用.它将修饰”enterCredentials”显示组件(可以是一个常见的struts forward).

跳转(Transition)

和通常的状态机一样,WebFlow定义了状态以及状态之间跳转动作.这些跳转动作很类似struts中的ActionForward.同样是负责连接两个状态.

后继动作(Continuation)

后继动作(Continuation)允许你回退并重新开始程序执行流程 — 从程序执行的角度来看是一个适时的逆流程.Continuation的概念最早来自编程语言,但是却从来没有被用于像Java,VB,C++这样主流的编程语言中.WebFlow创造性地实现了continuation.由于continuation可以用来持久和重造任何一个流程状态,从而提供给你极大的自由.

重用

WebFlow中的流程定义,如登录流程,有针对性地被结构化以便重用.他们定义封装了自己的生命周期.这些定义可以很容易的用支持Spring的其他Web组件配置重用.架构师应该识别出并定义通用的流程,如登录,搜索等以便今后的重用.
此外,Action如果正确的设计与Spring的结合,也可以被重用.他们可以同时被不同流程的action state使用.这些重用,既有应用级的又有流程级的,增强了维护性和代码可读性.

与struts结合

WebFlow与struts的结合部分地通过标准的Spring类和org.springframework.web.struts包中的一些配置.要与WebFlow相关概念(Action,ActionFlow)结合只需要注册WebFlow规格的struts action,并像普通的WebFlow action一样使用.

下面的配置代码来自struts-config.xml,描述了Struts的Action如何配置成流程的入口.注意WebFlow规格的Action类(org.springframework.web.flow.struts.FlowAction)和属性”flowId”,它们将Action与登陆流程连接起来.例子中的登录流程在Spring的应用上下文(ApplicationContext)中作为一个loginFlow的bean管理.你还需要将这个流程注册为一个由Spring管理的bean.

<!- flow actions ->
<action path=”/loginFlow”
type=”org.springframework.web.flow.struts.FlowAction”
name=”actionForm” scope=”request”
className=”org.springframework.web.flow.struts.FlowActionMapping”>
<set-property property=”flowId” value=”loginAction” />
</action>

在这个例子中还用到了Spring中的RequestProcessor(org.springframework.web.struts.BindingRequestProcessor),是Spring的自动绑定form和bean.这一特性避免再去写单独的ActionForm对象.

<controller processorClass=”org.springframework.web.struts.BindingRequestProcessor”/>

同时,它还要求一个使用工具类来自动绑定Web表单中的值到一个对象.

<plug-in className=”org.springframework.web.struts.BindingPlugin”/>

WebFlow的预发布现在可以下载,其中包含一个样例应用(“birthdate”),详细描述了这个整合过程.

如果你正在着手建立一个Web应用,Spring是一个非常不错的选择.Spring MVC非常容易上手并且可以很方便的同其他组件整合.另一方面,即将出现的Spring WebFlow将提供给你各种复杂的新特性.使你能够开发出高度重用和结构化的Web应用.如果你在开发的是一个大规模的企业应用,这一点是很重要的.这也是为什么struts如此流行.

总的来说,J2EE Web框架目前处在一种群雄逐鹿的状态,没有一个领导者.Struts是最流行的,但是它的主架构师也是主要的开发者已经抛弃了它.被称为Struts取代者的JSF目前还没有获得足够的影响力.而同时,其他的框架正在慢慢开始流行.

你也许会问,”我应该选择哪个?”Spring WebFlow出现可以让你以后再去考虑这个问题.WebFlow允许你在不需要较大改动的情况下方便的切换框架.像前面说过的,Spring WebFlow是一个抽象的框架,可以让你只专注于业务流程和重用.无论是Struts,JSF还是Spring MVC都可以作为它的业务流程实现.因此,你也就不需要马上作出上面说的那个选择了.

Nokia E61 E61i键盘使用方法

Nokia E61 E61i键盘使用方法

符号说明:
键盘默认输入法为拼音。
↗:左下角的蓝色箭头,按一次后可输入1个符号或1个数字,之后恢复拼音键盘;快速按2次后,键盘变为数字或符号输入方式;
↑:Windows的Shift健,按1次可输入1个小写英文字母,之后恢复拼音键盘;
Ctrl+↑:切换输入法(和Windows的一样),输入法依次为“拼音”,“笔画”,“英文”,“拼音”;
Ctrl+空格健:转换输入法(和Windows的一样)中文,英文;
↗+Ctrl:打开或关闭蓝牙;
↗+Car:打开或关闭红外;
在拼音和英文输入方式下,键盘输入没有错误。
在中文输入方式下,符号可通过按Car键后选择符号,在英文输入方式下,Car不可用。
在英文输入方式下,按1、2、3次↑(Shift)可切换英文的输入状态为“Abc”,“abc”,“ABC”。
在中文或英文输入方式下,按2次↗都可换为符号输入方式,除Q(!),R(1),T(2),Y(3),U(*),F(4),G(5),H(6),J (#),V(7),B(8),N(9),M(0),正确外,其它的都有错误,实为:W(”),E(&),I(-),O(+),P(=),A(¥),S ($),D(ε),K(_),L(、),Z(<),X(>),C()
@:在空格键的左边(”,)。
键盘锁(开锁):左上角键+↗

(个别仅E61/E70等QWERTY全功能键盘机型)拼音打字的时候,按右下角的Chr键,也就是亚太版的中键,可以区分待选字符的四个声调,按一下是 第一声,按两下是第二声…….按ctrl+space可实现中英文切换;按↑+Chr可调出编辑语言窗口,选择不同的语言感谢其他机油提供新的信 息!!中文选择字区翻页:在输入后出现的当前中文字对话框内如果没有需要的字,可以使用空格键进行翻页直到选到需要的字。候选字对话框内字的选择:按一下 左下角的箭头(笔形键),再按相应的数字区的数字即可选择。中文输入状态时,按住Chr不放再按字母键可以输入小写英文字母;按一下↑再放开,然后按字母 键也可输入小写英您尚未登陆/注册查看回复返回论坛续上:文字母;按住↑的同时再按字母键,则是输入大写英文字母。从[多媒体资料]浏览图片时,可使用以 下数字键代替菜单,快速操作:1:逆时针旋转3:顺时针旋转5:放大0:缩小2,4,6,8:上左右下移动图片*:在全屏幕和普通视图间切换。用 realone观看视频时,按2可实现全屏切换用自带播放器播放音乐时,5——暂停或播放,4——前一首/(长按快退),6——后一首/(长按快进),8 ——停止,按挂机键直接转入后台播放按↑+回车可做标记,在批量删除短信时很方便;按Ctrl键+上下摇动摇杆可标记相应的文件,再次重复操作则取消标 记。在应用程序中选取文字。按住shift键,并以游戏杆向左或向右卷动以选取文字。您尚未登陆/注册查看回复返回论坛续上:t+游戏杆复制。Ctrl+ C剪下。Ctrl+X贴上。Ctrl+V复原。Ctrl+Z斜体。Ctrl+I粗体。Ctrl+B进入文件夹或者选择程序时可用回车键代替摇杆的OK键 (部分不行)在短信输入完成后,可按拨号键直接发送短信待机状态下:↗+Car为打开红外的快捷方式(↗为键盘左下角的兰色箭头):按住↗再按Car键可 打开红外,红外在没有找到对应红外口后会自动关闭。↗+Ctrl为打开蓝牙或者关闭蓝牙的快捷方式。按住↗再按Ctrl键可打开蓝牙,再次重复操作则为关 闭蓝牙。

[在待机状态下]

↗+Car为打开红外的快捷方式(↗为键盘左下角的兰色箭头):
按住↗再按 Car 键可打开红外,红外在没有找到对应红外口后会自动关闭。

↗+Ctrl 为打开蓝牙或者关闭蓝牙的快捷方式:
按住↗再按 Ctrl 键可打开蓝牙,再次重复操作则为关闭蓝牙。

左功能键+↗为键盘锁:
按下左功能键再按↗可以锁闭手机键盘,重复操作则为打开手机键盘。

左功能键+* 为键盘锁:
按下左功能键再按 * 可以锁闭手机键盘,重复操作则为打开手机键盘。

[在文字编辑中]

↗键的基本使用(↗为键盘左下角的兰色箭头):

按下一次可以输入一个数字或者符号,输入完成后则恢复拼音键盘。
快速按下二次则变为可输入多个数字或者符号,再次按下↗则恢复复拼音键盘。

↑为键盘最下面一行键盘的两个向上方向的键盘:

按下一次可输入一个小写英文字母,输入完成后则恢复拼音键盘。
按住↑再按其他键可以输入多个大写英文字母,输入完成后松开↑则恢复拼音键盘。
快速按两下↑并不松开可以输入多个小写英文字母,输入完成后松开↑则恢复拼音键盘。

注:↑键与其他symbian机型上的编辑键功能相同,也就是我们常说的笔形键。
注:←键与其他symbian机型上的C键功能相同,就是删除键。

Ctrl键+↑为切换输入法:

按住输Ctrl键并按下↑一次或者多次法排列顺序:拼音-笔画-英文。

Ctrl键+空格键:

按住输 Ctrl 键并按下空格键为转换输入法,在中文输入和英文输入之间转换。

中文输入状态下按下Car:

在中文输入状态下按下Car可出现标点符号的选择对话框。

↗+数字键中文选字:

在输入拼音或者笔画完成出现的中文字对话框时,选择第一个字可以直接用回车键选择,需要选择第二字至第六个字可按住↗+字左上角的对应数字来选择需要的字,当然也可以使用5向操纵杆选择需要的字。

注:回车键即为Car键正上方的键。

中文选择字区翻页:

在输入后出现的当前中文字对话框内如果没有需要的字,可以使用空格键进行翻页直到选到需要的字。

待机画面:
▲按住#键→可切换"标准"与"标准模式"(如要切换其它模式请轻按一下电源键)
▲按住P或M键→打开Web浏览
▲按住红色键→结束UMTS/GPRS连结(帮你节约联机费用)
▲按住菜单建→打开类似Windows XP的”工作管理员”窗口,可以迅速切换程序(此功能适用所有画面,不仅限于待机)*

■菜单画面:(不同韧体可能有异)
请注意到菜单排列恰好可以对应到蓝色数字键共12个(横的算起来有3列,纵的有4行)
▲左下方蓝色功能键+对应的蓝色数字键→选取并进入该程序(可以有效减少游戏杆使用)
■讯息画面:
▲Ctrl + C 复制
▲Ctrl + X 剪下
▲Ctrl + V 贴上
以上三项,若为中文韧体,可用”按住Chr键→带出剪贴画面”取代
▲Chr + 任意文字键→输入特殊字符(若是在注音模式下,会输入注音符号,不过无法和键盘上的符号一致,真是奇怪)
▲Ctrl + 游戏杆向下→下一页 ▲Ctrl + 游戏杆向上→上一页
▲Shift + 游戏杆左(右)→选取字符
▲Shift + Ctrl + 游戏杆左(右)→选取整组文字(word)
▲Ctrl + 游戏杆左(右)→移动光标至前后文字(word)
▲绿色通话键→立即寄出讯息
▲红色结束键→立即退出讯息编辑
▲Shift + 游戏杆向上(下)→欲选取多个讯息或邮件,功能类似windows xp中的档案总管

■行事历画面:
▲蓝色功能键+ * →切换月、周、日、待办事项检视画面
▲蓝色功能键+ # →切换回今日
■浏览器画面:
▲蓝色功能键+0 → 回到首页 ▲蓝色功能键+1 → 显示书签
▲蓝色功能键+2 → 显示文字搜寻对话框
▲蓝色功能键+3 → 回到前一网页检视
▲蓝色功能键+5 → 跳出网页选取窗口
▲蓝色功能键+8 → 切换显示全网页缩图
▲蓝色功能键+9 → 显示本网页url对话框
▲蓝色功能键+* → Zoom In
▲蓝色功能键+# →Zoom Out
■文件编辑画面:(文字编辑器)
▲Ctrl + B →黑体字
▲Ctrl + I →斜体字
▲Ctrl + U →底线
▲Ctrl + 游戏杆向下→跳到文件结尾
▲Ctrl + 游戏杆向上→跳到文件开头

■多媒体数据画面
▲1 →逆时针旋转
▲3 →顺时针旋转
▲* →切换窗口与全屏幕检视
▲2, 4, 6, 8 →平移,和游戏杆功能相同

■音乐播放机画面:
▲4 →跳至前一首歌曲
▲Hold 4 →快速回转歌曲(非常好用)
▲6 →跳至下一首歌曲诺基亚
▲Hold 6 →快速播放歌曲
▲5 →播放/暂停
▲8 →结束播放

■Real Player画面:
▲2 →切换全屏幕画面
▲ 游戏杆向上→快速播放影片
▲ 游戏杆向下→快速回转影片
■工程码(待机画面直接输入,不必按enter
▲*#0000# →显示韧体版本
▲*#06# →显示IMEI号码
▲*#2820# →显示蓝牙地址
▲*#62209526# →显示WLAN adapter的MAC地址
▲*#92702689# →显示通话定时器
▲*#7780# →soft resets并且reset手机设定
▲*#7370# →hard resets
若你指的是回复E61手机的初始值的话
1. 键入*#7370#
2. Default Password 是 “12345”
ps : Password 失败不要超过 3 次,否则手机会被lock

Shell Tips

#1 查找文件修改时间为某一段时间的文件:

touch -c 0901000007 file.start
touch file.end

find /local/Tomcat55/0/cluster/machine0/webapps/Pcclass -newer file.start ! -newer file.end > app_modified_since01Sep.txt -ls

find /jpmorgan/apps/pcclass -newer file.start ! -newer file.end > pcc_modified_since01Sep.txt -ls

#2 find records which dont contain “up to date” in the log.txt file to compile.log
cat log.txt | grep -v ‘up to date’ >> compile.log

#3 获取文件总行数
wc -l /jpmorgan/apps/pcclass/temp/1.txt | cut -c1-8
获取文件夹下文件个数:
ls /etc | wc -l

(see:http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+wc)

#4 文本替换
echo “a test” | tr t p
echo “a test” | tr aest 1234
echo “a test” | tr -d t
echo “a test” | tr ‘[:lower:]’ ‘[:upper:]’

#5 sed (Stream EDitor) 正则替换(pattern replacement)
(see:http://www.scit.wlv.ac.uk/cgi-bin/mansec?1+sed)
replace “one” with “another”, one occurrence:
echo “Replace one word” | sed -e s/one/another/

replace all the letter in “aeiouy” with “_” – g:
echo “This is a test” | sed -e s/[aeiouy]/_/g
Th_s _s _ t_st

#6 替换文件中的某个字符串
replace all “a” in 1.txt with “b”:
way 1:echo `sed ‘s/a/b/g’ 1.txt` > 2.txt
!!!-this will lose the line separator
way 2: use awk, better way, more flexible and programatical
awk ‘{
if($0==”aaa”) {print “bbb”}
else print $0
}’ 1.txt > 2.txt

#7 tail

分析日志时,把最后1000行输出到另一个文件.使用tail命令
tail -1000 Pcclassind.log > /tmp/dhanush.log
在控制台输出日志文件(文件更新会随时显示到控制台)
tail -f /local/Tomcat55/1/cluster/machine3/logs/catalina.out

#8 date time
Year=`date | cut -f 6 -d ” “`
month=`date | cut -f 2 -d ” “`
day=`date | cut -f 3 -d ” ” `

#9 查看文件夹所占空间
du -s foldername/
(http://www.computerhope.com/unix/udu.htm )

#10查看所有java进程
ps -ef | grep java