Month: August 2013

关于pipeline架构的几点说明

最近要将系统改造成pipeline架构,所以研究了一下pipeline相关的理论,并看了看servlet filter, struts2 interceptor, spring mvc interceptor, webx pipeline和netty pipeline的一些源码。 这里总结一些小点: 结构: 1. Pipeline的类模型由Pipeline, Valve 和 Context 组成。 Pipeline代表一个执行流,Valve代表执行流中的一个节点,Context是执行时的上下文信息,它一般由两部分组成: request/response + 当前流的执行状态。  2. 有的系统只能有一个Pipeline, 有的则允许配多个。 在struts2中,一种interceptor的组合,就代表了一个Pipeline;多种组合,意味着多个Pipeline. 用法: 1. 有的pipeline流是在同一层次上,每个valve处理的request/response对象基本上是同质的。比如servlet filter和各种mvc框架,所处理的事情都是web层的,所处理的context对象就是http request或框架自定义的javabean. 2. 有的pipeline流则是纵向的,从上层流到下层,或从下层流到上层,这时每个valve所处理的request/response对象一般是异构的。协议栈就是个典型的例子:下层valve处理字节流,上层Valve处理字符流。 不过,为了适应pipeline架构,这些异构的context对象必须有共同的基类,并且把这个基类作为各个valve的输入参数。 3. 从请求处理的角度来说, Pipeline可以代表整个执行流,也可以只用作请求被最终处理前的Interceptor.  Webx, netty中的Pipeline会将最后一个Valve作为请求处理者(一般称为Request Handler),而servlet filter和struts2 interceptor只作请求拦截、加工,真正的请求处理者则是servlet和action. 程序流: 1. 一个完整的Pipeline执行流一般是个环路: Valve1 => Valve2 => Valve3 => Valve2 => Valve1. 从拦截的角度说,valve既是前置拦截(下一个valve执行前),又是后置拉截(下一个 …

关于pipeline架构的几点说明 Read More »

对服务端推送(Server Push)比较好的解释

摘自: http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=2 Service streaming (streaming) allows a server to send a message to a client when an event occurs, without an explicit request from the client. In real-world implementations, the client initiates a connection to the server through a request, and the response returns bits and pieces each time a server-side event occurs; the response …

对服务端推送(Server Push)比较好的解释 Read More »

J2EE应用服务器版本选择

是否支持servlet 3.0?  是否必须用jdk 7? jetty: http://www.eclipse.org/jetty/documentation/current/what-jetty-version.html tomcat: http://tomcat.apache.org/whichversion.html

协议栈的建模问题:下层如何触发上层的执行?

在协议栈中,上层调用下层的操作很容易,直接做方法调用就可以了;那么下层如何调用上层呢? 大家都知道,下层不能依赖上层。 搜了一下,其中一个答案是 依赖注入 + 回调:     1. 做一个虚的Handler, 上层对象实现这个handler,并注入到本层对象中     2. 当本层做完自己的事后,调用handler.handleReceive(data)将数据抛给handler(实际是丢给上层对象)

普通Implicit Intent其实也是广播发送的

普通Implicit Intent跟Broadcast Intent一样,其实也是广播发送的;它没有指定这个Intent的消费者,任何一个注册相关兴趣的Activity都有可能成为它的消费者。 跟Broadcast Intent不同的是,普通Intent只能被一个activity消费;而Broadcast Intent可以被所有receiver都消费一次。

Spark & Openfire的认证流程

Spark的登录:LoginDialog.login()方法 1. 生成一个SessionManager 2. 生成一个XMPPConnection对象 3. 然后用XMPPConnection建立连接并初始化:生成socket,并建好它的reader/writer 4. 然后调用XMPPConnection.login()方法,为了简化,先把SASL抛一边,看看smack怎么用NonSASLAuthentication来做认证 5. 会对密码作digest,避免直接传password. 作digest时会用connectionId当盐 6. 发出认证请求,服务端返回用户名 7. 最后把服务端返回的用户名更新到connection.user中, 设置connection.authenticated = true, anonymous = false 再来看看spark如何使用身份信息,以 Roster.reload()为例(刷新好友列表) 1. packetWriter.sendPacket(packet)发出packet,packet里面不会掺杂用户身份信息。 2. 服务端收到消息后,其中一步是在ClientStanzaHandler.processMessage()中执行 packet.setFrom(session.getAddress()),把身份消息塞入Packet 引用 <iq id="psg6P-8" type="get" from="kent@someServer/Spark 2.6.3">   <query xmlns="jabber:iq:roster"/> </iq> 也就是说服务端直接把用户的身份信息放在服务端的mina session对象里,要用时再从session里把用户信息取出来

jdwp cheatsheet

Java5+: 引用 -agentlib:jdwp=transport=dt_socket,address=localhost:9009,server=y,suspend=y Java1.4- 引用 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=9009

Hacker News Android 客户端如何处理登录验证问题?

看代码研究了一下Hacker News Android 客户端如何处理登录验证问题。 登录流程 1. APP先用httpclient请求PC上的登录页面,拿到一堆html代码,然后从中解析中fnid, 应该是csrf token 2. 然后再把fnid, username, password 作为参数去POST PC上的登录form,服务端返回两个东西:   a. cookie: httpclient的cookieStore上会多一个cookie(key=user)   b. http response: 服务端返回一个字符串,称为userToken. 它的值其实就是上面说的cookie的值 3. 最后把userName和userToken存入Settings 登录后使用用户身份 使用用户身份时,会简单地把token当成cookie来用:把userToken从Settings中取出,构建好CookieStore, 然后塞到http client中,最后发出请求 API Apache HttpClient 及其Cookie API  +  Android SharedPreference 评价 这个方案实际上是以Cookie作为客户端和服务端交互语义的载体。好处是,服务端基本上只需写一套以cookie为核心的认证代码,就可以同时满足PC和APP的需要。

apk反编译:工具和注意事项

1. 先用apktools把apk本身解压;如果用7zip解压,会发现资源文件都是打不开的 2. 然后用dex2jar把*.dex变成*.jar,或者直接把*.apk变成*.jar 3. 最后用xjad打开jar里的class文件

慢慢积累:Android程序兼容性技巧

安装时获取用户授权APP做某种事:<uses-permission android:name="android.permission.CAMERA" /> 安装时指定硬件要求: <uses-feature android:name="android.hardware.camera" android:required="true/false" /> 运行时发送隐式Intent之前看看这个intent是否被支持. 关键API:  intent.resolveActivity(packageManager) == null ? ; 运行时确认硬件可用性:getPackageManager().hasSystemFeature(…); 运行时判断API Level:  if(android.os.Build.VERSION.SDK_INT > 14) …