Java

[Spring] 轻巧使用 Spring-Controller

spring评价     大家都知道,Spring MVC提供了一些功能齐全的Controller,并和Struts一样,为这些Controller配套了很多可配置、可扩展的东西,如 successView,validator,Bean绑定框架,ResourceBundle。但我的观点是:    1.“可配置”性有意义吗?可配置是为了重用,但WEB层的东西能有几次重用?比起写一大堆配置文件的痛苦,追求一点点的重用有什么意义?    2. 有必要把validator独立出来吗?几个Controller共用一个validator的情况并不多见,而且就算要共用,也可以把校验逻辑写在pojo里,而不是写在丑陋不堪的Spring-validator里    3.Spring-Bind 通过字段级的绑定,可以在表单提交失败时给出具体的失败原因,提高用户体验,与resourceBundle结合使用还可以实现国际化。但是这个代价太大了,因为你要在表单页面中写很多 <spring-bind>这样的东西,而且,你的项目真的需要国际化吗?    4.有些Form Controller很有框架的特点(半成品),但是用起来更不顺手。以SimpleFormController为例,你要另外定义一个Form Object,要告诉系统在请求form和提交form时分别作什么,而且程序还人为地把校验逻辑和业务逻辑调用彻底分成不同的阶段,既麻烦,又不灵活 简化使用    在厌倦了这些烦人的东西之后,我开始简化地使用Spring MVC。最终我形成了自己的模式。这个模式的核心思想就是:Spring MVC仅用作URL映射和Bean注入,而它的Controller仅当作普通的Servlet,用request.getParameter()的方式获取输入,用POJO的风格来完成功能,既灵活,又舒服。具体来说:      1.基本只用最简单的AbstractController。以表单处理为例,请求form用一个controller,提交form再用一个controller,把两个步骤分开,这样的代码都比较简洁,长度少了很多;采用了POJO风格编码,可读性也强了很多    2.调用javabean的方法完成校验。既可在controller间重用,又维持了pojo风格       3.successView 可以作为表单页面的隐藏变量传到controller中来,这样就不用写XML了。其实,大多数情况下,把successView写死在Controller的代码中就够了。不同功能模块共享Controller的情况是不多见的。    4.校验异常,或者发现业务错误,直接throw Exception。然后用一个通用的处理error的JSP来处理所有Exception (这是Spring的功能),这个jsp里加上一个“返回”按钮,就可以方便用户在出错之后重新提交请求        5.相近的请求让一个controller处理就够了(如添加用户、删除用户),这样的话写URL配置就只需要写一次。仍然可以只用AbstractController,然后用一个Http Parameter参数来区分请求即可。   现在能想到的就是这么多,以后再补充

强烈推荐使用 Hessian/Burlap 作为J2EE分布式系统内部 的 远程服务方案

    在J2EE分布式系统中,我们需要选取某种远程服务协议,在分布的进程之间进行交互。可供选择的协议 EJB、 基于SOAP的Web Service 这些重量级的,也有像RMI、Socket这种比较原始的。但最近了解到了Caucho公司的 Hessian/Burlap方案,我觉得这种方案才是最合适的, 因为它没有上文所述其他几种方案的缺点,而且,如果把Hessian/Burlap与Spring结合使用,设计者将感到无比的方便。    下面就逐个说说这些“不好的”方案,再介绍Hessian/Burlap方案。       a. EJB。 这就不用说了,EJB极其笨重,配置会累死人,性能也糟糕。       b. 基于SOAP的Web Service。 有着和EJB类似的缺点。声明一个服务很麻烦,而且用SOAP协议传输数据会浪费大量的带宽,因为SOAP基于XML,而XML中大部分的数据并不一定是业务数据,而仅仅是元数据。       c. RMI。如果与Spring结合使用,配置不算麻烦。但是其服务接口受到制约(必须继承java.rmi.Remote接口),而且RMI服务只能使用1109端口。       d. Socket。 这应该是最让程序员放心的协议了,因为程序员想怎么搞就怎么搞。但有两个代价:           i.要做很多底层的、基础性的事情。比如说,程序员不得不手写烦人的Socket客户端和服务端代码,要直接与 Socket、InputStream、OutputStream 等底层类打交道;要手工实现安全性、并发、转码、日志等功能;Socket服务器也要通过一个独立的MAIN程序来启动,而不能放到J2EE服务器产品运营,也就是说利用不了J2EE服务器的监控功能。          ii.使用SOCKET方式交互,需要设计交互的报文规范。这是一件非常累人的工作。报文既要使用统一的方式来组报和解报、又要保证报文不会引起歧义。当远程服务的接口变更时,报文可能要做极大的变更。举个例子,在原来的报文中插入一个字段,其后面的字段位置都要后移,这样的话,组报、解报代码可能都要大改。       e. Hessian/Burlap。它的优点就是解决了以上几种方案的缺点。           i. 易用性。非常方便,服务不需要继承奇怪的接口,也没有多少配置,只需包装成一个Servet即可。与Spring的注入机制结合使用的话,客户端和服务端都会很舒服。           ii. 性能好。Burlap也是用XML传输数据,但比SOAP简约的多;而Hessian是二进制协议,更加节省带宽。           iii. 它也是 基于Http的,它可以穿透防火墙,其实它也是Web Service的一种协议,           iv.为程序员 免去了底层性、基础性的工作。因为它是一个Servlet,底层性的工作,比如 输入输出流、并发、日志等事情 都可以交给Tomcat之类的、现成的服务器; 有了应用服务器,还可以获得其他的一些功能,比如监控、集群什么的;它还可以配置用户名和密码,安全性的工作也包干了           v. 不用设计报文了。因为服务端的服务是以 …

强烈推荐使用 Hessian/Burlap 作为J2EE分布式系统内部 的 远程服务方案 Read More »

每个常数值都应该定义为一个常数变量,其他所有应用该常量的地方都应该通过该定义来存取

    就像C语言里的“宏”一样。如果需求变了,导致常量的值变了,只需要在定义处改一次即可。如果不遵循这个模式,在使用常量的地方直接使用它的值,那么一旦常量值有变,每个使用此值的地方都要变。    不但常量值这样,每种策略、每种规则都应该这样:只定义一次,并作为存取的唯一入口。

多线程程序中要注意捕获java.lang.ThreadDeath

    它的API DOC中写着:    The top-level error handler does not print out a message if ThreadDeath is never caught.     如果你的各个线程相继死去,并且没有报错,那很有可能就是这个东西引起的    程序应该在run()方法内部捕捉这个异常,才能保证Thread不死    Tomcat容器会捕获这个错误    如果在Eclipse内执行某个程序,也会捕获这个错误

用数据包装类比用原始类型作为成员变量的好处

以Integer 和 int 为例进行对比 1.如果成员变量的intValue还未确定,用Integer的话,只须令这个成员为NULL; 但如果用int的话,就必然存在问题,因为一个int成员变量的值总是确定的,即使你没给它赋任何值,它的值就是0 2.对一个对象运用反射机制时,比如setProperty()和getProperty(),都要将Field的值当作对象来处理。Integer成员可以直接用做对象,但int成员还要封装/解封才行 3.充当Map的key时,Integer比int更方便

为什么要用Class.forName() 来装载 JDBC的驱动

    因为Class.forName除了像ClassLoader一样装载驱动类,还会初始化这个驱动类。初始化的一个重要环节就是调用类的静态方法(static代码块)。驱动类在静态方法里将自己注册到DriverManager,只有注册了,驱动才能发生作用。因此,不用Class.forName(驱动类),就不会初始化这个类,这个驱动就会出错,使用驱动的程序就不能正确地执行