同在一个产业链园区的XX厂因为5台Window2003服务器收到了律师函并且被迫下了12万$的采购单,虽然100万对XXX厂来数不是大数目,但是总有种被打劫的感觉。

在企业ERP应用中服务层一般都是做成远程调用的,具体Windows平台的技术有WebService,WCF,Remoting等,这里展示的是服务端采用linux 平台下采用Hessian组件实现RPC.

服务端:
Web服务器:JBoss,tomcat (weblogic挺美但是不免费啊)
数据库:mysql(一般erp都用oracle做数据库,当然那个啥费用也是不含糊地)
客户端:
逆天的XP(sp3) 加.net4.0 (NND,这个组合量你也收不了多少钱把!)
VS2010? 我们用180试用版或者那啥notepad

Hessian+spring配置
1.web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  3. <display-name>HessianTest</display-name>
  4. <context-param>
  5. <param-name>contextConfigLocation</param-name>
  6. <param-value>classpath*:conf/ht-core.xml</param-value>
  7. </context-param>
  8. <listener>
  9. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  10. </listener>
  11. <servlet>
  12. <servlet-name>hessionRpc</servlet-name>
  13. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  14. <init-param>
  15. <param-name>contextConfigLocation</param-name>
  16. <param-value>classpath*:conf/ht-rpc.xml</param-value>
  17. </init-param>
  18. <load-on-startup></load-on-startup>
  19. </servlet>
  20. <servlet-mapping>
  21. <servlet-name>hessionRpc</servlet-name>
  22. <url-pattern>/rpc/*</url-pattern>
  23. </servlet-mapping>
  24.  
  25. <servlet>
  26. <description></description>
  27. <display-name>TestSpring</display-name>
  28. <servlet-name>TestSpring</servlet-name>
  29. <servlet-class>f.studio.web.servlet.TestSpring</servlet-class>
  30. </servlet>
  31. <servlet-mapping>
  32. <servlet-name>TestSpring</servlet-name>
  33. <url-pattern>/TestSpring</url-pattern>
  34. </servlet-mapping>
  35. <filter>
  36. <display-name>HessianCtxFilter</display-name>
  37. <filter-name>HessianCtxFilter</filter-name>
  38. <filter-class>f.studio.web.filter.HessianCtxFilter</filter-class>
  39. </filter>
  40. <filter-mapping>
  41. <filter-name>HessianCtxFilter</filter-name>
  42. <url-pattern>/rpc/*</url-pattern>
  43. </filter-mapping>
  44.  
  45. <welcome-file-list>
  46. <welcome-file>index.html</welcome-file>
  47. <welcome-file>index.htm</welcome-file>
  48. <welcome-file>index.jsp</welcome-file>
  49. <welcome-file>default.html</welcome-file>
  50. <welcome-file>default.htm</welcome-file>
  51. <welcome-file>default.jsp</welcome-file>
  52. </welcome-file-list>
  53. </web-app>

2.Service,DAO等spring配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  5.  
  6. <bean name="studentServiceImpl"
  7. class="f.studio.service.impl.StudentServiceImpl" scope="prototype" />
  8. </beans>

3.Hessian导出层spring配置,因为一个项目里可能使用strut2,Servlet,cxf等服务提供层,但是他们需要共用Service,DAO等
参考:http://jinnianshilongnian.iteye.com/blog/1602617

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  9.  
  10. <bean name="/studentServiceRpc"
  11. class="org.springframework.remoting.caucho.HessianServiceExporter">
  12. <property name="service" ref="studentServiceImpl" />
  13. <property name="serviceInterface" value="f.studio.service.StudentService" />
  14. </bean>
  15.  
  16. </beans>

用户登陆状态问题
Hessian的C#实现可以自己保存cookie,并且是全局的(应用程序范围)
服务端尝试使用Hessian提供的ServiceContext获取对Session的引用但是结果总为null,所以写个filter 来自己维护用户登陆Session供Service实现类使用

  1. package f.studio.web.filter;
  2.  
  3. import java.io.IOException;
  4. import javax.servlet.Filter;
  5. import javax.servlet.FilterChain;
  6. import javax.servlet.FilterConfig;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpSession;
  12.  
  13. import f.studio.util.HessianCtxContainer;
  14.  
  15. /**
  16. * Servlet Filter implementation class HessianCtxFilter
  17. */
  18. public class HessianCtxFilter implements Filter {
  19.  
  20. public static final String LOGIN_SESSION_KEY="LOGIN_USER_KEY";
  21. /**
  22. * Default constructor.
  23. */
  24. public HessianCtxFilter() {
  25. // TODO Auto-generated constructor stub
  26. }
  27.  
  28. /**
  29. * @see Filter#destroy()
  30. */
  31. public void destroy() {
  32. // TODO Auto-generated method stub
  33. }
  34.  
  35. /**
  36. * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
  37. */
  38. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  39.  
  40. HttpSession session = ((HttpServletRequest) request).getSession(true);
  41. System.out.println("sessionId:" + session.getId());
  42. try {
  43.  
  44. Object user = session.getAttribute(LOGIN_SESSION_KEY);
  45. HessianCtxContainer.setAttribute(LOGIN_SESSION_KEY, user);
  46. System.out.println("sessionUser:" + user);
  47. chain.doFilter(request, response);
  48.  
  49. } finally {
  50. //移除掉ThreadLocal中Map中的对象防止益出
  51. //session具备自动移动除功能
  52. //不要在环境下(cxf,strut2等)使用HessionCtxContainer,避免线程重用时造成混乱
  53. Object user = HessianCtxContainer.remove(LOGIN_SESSION_KEY);
  54. session.setAttribute(LOGIN_SESSION_KEY, user);
  55. }
  56.  
  57. }
  58.  
  59. /**
  60. * @see Filter#init(FilterConfig)
  61. */
  62. public void init(FilterConfig fConfig) throws ServletException {
  63. // TODO Auto-generated method stub
  64. }
  65.  
  66. }

服务实现类:

  1. package f.studio.service.impl;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Date;
  5. import java.util.List;
  6.  
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpSession;
  10.  
  11. import org.omg.PortableInterceptor.USER_EXCEPTION;
  12.  
  13. import com.caucho.hessian.io.Hessian2Output;
  14. import com.caucho.services.server.ServiceContext;
  15.  
  16. import f.studio.domain.Klass;
  17. import f.studio.domain.QueryStudentInfo;
  18. import f.studio.domain.StudentInfo;
  19. import f.studio.service.StudentService;
  20. import f.studio.util.HessianCtxContainer;
  21. import f.studio.web.filter.HessianCtxFilter;
  22.  
  23. public class StudentServiceImpl implements StudentService {
  24.  
  25. public List<StudentInfo> query(QueryStudentInfo q) {
  26.  
  27. CheckLogin();
  28.  
  29. ServletRequest request= ServiceContext.getContextRequest();
  30. System.out.println(ServiceContext.getServiceName());
  31. //HttpSession session= request.getSession(true);
  32. //session.setAttribute("User", new Date());
  33.  
  34. System.out.println("ServiceImpHashCode:" + this.hashCode());
  35. System.out.println(q);
  36. //if(1==1)throw new RuntimeException("运行错误信息啊");
  37. List<StudentInfo> list=new ArrayList<StudentInfo>();
  38. Klass klass=new Klass();
  39. klass.setId(9999);
  40. klass.setName("张老师");
  41. klass.setAddTime(new Date());
  42.  
  43. for(int i=0;i<10;i++){
  44. StudentInfo s=new StudentInfo();
  45.  
  46. //===父类
  47. s.setRecId(88888);
  48. s.setCreateDate(new Date());
  49. //==
  50. s.setId(i);
  51. s.setName("张思念" + i);
  52. s.setSex(i % 5 ==0);
  53. //===添加两个元素==
  54. s.getKs().add(klass);
  55. s.getKs().add(klass);
  56.  
  57. list.add(s);
  58. }
  59. return list;
  60. }
  61.  
  62. public String hello(String name) {
  63. return "Hi " +name;
  64. }
  65.  
  66. public void Login(String username, String password) {
  67. if("Admin".equals(username) && "123".equals(password)){
  68. HessianCtxContainer.setAttribute(HessianCtxFilter.LOGIN_SESSION_KEY , username);
  69. return;
  70. }
  71. throw new RuntimeException("错误的用户名或密码!");
  72. }
  73.  
  74. public static void CheckLogin(){
  75.  
  76. if(HessianCtxContainer.getAttribute(HessianCtxFilter.LOGIN_SESSION_KEY)==null){
  77. throw new RuntimeException("未登录或登录超时!");
  78. }
  79. }
  80. }

.net客户端,需要添加对hessianCsharp.dll的引用
调用一次Login后,再执行其他调用

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using hessiancsharp.client;
  10.  
  11. namespace HessianTest
  12. {
  13. using f.studio.domain;
  14. using System.Threading;
  15. public partial class Form1 : Form
  16. {
  17. public Form1()
  18. {
  19. InitializeComponent();
  20. }
  21.  
  22. private void button1_Click(object sender, EventArgs e)
  23. {
  24. try
  25. {
  26. CHessianProxyFactory factory = new CHessianProxyFactory("userName", "password");
  27. string url = "http://localhost/HessianTest/rpc/studentServiceRpc";//修改为你的server端地址
  28. StudentService test = (StudentService)factory.Create(typeof(StudentService), url);
  29. string result = test.hello("大白鲨");
  30. var q = new QueryStudentInfo() { BTime = DateTime.Now, Name = "哈哈", Id = , Sex = false };
  31. q.Data = new byte[] { , , , , };
  32. q.CreateDate = DateTime.Now;
  33. q.RecId = ;
  34.  
  35. var list = test.query(q);
  36. foreach (var it in list)
  37. {
  38. Console.WriteLine(it);
  39. }
  40. Console.WriteLine(result);
  41. }
  42. catch (Exception ex)
  43. {
  44. Console.WriteLine(ex.Message);
  45. }
  46.  
  47. }
  48.  
  49. private void button5_Click(object sender, EventArgs e)
  50. {
  51. try
  52. {
  53. CHessianProxyFactory factory = new CHessianProxyFactory("userName", "password");
  54. string url = "http://localhost/HessianTest/rpc/studentServiceRpc";//修改为你的server端地址
  55. StudentService test = (StudentService)factory.Create(typeof(StudentService), url);
  56. test.Login("Admin", "");
  57.  
  58. Console.WriteLine("登陆成功");
  59. }
  60. catch (Exception ex)
  61. {
  62. Console.WriteLine(ex.Message);
  63. }
  64. }
  65. }
  66.  
  67. public interface StudentService
  68. {
  69. string hello(string name);
  70. List<StudentInfo> query(QueryStudentInfo q);
  71. void Login(String usename, String password);
  72. }
  73.  
  74. }
  75.  
  76. namespace f.studio.domain
  77. {
  78. public class BaseInfo
  79. {
  80. private DateTime? createDate;
  81.  
  82. public DateTime? CreateDate
  83. {
  84. get { return createDate; }
  85. set { createDate = value; }
  86. }
  87. private long? recId;
  88.  
  89. public long? RecId
  90. {
  91. get { return recId; }
  92. set { recId = value; }
  93. }
  94. }
  95. /// <summary>
  96. /// 上传时用需要保持命名空间与服务器一致
  97. /// </summary>
  98. public class QueryStudentInfo :BaseInfo
  99. {
  100. private int id;
  101. private String name;
  102. private DateTime? btime;
  103. private Byte[] data;
  104. private bool sex;
  105.  
  106. public int Id
  107. {
  108. get { return id; }
  109. set { id = value; }
  110.  
  111. }
  112. public DateTime? BTime
  113. {
  114. get { return btime; }
  115. set { btime = value; }
  116. }
  117. public string Name
  118. {
  119. get { return name; }
  120. set { name = value; }
  121. }
  122. public Byte[] Data
  123. {
  124. get { return data; }
  125. set { data = value; }
  126. }
  127. public bool Sex
  128. {
  129. get { return sex; }
  130. set { sex = value; }
  131. }
  132. }
  133.  
  134. /// <summary>
  135. /// 不能使用public int Id{get;set;}
  136. /// private 字段名称,大小写需要跟服务端定义一致
  137. /// [Serializable]标记貌似不是必须的
  138. /// </summary>
  139. public class Klass :BaseInfo
  140. {
  141. private int id;
  142. private String name;
  143. private DateTime? addTime;
  144.  
  145. public DateTime? AddTime
  146. {
  147. get { return addTime; }
  148. set { addTime = value; }
  149. }
  150. public string Name
  151. {
  152. get { return name; }
  153. set { name = value; }
  154. }
  155.  
  156. public int Id
  157. {
  158. get { return id; }
  159. set { id = value; }
  160. }
  161.  
  162. }
  163.  
  164. public class StudentInfo :BaseInfo
  165. {
  166. private string name;
  167. private bool? sex;
  168. private long id;
  169. private byte[] fileData;
  170.  
  171. public byte[] FileData
  172. {
  173. get { return fileData; }
  174. set { fileData = value; }
  175. }
  176. private List<Klass> ks;
  177.  
  178. public List<Klass> Ks
  179. {
  180. get { return ks; }
  181. set { ks = value; }
  182. }
  183.  
  184. public string Name
  185. {
  186. get { return name; }
  187. set { name = value; }
  188. }
  189.  
  190. public long Id
  191. {
  192. get { return id; }
  193. set { id = value; }
  194. }
  195.  
  196. public bool? Sex
  197. {
  198. get { return sex; }
  199. set { sex = value; }
  200. }
  201. public override string ToString()
  202. {
  203. return string.Format("Id:{0},Name:{1},Sex:{2},RecId:{3},CreateDate:{4}", Id, Name, Sex,RecId,CreateDate);
  204. }
  205.  
  206. }
  207. }

完成服务端代码下载

跟微软保持适当距离--Hessian + .net 实现RPC体系的企业应用的更多相关文章

  1. Hessian 源码简单分析

    Hessian 是一个rpc框架, 我们需要先写一个服务端, 然后在客户端远程的调用它即可. 服务端: 服务端通常和spring 做集成. 首先写一个接口: public interface Hell ...

  2. 我看微软收购GitHub

    今天是微软收购GitHub的第三天,之前很多人担心被微软收购的GitHub会步Skype,诺基亚等企业的后尘,凡此种种我觉得更多人的担心是:GitHub不再开源免费罢了. GitHub今年4月刚成立十 ...

  3. 纳德拉再造微软:市值如何重回第一阵营(思维确实变了,不再是以windows为中心,拥抱其它各种平台,敢在主战场之外找到适合自己的新战场)

    有人说,现在的美国硅谷充满了“咖喱味”.也有人说,硅谷已经变成“印度谷”.原因就在于,以微软CEO萨提亚·纳德拉.谷歌CEO桑达尔·皮查伊为代表的印度人,近年以来掌控了全世界最令人望而生畏的科技巨头. ...

  4. WPF路线图白皮书: 2015及未来

    介绍 当2006年微软首次推出Windows Presentation Foundation(WPF)时,它代表了应用程序的设计和开发又向前跨出了巨大的一步.它简化了GUI应用程序的开发,有助于UI和 ...

  5. 华人曾与IBM抗衡! 盘点已远去的IT巨头(转)

    [PConline资讯 ]从算盘到计算器,从大型机到个人PC,再到当今火热的移动终端和云计算,人类计算史已经走过了千年之久,现代IT计算领域也经过了百年浮沉.在世界工业领域,IT技术应该是诞生时间最短 ...

  6. Facebook人工智能实验室的前世今生

    Facebook人工智能实验室的前世今生 是时候停止把Facebook当作纯粹的社交媒体公司来看了.它用无人机提供互联网服务,为了发展虚拟现实而收购Oculus,不懈追求人工智能,Facebook已经 ...

  7. 公司管理系列--Facebook是如何营造企业文化的[转]

      本文讲下硅谷创业公司的文化,去过硅谷公司或者是看过硅谷公司报道的人,都会惊讶硅谷创业公司里面有如此奇特且活力十足的文化.在中国,企业文化是一个被滥用但是却又缺乏解读的概念,很多国内企业对保持公司的 ...

  8. 微软和Google的盈利模式对比分析

    一: 微软和Google是世界上最成功科技巨头之一,但他们之间却有着不同的产品和业务,二者的盈利方式也各有不同,本文将分析和探讨的二者盈利模式的异同. 微软的盈利模式 在1975年由大学肄业的Bill ...

  9. Java 技术栈

    JAVA是一个面向对象的编程语言,由SUN公司的程序员所开发.它不仅吸收了C++的各种优点,而且还撇弃了C++中难以理解的概念,如多继承.指针等:因此JAVA语言具有功能强大且简单易用两个特征, JA ...

随机推荐

  1. maven打jar到私服

    <dependency> <groupId>fakepath</groupId> <artifactId>wcs-java-sdk</artifa ...

  2. oracle数据库死锁的查看及解决

    Oracle常见死锁发生的原因以及解决方法 www.MyException.Cn  网友分享于:2014-09-02  浏览:0次       Oracle常见死锁发生的原因以及解决办法 一,删除和更 ...

  3. iis 在站点中新建虚拟目录站点之后,虚拟目录中的 web.config 与 主站点中的 web.config冲突解决方案

    在虚拟目录站点中增加如下配置即可:<clear/>

  4. Javamail使用代码整理

    package com.hengrun.mail; import java.io.*; import java.security.Security; import java.text.SimpleDa ...

  5. SSH: sshd dead but subsys locked

    问题: 查看SSH的状态时,提示错误如下: /etc/init.d/sshd status error: sshd dead but subsys locked 解决方法: sshd -d rm -r ...

  6. py基础4--迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1. 列表生成式,迭代器&生成器 列表生成式 我现在有个需求, ...

  7. 【POJ】1185 炮兵阵地(状压dp)

    题目 传送门:QWQ 分析 看到$ M<=10 $考虑状压. 然后把每行都压一下,那么每个状态相关的就是上一行和上上行的状态. 然后枚举. 然后复杂度最坏是$ O(100 \times 1024 ...

  8. 给iOS开发新手送点福利,简述UIView的属性和用法

    UIView 1.alpha 设置视图的透明度.默认为1. // 完全透明 view.alpha = 0; // 不透明 view.alpha = 1; 2.clipsToBounds // 默认是N ...

  9. samba性能调优

    不知道有多少公司的内部打印及文件服务器是用的Linux,我想肯定不会太多,因为Windows实现起来更方便,更快速,当然,Windows也 是更Danger. 因为Windows有太多不确定性的东西, ...

  10. MySQL转Oracle,MyBatis Mapper XML 文件修改项总结

    1.对于批量插入 需要更改成 <insert id="saveAll"> insert into(a,b,c) <foreach collection=" ...