- 浏览: 340588 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
奶油花生:
那如果我左侧菜单栏也是动态的呢,比如要读一个树形取出来的数据。 ...
使用Velocity吧2:Velocity的layout功能 -
fantaxy025025:
世隔近5年,我才看到了这么精彩的讨论。所谓,思想和眼光,相辅相 ...
是谁调用了它的静态方法? -
forrest_lv:
看了这个后,以此时刻提醒自己
说说我对编程的看法 -
bihujrj:
您好,我想在paoding上做一点改进。不知paoding有没 ...
Paoding Rest 0.2 Released -
fantaxy025025:
这个版主也不回答问题。。。呜呜
使用 庖丁分词(2.0.4-alpha)
不知道如何给本帖子取名,所以在标题出仅仅列出一些关键字。
本帖是工作成果之总结发贴,又由于太长,故有关心hessian/burlap/RCP如何在客户端和服务端之间默认传送参数,使服务器端的对象能够使用ThreadLocal获得当前远程请求者信息的同学 可以看看这个帖子,其它同学可以忽略之 否则看这这么长的贴可能会很受罪
背景
在远程调用框架方面,Spring现在能够良好集成Hessian/Burlap之类基于Http的RCP。 构建这样的程序基本步骤是这样的:
1,创建并配置POJO形式的服务对象,比如UserBo;
2、远程调用暴露器,比如Spring提供的Hessian暴露器,使成为web服务;
3、客户端(e.g.Swing-based)通过proxy,按照UserBo的接口调用远程服务
问题
区别于浏览器通过http访问Web服务器,浏览器能够支持它和服务器端cookie传送,
使本没有状态的http协议在web上能够提供有状态的服务,web容器因此可以通过标准的HttpSession保存登录信息等。
而这是一般使用Hessian之类的RCP难以做到的,如何模拟浏览器传送"cookie"成为头痛的问题。我一直为这件事烦恼着,做了这几个试验:
1、Hessian客户端能够保持服务器送过来的Cookie吗? 不能。试验过程如下:
1)做一个Filter过滤器,过滤Hessian远程调用
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
现在已经没办法通过HttpSession机制处理这个问题,那
1、如何确定每次从swing到server的hessian调用是登录后的调用,而不会被人模拟调用?
2、我如何知道每次调用的调用者是谁?
头脑风暴
头脑中一下子蹦出来的是:每个调用方法都加一个userId参数。
“搞定!”but极其ugly,想想,一般情况下,我不希望Bo提供的每一个方法都要求加一个UserId,我不会。
如果想要知道当前是由谁调用这个Bo类,在普通的web应用上,我采用的是Filter+ThreadLocal来做的,
这样只需在Bo方法里面调用提供ThreadLocal服务的全局共享对象来获取当前的请求者。
我不会在Bo中加入userId参数的,除非万不得已。。。继续苦思冥想....
是否能够改变Hessian客户端代理,使其能够读取http头信息,并在每次发送新请求时再把读取的cookie送到服务器?我想这是个不错的方案,但汗了一下,同上,也只要在“需求极其有必要+没有其它办法”条件下才去改变别人的底层结构。暂行搁置此方案。
有了,借助了“网络协议栈”提供的编程思想+AOP,我想到了一个方法,并在进行了试验性实践,证明可行了
因为可能也有人需要:《如何在hessian的环境下模拟session(会话)》, 或者可以用来参考拓展一下编程思路,所以我写这个总结。。。花费了我近2个小时,快晕死了
终极解决-思路
1、协议栈思想:
协议栈告诉我们下层协议总是“偷偷”的在上层协议内容之外再加上一些额外的,和本层协议有关的内容,发送到网络另外一端,同时另外那一端的对等协议,接收传输内容时,会剥离刚才加入的额外信息进行控制,并把剥离后的协议内容往上一层推。。。。
2、AOP理论:
拦截器,就像土匪,在你行走的路上,硬要对你进行盘问,满意则放人通过,不满意可以把你潜回;它可以偷袭你一些数据,也可能悄悄地加入他想要的行为、数据
3、协议栈思想 + AOP
客户端调用某个Bo的方法时,配置代理bean给他,这个代理bean同时也是拦截器,客户端调用Bo的每个方法都会被拦截,去调用一个底层接口(Delegate)。这个底层接口,能把你要调用的Bo名称,方法名,参数记起来,并加上每次你都需要传给服务器的参数传送到服务器。同时在服务器端,有一个这个底层接口个对应的服务对象(由DelegateImpl实现),该实现会把拦截器刚才记住的这些信息找出来:
取回拦截器刚才悄悄加入的信息(Attachments)记录在一个和ThreadLocal相关的类中(由Current实现);
取回你要调的Bo名称,从服务器applicationContext中找到这个对象
通过方法名和参数找到最终要调用的Method对象,最终调用method.invoke,实现对服务端Bo的调用。
哦, 6.0 已经归入官方类库了.
我原来是把 JDK 源码中 plugin 部分的 MemoryCookieHandler rip 过来用的, 附件为代码, 6.0 以前的 JVM 还可以用.
你的理解有错误,默认的Hessian Servlet实现是不创建session,而你的测试代码里面为什么会打出不同的session id,是因为这句话:
HttpSession session = req.getSession();
修改成
HttpSession session = req.getSession(false);
你就会发现问题的根源
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
你肯定实验错了,后面的一堆烦琐的解决方案先不看了,把你的测试代码放出来。
用Hessian解决Stateful的问题很简单,多加一个Filter,把session里面的用户标识读到就可以了。
你做过这个试验?我把我的试验代码和结果显示在下面了,你也列来看看,如果可以的话,那世界真的很美丽了(不过这是不可能的)
如果不是的话,所谓的繁琐,难度较大的也都在封转底层代码中了,外面的编程可简单多了(=Filter+ThreadLocal的代码量)
web.xml配置片段
Filter Session id打印代码
同一个客户端连续请求2次的打印结果:
--------------session id-------------------------
EC901AF3E6C895925B2DB007EBC1F833
--------------session id-------------------------
712C18CA3D926013613FBABCD2925560
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
你肯定实验错了,后面的一堆烦琐的解决方案先不看了,把你的测试代码放出来。
用Hessian解决Stateful的问题很简单,多加一个Filter,把session里面的用户标识读到就可以了。
本帖是工作成果之总结发贴,又由于太长,故有关心hessian/burlap/RCP如何在客户端和服务端之间默认传送参数,使服务器端的对象能够使用ThreadLocal获得当前远程请求者信息的同学 可以看看这个帖子,其它同学可以忽略之 否则看这这么长的贴可能会很受罪
背景
在远程调用框架方面,Spring现在能够良好集成Hessian/Burlap之类基于Http的RCP。 构建这样的程序基本步骤是这样的:
1,创建并配置POJO形式的服务对象,比如UserBo;
2、远程调用暴露器,比如Spring提供的Hessian暴露器,使成为web服务;
3、客户端(e.g.Swing-based)通过proxy,按照UserBo的接口调用远程服务
问题
区别于浏览器通过http访问Web服务器,浏览器能够支持它和服务器端cookie传送,
使本没有状态的http协议在web上能够提供有状态的服务,web容器因此可以通过标准的HttpSession保存登录信息等。
而这是一般使用Hessian之类的RCP难以做到的,如何模拟浏览器传送"cookie"成为头痛的问题。我一直为这件事烦恼着,做了这几个试验:
1、Hessian客户端能够保持服务器送过来的Cookie吗? 不能。试验过程如下:
1)做一个Filter过滤器,过滤Hessian远程调用
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
现在已经没办法通过HttpSession机制处理这个问题,那
1、如何确定每次从swing到server的hessian调用是登录后的调用,而不会被人模拟调用?
2、我如何知道每次调用的调用者是谁?
头脑风暴
头脑中一下子蹦出来的是:每个调用方法都加一个userId参数。
“搞定!”but极其ugly,想想,一般情况下,我不希望Bo提供的每一个方法都要求加一个UserId,我不会。
如果想要知道当前是由谁调用这个Bo类,在普通的web应用上,我采用的是Filter+ThreadLocal来做的,
这样只需在Bo方法里面调用提供ThreadLocal服务的全局共享对象来获取当前的请求者。
我不会在Bo中加入userId参数的,除非万不得已。。。继续苦思冥想....
是否能够改变Hessian客户端代理,使其能够读取http头信息,并在每次发送新请求时再把读取的cookie送到服务器?我想这是个不错的方案,但汗了一下,同上,也只要在“需求极其有必要+没有其它办法”条件下才去改变别人的底层结构。暂行搁置此方案。
有了,借助了“网络协议栈”提供的编程思想+AOP,我想到了一个方法,并在进行了试验性实践,证明可行了
因为可能也有人需要:《如何在hessian的环境下模拟session(会话)》, 或者可以用来参考拓展一下编程思路,所以我写这个总结。。。花费了我近2个小时,快晕死了
终极解决-思路
1、协议栈思想:
协议栈告诉我们下层协议总是“偷偷”的在上层协议内容之外再加上一些额外的,和本层协议有关的内容,发送到网络另外一端,同时另外那一端的对等协议,接收传输内容时,会剥离刚才加入的额外信息进行控制,并把剥离后的协议内容往上一层推。。。。
2、AOP理论:
拦截器,就像土匪,在你行走的路上,硬要对你进行盘问,满意则放人通过,不满意可以把你潜回;它可以偷袭你一些数据,也可能悄悄地加入他想要的行为、数据
3、协议栈思想 + AOP
客户端调用某个Bo的方法时,配置代理bean给他,这个代理bean同时也是拦截器,客户端调用Bo的每个方法都会被拦截,去调用一个底层接口(Delegate)。这个底层接口,能把你要调用的Bo名称,方法名,参数记起来,并加上每次你都需要传给服务器的参数传送到服务器。同时在服务器端,有一个这个底层接口个对应的服务对象(由DelegateImpl实现),该实现会把拦截器刚才记住的这些信息找出来:
取回拦截器刚才悄悄加入的信息(Attachments)记录在一个和ThreadLocal相关的类中(由Current实现);
取回你要调的Bo名称,从服务器applicationContext中找到这个对象
通过方法名和参数找到最终要调用的Method对象,最终调用method.invoke,实现对服务端Bo的调用。
评论
17 楼
歆渊
2007-08-07
gwbasic 写道
Java 6.0HttpUrlConnection已经支持Cookie了
哦, 6.0 已经归入官方类库了.
我原来是把 JDK 源码中 plugin 部分的 MemoryCookieHandler rip 过来用的, 附件为代码, 6.0 以前的 JVM 还可以用.
16 楼
gwbasic
2007-06-13
Java 6.0HttpUrlConnection已经支持Cookie了
public static void main(String[] args) { CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL)); HessianProxyFactory factory = new HessianProxyFactory(); try { TestService testService = (TestService) factory.create(TestService.class, "http://127.0.0.1:8080/hessian/remoting/TestService"); System.out.println(testService.getSessionId("您好.")); System.out.println(testService.getSessionId("您好.")); testService = (TestService) factory.create(TestService.class, "http://127.0.0.1:8080/hessian/remoting/TestService"); System.out.println(testService.getSessionId("您好.")); System.out.println(testService.getSessionId("您好.")); } catch (MalformedURLException e) { e.printStackTrace(); } }
15 楼
dovecat
2007-05-24
好长...
14 楼
Qieqie
2007-05-24
good!
你的代码给了另外一个不错的思路了,关键是你提供的下面这个代码,我可以进行扩展,动态塞入一些附带想要传给服务器的数据,然后做Filter从Http Header取出来放到ThreadLocal
(我还是免不了要N些封装类,使这些代码对编程透明,以及支持Spring配置。。。)
考虑一下,是否可以扩展Hessian使能够读取服务器传过来的HttpHeader数据,从而把session的cookie读出来? 如果可以的话,那HttpSession就可以使用了!
补充:很高兴看到readonly的代码!
你的代码给了另外一个不错的思路了,关键是你提供的下面这个代码,我可以进行扩展,动态塞入一些附带想要传给服务器的数据,然后做Filter从Http Header取出来放到ThreadLocal
(我还是免不了要N些封装类,使这些代码对编程透明,以及支持Spring配置。。。)
考虑一下,是否可以扩展Hessian使能够读取服务器传过来的HttpHeader数据,从而把session的cookie读出来? 如果可以的话,那HttpSession就可以使用了!
补充:很高兴看到readonly的代码!
public class IdentityHessianProxyFactory extends HessianProxyFactory { public static final String IDENTITY_KEY = "_hessian_client_"; private String clientId; public IdentityHessianProxyFactory(String clientId) { super(); this.clientId = clientId; } protected URLConnection openConnection(URL url) throws IOException { URLConnection conn = super.openConnection(url); conn.setRequestProperty(IDENTITY_KEY, clientId); return conn; } }
13 楼
Readonly
2007-05-24
唉,咋就不理解偶的意思呢?不多说了,看附件的代码,附件没有考虑多线程问题,你用filter取代掉BasicServiceImpl里面service这一块代码,把取得的用户标识放到ThreadLocal就可以了。5行代码就可以搞定的事情,还弄这么麻烦....
12 楼
Qieqie
2007-05-24
大部分没必要,有时有必要。
其实在我的帖子里面,倒没有一定是statefull,只是记录信息到ThreadLocal(即Current类中)。也就是我最想解决的是能够支持在Bo里面通过ThreadLocal的机制知道当前的请求者,这有可能有好处(有时候这种好处可能不小,比如控制安全,判断权限,记录访问日志等等)
其实在我的帖子里面,倒没有一定是statefull,只是记录信息到ThreadLocal(即Current类中)。也就是我最想解决的是能够支持在Bo里面通过ThreadLocal的机制知道当前的请求者,这有可能有好处(有时候这种好处可能不小,比如控制安全,判断权限,记录访问日志等等)
11 楼
max.h.chen
2007-05-24
为什么需要stateful hessian?RPC要的就是stateless,难道hessian客户端连自己的状态都管理不了吗?不会瘦到这种程度吧!
10 楼
Qieqie
2007-05-24
HttpSession session = req.getSession(false);
表示如果当前有Session则返回,没有的话就返回null,
每次都返回null,做不到Statefull.
HttpSession session = req.getSession(); 等价于HttpSession session = req.getSession(true);
如果当前会话已经存在,则返回该会话,没有的话创建一个-->这是我们需要的恶
表示如果当前有Session则返回,没有的话就返回null,
每次都返回null,做不到Statefull.
HttpSession session = req.getSession(); 等价于HttpSession session = req.getSession(true);
如果当前会话已经存在,则返回该会话,没有的话创建一个-->这是我们需要的恶
9 楼
Readonly
2007-05-24
剑精or风怒了,编辑掉
8 楼
Readonly
2007-05-24
Qieqie 写道
是因为cookie没办法被hessian客户读取记录导致的http session没办法使用。
因为创建http session对hessian没有意义,也就不需要去一直获取,也就没有因为session导致大负荷量负载下Session狂暴的问题
你也试验下告诉下结果,免得就我一个环境实验,可能存在偏差
因为创建http session对hessian没有意义,也就不需要去一直获取,也就没有因为session导致大负荷量负载下Session狂暴的问题
你也试验下告诉下结果,免得就我一个环境实验,可能存在偏差
你的理解有错误,默认的Hessian Servlet实现是不创建session,而你的测试代码里面为什么会打出不同的session id,是因为这句话:
HttpSession session = req.getSession();
修改成
HttpSession session = req.getSession(false);
你就会发现问题的根源
7 楼
Qieqie
2007-05-24
是因为cookie没办法被hessian客户读取记录导致的http session没办法使用。
因为创建http session对hessian没有意义,也就不需要去一直获取,也就没有因为session导致大负荷量负载下Session狂暴的问题
你也试验下告诉下结果,免得就我一个环境实验,可能存在偏差
因为创建http session对hessian没有意义,也就不需要去一直获取,也就没有因为session导致大负荷量负载下Session狂暴的问题
你也试验下告诉下结果,免得就我一个环境实验,可能存在偏差
<?xml version="1.0" encoding="UTF-8"?> <web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/applicationContext*.xml </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>remoting</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup /> </servlet> <servlet-mapping> <servlet-name>remoting</servlet-name> <url-pattern>/remoting/*</url-pattern> </servlet-mapping> <filter> <filter-name>TestFilter</filter-name> <filter-class> com.xxx.TestFilter </filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/remoting/*</url-pattern> </filter-mapping> </web-app>
6 楼
Readonly
2007-05-24
你的web.xml不完整,附上完整的看看
Hessian不可能愚蠢到每次请求都创建一个新的session,这样在高压力负载下的生产环境,application server马上就会被几十万个active session弄趴下了。
Hessian不可能愚蠢到每次请求都创建一个新的session,这样在高压力负载下的生产环境,application server马上就会被几十万个active session弄趴下了。
5 楼
Qieqie
2007-05-24
Readonly 写道
Qieqie 写道
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
你肯定实验错了,后面的一堆烦琐的解决方案先不看了,把你的测试代码放出来。
用Hessian解决Stateful的问题很简单,多加一个Filter,把session里面的用户标识读到就可以了。
你做过这个试验?我把我的试验代码和结果显示在下面了,你也列来看看,如果可以的话,那世界真的很美丽了(不过这是不可能的)
如果不是的话,所谓的繁琐,难度较大的也都在封转底层代码中了,外面的编程可简单多了(=Filter+ThreadLocal的代码量)
web.xml配置片段
<filter> <filter-name>TestFilter</filter-name> <filter-class> com.xxx.TestFilter </filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/remoting/*</url-pattern> </filter-mapping>
Filter Session id打印代码
public class TestFilter implements Filter { public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) arg0; HttpSession session = req.getSession(); System.out.println("--------------session id-------------------------"); System.out.println(session.getId()); arg2.doFilter(arg0, arg1); } public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } }
同一个客户端连续请求2次的打印结果:
--------------session id-------------------------
EC901AF3E6C895925B2DB007EBC1F833
--------------session id-------------------------
712C18CA3D926013613FBABCD2925560
4 楼
huangpengxiao
2007-05-24
通宵?
3 楼
Readonly
2007-05-24
Qieqie 写道
2)获取request.getSession(),打印sessionId
通过打印,看出每一次调用打印的sessionId都不一样,所以试图直接使用HttpSession保持会话是不行的。
你肯定实验错了,后面的一堆烦琐的解决方案先不看了,把你的测试代码放出来。
用Hessian解决Stateful的问题很简单,多加一个Filter,把session里面的用户标识读到就可以了。
2 楼
Qieqie
2007-05-24
终极解决-底层架构代码展示
1、Current代码
2、Deletegate接口
3、DelegateImpl代码
4、RemoteProxyBean代码
5、Attachments接口
6、SimpleAttachments
1、Current代码
public abstract class Current { private static final ThreadLocal<Object[]> data = new ThreadLocal<Object[]>(); public static void setAttachemnts(Object[] attachments) { data.set(attachments); } public static Object[] getAttachments() { return data.get(); } }
2、Deletegate接口
public interface Delegate { public Object call(String targetBeanName, String methodName, Object[] args, Object[] attachments); }
3、DelegateImpl代码
public class DelegateImpl implements Delegate, ApplicationContextAware { // Spring上下文 private ApplicationContext applicationContext; // 缓存从applicationContext得到的bean private Map<String, Object> beans = new HashMap<String, Object>(); private static final Log log = LogFactory.getLog(Delegate.class); public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public ApplicationContext getApplicationContext() { return applicationContext; } public Object call(String serviceBeanName, String methodName, Object[] args, Object[] attachments) { if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder(); sb.append("-------------------------------call delegate for ") .append(serviceBeanName).append('.').append(methodName) .append("\n attchments: "); for (Object a : attachments) { sb.append(a).append(", "); } sb.setLength(sb.length() - 2); log.debug(sb.toString()); } if (attachments != null) { Current.setAttachemnts(attachments);//!!这里把attachments设置到Current } Object bo = getBean(serviceBeanName); Class<?>[] argClasses = new Class[args.length]; for (int i = 0; i < argClasses.length; i++) { argClasses[i] = args[i].getClass(); } Method method = null; try { method = bo.getClass().getMethod(methodName, argClasses); } catch (Exception e) { throw new InvocationFailureException(e.getMessage(), e); } if (log.isDebugEnabled()) { log.debug("found method named '" + methodName + "' of bean " + serviceBeanName); } Object ret = null; try { ret = method.invoke(bo, args); } catch (IllegalArgumentException e) { throw new InvocationFailureException(e.getMessage(), e); } catch (IllegalAccessException e) { throw new InvocationFailureException(e.getMessage(), e); } catch (InvocationTargetException e) { throw new InvocationFailureException(e.getMessage(), e); } if (log.isDebugEnabled()) { log.debug("successfully completed invocation for " + serviceBeanName + '.' + methodName); } return ret; } protected Object getBean(String serviceBeanName) { Object bean = beans.get(serviceBeanName); if (bean == null) { bean = applicationContext.getBean(serviceBeanName); beans.put(serviceBeanName, bean); } return bean; } }
4、RemoteProxyBean代码
public class RemoteProxyBean implements MethodInterceptor, InitializingBean, FactoryBean, ApplicationContextAware { // 业务对象接口,比如com.xxx.bo.UserBo private Class serviceInterface; // 业务对象在服务器中的名称,比如userBo,由本类从applicationContext自动读入(配置本类的bean标识) private String serviceBeanName; // 暴露给客户端使用的代理对象,以serviceInterface的名义 private Object serviceProxy; // 服务端暴露的远程代理接口 private Delegate delegate; // Spring上下文 private ApplicationContext applicationContext; // 附加信息来源 private Attachments attachments; //attachments,delegate,applicationContext,serviceInterface getter/setters here public Object getObject() throws Exception { return this.serviceProxy; } public Class getObjectType() { return getServiceInterface(); } public boolean isSingleton() { return true; } public void afterPropertiesSet() { readServiceBeanName(); this.serviceProxy = ProxyFactory.getProxy(getServiceInterface(), this); } protected void readServiceBeanName() { String[] names = applicationContext .getBeanNamesForType(RemoteProxyBean.class); for (String name : names) { Object maybe = applicationContext.getBean(name); if (maybe == this) { this.serviceBeanName = name; break; } } if (this.serviceBeanName == null) { throw new IllegalArgumentException(); } //Spring会对FacotryBean的名称前面将&,我们要把它去掉 int index = this.serviceBeanName.indexOf('&'); this.serviceBeanName = this.serviceBeanName.substring(index + 1); } public Object invoke(MethodInvocation invocation) throws Throwable { Object [] attachments = null; if (this.attachments != null) { attachments = this.attachments.get(); } return delegate.call(serviceBeanName, invocation.getMethod().getName(), invocation.getArguments(), attachments); } }
5、Attachments接口
public interface Attachments { public Object[] get(); }
6、SimpleAttachments
/** * 最简单的实现,用于单用户的客户端。 * 多用户的客户端,应该另外实现。 * * @author zhiliang.wang * */ public class SimpleAttachments implements Attachments { private Object[] values; public Object[] get() { return values; } public void set(Object[] values) { this.values = values; } }
1 楼
Qieqie
2007-05-24
终极解决 - 编程代码展示
1、UserBo(仅为示例用,没有考虑接口设计是否完全合理):
2、客户端登录代码
3、客户端修改资料代码
4、客户端applicationContext.xml片段
5、服务端UserBo实现
6、服务端remoting-servlet.xml配置片段
7、服务端applicationContext-bo.xml配置片段
<bean id="userBo" class="xxx.UserBoImpl" autowire="byName"/>
1、UserBo(仅为示例用,没有考虑接口设计是否完全合理):
public interface UserBo { public User login(String name, String password); public void updateProfile(String signature); }
2、客户端登录代码
User user = userBo.login("wang", "xxxxxx"); SimpleAttachments attachments = (SimpleAttachments )getBean("attachments");//SimpleAttachments 是这个方案中的一个接口,只有一对get/set方法;getBean指的是从client端的applicationContext.xml读 attachments.set(new Object[]{user.getId(), user.getToken(), user.getLastLoginTime()});
3、客户端修改资料代码
userBo.updateProfile("签名是用来做什么的,有什么意义?");
4、客户端applicationContext.xml片段
<bean id="remoteProxyBean" abstract="true" class="xxx.RemoteProxyBean"> <property name="delegate"> <bean class="org.springframework.remoting.caucho.HessianProxyFactoryBean"> <property name="serviceUrl" value="${remoting}delegate" /> <property name="serviceInterface" value="xxx.Delegate" /> </bean> </property> <property name="attachments" ref="attachments"></property> </bean> <bean id="attachments" class = "xxx.SimpleAttachements"> </bean> <bean id="userBo" parent="remoteProxyBean"> <property name="serviceInterface" value="xxx.UserBoImpl" /> </bean>
5、服务端UserBo实现
public User login(String name, String password){ User user = userDao.getByName(name); if (user != null && user.getPassword().equals(password)) { user.setLastLoginTime(new Date()); user.setToken("随机生成的类似session id的一个字符串,和userId,当前时间有关"); return user; } return null; } public void updateProfile(String signature) { Object[] attachements = Current.getAttachements();//注意这个Current类 //attachements==null的情况,我们可以通过配置AOP拦截掉,使这里的attachements不会为null Long userId = attachements[0]; //attachements不合法,比如Token被恶意改写的情况,同样可以配置AOP或Filter在调用本方法之前就验证了,这里我们就认为是合法的便可以 User user = userDao.getById(userId); user.setSignature(signature); }
6、服务端remoting-servlet.xml配置片段
<bean name="/delegate" class="org.springframework.remoting.caucho.HessianServiceExporter"> <property name="service" ref="delegate" /> <property name="serviceInterface" value="xxx.Delegate" /> </bean> <bean name="delegate" class="xxx.DelegateImpl" />
7、服务端applicationContext-bo.xml配置片段
<bean id="userBo" class="xxx.UserBoImpl" autowire="byName"/>
相关推荐
Spring AOP和Hessian是两个在Java开发中广泛使用的技术,尤其在分布式系统和服务治理中。下面将详细解释这两个概念以及它们如何结合使用。 **Spring AOP(面向切面编程)** Spring AOP是Spring框架的一个重要组成...
**Hessian:深入理解与应用** ...总的来说,Hessian是一个实用的、轻量级的RPC协议,尤其适合对性能有较高要求且希望简化通信复杂性的场景。通过理解和掌握Hessian,开发者可以更有效地构建和优化分布式系统。
当Hessian与Spring框架结合时,步骤稍有不同: 1. **依赖和接口**:同样需要引入Hessian库,并定义服务接口。但此时,接口的实现可以是普通的Plain Old Java Objects (POJOs)。 2. **Spring配置**:在服务端的...
Hessian 是一种二进制的 RPC 协议,由 Caucho 公司开发,其特点是小巧、快速、无状态。Hessian 支持 Java、C++、Python 等多种语言,使得跨语言的服务调用成为可能。Hessian 的优点在于它能够自动序列化和反序列化...
3. **Python中的Hessian**:Python也有对应的Hessian库,如`pyhessian`,它实现了Hessian协议,使得Python应用能够与Java Hessian服务进行通信。同样,服务端可以通过定义Python函数并包装为Hessian服务,客户端则...
这个压缩包包含了Hessian的多个版本,分别是Hessian3.1.6、Hessian3.2.1以及Hessian4.0.7。每个版本都有其特定的功能改进和优化,了解这些版本的区别和适用场景对于开发者来说至关重要。 Hessian3.1.6是Hessian的一...
4. **跨语言支持**:虽然最初是为Java设计的,但Hessian也有其他语言的实现,比如Python、C++、C#等,因此可以在多种语言之间进行通信。 在【描述】中提到的博客链接,可能详细介绍了如何使用Hessian进行客户端和...
在图像处理领域,多尺度Hessian滤波器是一种高级的图像增强技术,它主要用于检测图像中的线性结构,特别是对于微弱或者噪声较大的图像特征有很好的识别能力。这个技术是基于数学形态学的Hessian矩阵理论,由V.S. ...
而Spring框架是Java领域中广泛使用的依赖注入(DI)和面向切面编程(AOP)的工具,它极大地简化了企业级应用的开发和维护。 当我们谈论“Hessian与Spring整合”时,通常是指将Hessian作为服务通信的机制,结合...
这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一种高效、轻量级的二进制序列化协议,特别适合于跨语言的网络通信。理解并掌握Hessian的基本概念和使用方法,能够...
在IT领域,尤其是在医学图像分析中,Hessian矩阵是一个重要的数学工具,用于图像特征检测,特别是在血管分割的应用中。本文将深入探讨标题和描述中提到的"基于Hessian矩阵增强的心血管分割"这一主题。 Hessian矩阵...
用户只需按照说明运行这些文件,就可以快速体验Hessian的通信过程,这对于学习和测试Hessian协议非常有帮助。 Hessian的优势在于它的二进制编码,相比于基于文本的协议(如JSON或XML),它能显著减少网络传输的数据...
《Hessian应用详解》 Hessian,一种轻量级的二进制协议,因其高效、简单的特点,在分布式服务中被广泛应用。它允许开发者在HTTP上透明地调用远程方法,就像是本地方法调用一样,极大地提高了开发效率和系统性能。...
- 在实际开发中,我们可能会需要编写一些辅助工具类来处理Hessian的相关操作,例如Hessian2Input和Hessian2Output,它们用于读写Hessian序列化的二进制流。 6. **安全性与优化**: - 虽然Hessian协议效率高,但其...
对Hessian服务的监控和日志记录是必要的,可以帮助开发者了解服务运行状态,快速定位和解决问题。可以使用各种监控工具,如JMX、Prometheus或ELK栈等。 10. **测试**: 在实际部署前,需要对Hessian服务进行充分...
在IT行业中,Hessian是一种高效的二进制RPC(Remote Procedure Call)协议,它允许Java应用程序之间进行远程调用,就像调用本地方法一样便捷。Hessian由Caucho公司开发,其目标是提供轻量级、快速且简洁的通信方式。...
总的来说,Hessian提供了高效、轻量级的跨语言通信解决方案,尤其适合对性能有较高要求的场景。通过学习和实践这个Hessian demo,你将能够更好地应对涉及远程调用和数据交换的问题。无论是Java开发者还是C++开发者,...
标题中的“spring整合hessian进行远程通讯”是指在Spring框架中使用Hessian库来实现远程过程调用(RPC)。这是一个常见的技术组合,用于构建分布式系统,使得应用组件之间可以跨网络进行高效通信。 Hessian是一种二...
在IT行业中,Hessian是一种高效的远程方法调用(Remote Method Invocation, RMI)协议,它由Caucho Technology开发。Hessian提供了一种二进制的序列化格式,使得网络通信更加高效,减少了数据传输量。它支持Java、...
在IT行业中,Spring框架是Java领域最常用的轻量级应用框架之一,而Hessian则是一种高效的RPC(远程过程调用)协议,它允许服务提供者和消费者之间进行二进制远程方法调用。本案例主要关注如何将Spring与Hessian进行...