WaveSun

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  17 随笔 :: 0 文章 :: 3 评论 :: 0 Trackbacks

2009年5月25日 #

     摘要: 这个滑动条(拖动条)效果,一开始是参考了BlueDestiny的slider和Apple产品展示的样式,做了程序的原 型。 在做了拖放效果之后,我想应该可以做一个更好的了,所以重做一遍,完善和扩展了一些功能。 碍于时间没有做得很强大,都是一些基本功能,希望各位多提意见! 效果预览 0){ this._IsMin = false; }else{ if(!this._IsMin)...  阅读全文
posted @ 2010-03-22 15:31 WaveSun 阅读(603) | 评论 (0)编辑 收藏

Spring入门

Spring是一个非常优秀的轻量级框架,通过Spring的IoC容器,我们的关注点便放到了需要实现的业务逻辑 上。对AOP的支持则能让我们动态增强业务方法。编写普通的业务逻辑Bean是非常容易而且易于测试的,因为它能脱离J2EE容器(如 Servlet,jsp环境)单独进行单元测试。最后的一步便是在Spring框架中将这些业务Bean以XML配置文件的方式组织起来,它们就按照我们 预定的目标正常工作了!非常容易!

本文将给出一个基本的Spring入门示例,并演示如何使用Spring的AOP将复杂的业务逻辑分离到每个方面中。

1.开发环境配置2.编写Bean接口及其实现3.在Spring中配置Bean并获得Bean的实例4.编写Advisor以增强 ServiceBean5.总结

1.开发环境配置

首先,需要正确配置Java环境。推荐安装JDK1.4.2,并正确配置环境变量:

JAVA_HOME=<JDK安装目录>CLASSPATH=.Path=%JAVA_HOME%"bin;……

我们将使用免费的Eclipse 3.1作为IDE。新建一个Java Project,将Spring的发布包spring.jar以及commons-logging-1.0.4.jar复制到Project目录下,并在 Project > Properties中配置好Java Build Path:

Spring入门(图一)

点击查看大图 2.编写Bean接口及其实现

我们实现一个管理用户的业务Bean。首先定义一个ServiceBean接口,声明一些业务方法:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

/** * Interface of service facade. *  * @author Xuefeng */public interface ServiceBean {    void addUser(String username, String passWord);    void deleteUser(String username);    boolean findUser(String username);    String getPassword(String username);}

然后在MyServiceBean中实现接口:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 *  * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

import java.util.*;

public class MyServiceBean implements ServiceBean {

    private String dir;    private Map map = new HashMap();

    public void setUserDir(String dir) {        this.dir = dir;        System.out.println("Set user dir to: " + dir);    }

    public void addUser(String username, String password) {        if(!map.containsKey(username))            map.put(username, password);        else            throw new RuntimeException("User already exist.");    }

    public void deleteUser(String username) {        if(map.remove(username)==null)            throw new RuntimeException("User not exist.");    }

    public boolean findUser(String username) {        return map.containsKey(username);    }

    public String getPassword(String username) {        return (String)map.get(username);    }}


为了简化逻辑,我们使用一个Map保存用户名和口令。

现在,我们已经有了一个业务Bean。要测试它非常容易,因为到目前为止,我们还没有涉及到Spring容器,也没有涉及到任何Web容器(假定这 是一个Web应用程序关于用户管理的业务Bean)。完全可以直接进行Unit测试,或者,简单地写个main方法测试:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

public class Main {

    public static void main(String[] args) throws Exception {        ServiceBean service = new MyServiceBean();        service.addUser("bill", "hello");        service.addUser("tom", "goodbye");        service.addUser("tracy", "morning");        System.out.println("tom's password is: " + service.getPassword("tom"));        if(service.findUser("tom")) {            service.deleteUser("tom");        }    }}

执行结果:Spring入门(图二)

3.在Spring中配置Bean并获得Bean的实例

我们已经在一个main方法中实现了业务,不过,将对象的生命周期交给容器管理是更好的办法,我们就不必为初始化对象和销毁对象进行硬编码,从而获 得更大的灵活性和可测试性。

想要把ServiceBean交给Spring来管理,我们需要一个XML配置文件。新建一个beans.xml,放到src目录下,确保在 classpath中能找到此配置文件,输入以下内容:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>    <bean id="service" class="com.crackj2ee.example.spring.MyServiceBean" /></beans>

以上XML声明了一个id为service的Bean,默认地,Spring为每个声明的Bean仅创建一个实例,并通过id来引用这个 Bean。下面,我们修改main方法,让Spring来管理业务Bean:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource;

public class Main {

    public static void main(String[] args) throws Exception {        // init factory:        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));        // use service bean:        ServiceBean service = (ServiceBean)factory.getBean("service");        service.addUser("bill", "hello");        service.addUser("tom", "goodbye");        service.addUser("tracy", "morning");        System.out.println("tom's password is """ + service.getPassword("tom") + """");        if(service.findUser("tom")) {            service.deleteUser("tom");        }        // close factory:        factory.destroySingletons();    }}


执行结果: Spring入门(图三)

由于我们要通过main方法启动Spring环境,因此,首先需要初始化一个BeanFactory。红色部分是初始化Spring的 BeanFactory的典型代码,只需要保证beans.xml文件位于classpath中。

然后,在BeanFactory中通过id查找,即可获得相应的Bean的实例,并将其适当转型为合适的接口。

接着,实现一系列业务操作,在应用程序结束前,让Spring销毁所有的Bean实例。

对比上一个版本的Main,可以看出,最大的变化是不需要自己管理Bean的生命周期。另一个好处是在不更改实现类的前提下,动态地为应用程序增加 功能。

4.编写Advisor以增强ServiceBean

所谓AOP即是将分散在各个方法处的公共代码提取到一处,并通过类似拦截器的机制实现代码的动态织入。可以简单地想象成,在某个方法的调用前、返回 前、调用后和抛出异常时,动态插入自己的代码。在弄清楚Pointcut、Advice之类的术语前,不如编写一个最简单的AOP应用来体验一下。

考虑一下通常的Web应用程序都会有日志记录,我们来编写一个LogAdvisor,对每个业务方法调用前都作一个记录:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;

public class LogAdvisor implements MethodBeforeAdvice {    public void before(Method m, Object[] args, Object target) throws Throwable {        System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");    }}

然后,修改beans.xml:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />

    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />

    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>        <property name="target"><ref local="serviceTarget"/></property>        <property name="interceptorNames">            <list>                <value>logAdvisor</value>            </list>        </property>    </bean></beans>

注意观察修改后的配置文件,我们使用了一个ProxyFactoryBean作为service来与客户端打交道,而真正的业务Bean即 MyServiceBean被声明为serviceTarget并作为参数对象传递给ProxyFactoryBean,proxyInterfaces 指定了返回的接口类型。对于客户端而言,将感觉不出任何变化,但却动态加入了LogAdvisor,关系如下: Spring入门(图四)


运行结果如下,可以很容易看到调用了哪些方法: Spring入门(图五)

要截获指定的某些方法也是可以的。下面的例子将修改getPassword()方法的返回值:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;

public class PasswordAdvisor implements MethodInterceptor {    public Object invoke(MethodInvocation invocation) throws Throwable {        Object ret = invocation.proceed();        if(ret==null)            return null;        String password = (String)ret;        StringBuffer encrypt = new StringBuffer(password.length());        for(int i=0; i<password.length(); i++)            encrypt.append('*');        return encrypt.toString();    }}

这个PasswordAdvisor将截获ServiceBean的getPassword()方法的返回值,并将其改为"***"。继续 修改beans.xml:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>    <bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />

    <bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />

    <bean id="passwordAdvisorTarget" class="com.crackj2ee.example.spring.PasswordAdvisor" />

    <bean id="passwordAdvisor" class="org.springframework.aop.support.RegeXPMethodPointcutAdvisor">        <property name="advice">            <ref local="passwordAdvisorTarget"/>        </property>        <property name="patterns">            <list>                <value>.*getPassword</value>            </list>        </property>    </bean>

    <bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">        <property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>        <property name="target"><ref local="serviceTarget"/></property>        <property name="interceptorNames">            <list>                <value>logAdvisor</value>                <value>passwordAdvisor</value>            </list>        </property>    </bean></beans>


利用Spring提供的一个RegexMethodPointcutAdvisor可以非常容易地指定要截获的方法。运行结果如下,可以看到返回结果变 为"******": Spring入门(图六)

还需要继续增强ServiceBean?我们编写一个ExceptionAdvisor,在业务方法抛出异常时能做一些处理:

/** * Copyright_2006, Liao Xuefeng * Created on 2006-3-9 * For more information, please visit: http://www.crackj2ee.com */package com.crackj2ee.example.spring;

import org.springframework.aop.ThrowsAdvice;

public class ExceptionAdvisor implements ThrowsAdvice {    public void afterThrowing(RuntimeException re) throws Throwable {        System.out.println("[Exception] " + re.getMessage());    }}

将此Advice添加到beans.xml中,然后在业务Bean中删除一个不存在的用户,故意抛出异常:

service.deleteUser("not-exist");

再次运行,注意到ExceptionAdvisor记录下了异常: Spring入门(图七)

5.总结

利用Spring非常强大的IoC容器和AOP功能,我们能实现非常灵活的应用,让Spring容器管理业务对象的生命周期,利用AOP增强功能, 却不影响业务接口,从而避免更改客户端代码。

为了实现这一目标,必须始终牢记:面向接口编程。而Spring默认的AOP代理也是通过Java的代理接口实现的。虽然Spring也可以用 CGLIB实现对普通类的代理,但是,业务对象只要没有接口,就会变得难以扩展、维护和测试。

欢迎来信与作者交流:asklxf@163.com

可以从此处下载完整的Eclipse工程:

springbasic.rar

(出处:http://www.jzwiki.com/article_1215945431010.shtml#)

posted @ 2010-03-09 13:00 WaveSun 阅读(250) | 评论 (0)编辑 收藏


当你在客户端用view source看JSP生成的代码时,会发现有很多空行,他们是由<%...%>后的回车换行而生成的,也就是说每一行 由<%...%>包含的JSP代码到客户端都变成一个空行,虽然不影响浏览,但还是希望能把他们删掉

办法如下:(网上收集整理)

1. 支持JSP 2.1+ ,在每个要去空行的页面里包含下面代码:

  

<%@ page trimDirectiveWhitespaces="true" %>

在 Tomcat 6.0.14下测试成功


2. 支持servlet 2.5+, 即 web.xml的 XSD版本为2.5,在web.xml中加入如下代码

  

<jsp-config>
      
<jsp-property-group>
        
<url-pattern>*.jsp</url-pattern>
        
<trim-directive-whitespaces>true</trim-directive-whitespaces>
      
</jsp-property-group>
    
</jsp-config>

在tomcat 6.0.14下测试成功


3. Tomcat 5.5.x+,在Tomcat安装目录/conf/web.xml中找到名叫"jsp"的servlet,添加下面一段代码:

<init-param>
        
<param-name>trimSpaces</param-name>
        
<param-value>true</param-value>
    
</init-param>


 

本人没测过,不过tomcat中web.xml文件的帮助这么说的

trimSpaces          Should white spaces in template text between  actions or directives be trimmed?  [false]

所以应该可行 

发表于 @ 2008年05月23日 11:40:00 | 评论( 3 ) | 举报| 收藏

mcoldice 发 表于2009年2月23日 16:56:39  举 报回复
关于第三条:
1 确实有效
2 5.0也同样有效,所以不时必须要5.5.x+
mcoldice 发 表于2009年2月23日 16:56:53  举 报回复
关于第三条:
1 确实有效
2 5.0也同样有效,所以不时必须要5.5.x+
xuhaiyang 发 表于2009年2月23日 17:55:25  举 报回复
因 为没用5.0测过,所以就没写出来。
谢谢你的补测。
原文地址:http://blog.csdn.net/xuhaiyang/archive/2008/05/23/2472591.aspx
posted @ 2010-03-09 10:08 WaveSun 阅读(978) | 评论 (0)编辑 收藏

关键字: jsp <jsp-config>
<jsp-config> 包括 <taglib> <jsp-property-group> 两个子元素。其中<taglib> 元素在JSP 1.2 时就已经存在;而<jsp-property-group>JSP 2.0 新增的元素。<jsp-property-group> 元素主要有八个子元素,它们分别为:
1.<description>:设定的说明
2.<display-name>:设定名称
3.<url-pattern>:设定值所影响的范围,如: /CH2 /*.jsp
4.<el-ignored>:若为 true,表示不支持 EL 语法
5.<scripting-invalid>:若为 true,表示不支持 <% scripting %>语法
6.<page-encoding>:设定 JSP 网页的编码
7.<include-prelude>:设置 JSP 网页的抬头,扩展名为 .jspf
8.<include-coda>:设置 JSP 网页的结尾,扩展名为 .jspf

一个简单的<jsp-config> 元素完整配置:

Xml代码
  1. <jsp-config>     
  2.   <taglib>     
  3.     <taglib-uri>Taglib</taglib-uri>     
  4.     <taglib-location>/WEB-INF/tlds/MyTaglib.tld</taglib-location>     
  5.   </taglib>     
  6.   <jsp-property-group>     
  7.     <description>Special property group for JSP Configuration JSP example.</description>     
  8.     <display-name>JSPConfiguration</display-name>     
  9.     <url-pattern>/jsp/* </url-pattern>     
  10.     <el-ignored>true</el-ignored>     
  11.     <page-encoding>GB2312</page-encoding>     
  12.     <scripting-invalid>true</scripting-invalid>     
  13.     <include-prelude>/include/prelude.jspf</include-prelude>     
  14.     <include-coda>/include/coda.jspf</include-coda>     
  15.   </jsp-property-group>     
  16. </jsp-config>  
 
对于Web 应用程式来说,Scriptlet 是个不乐意被见到的东西,因为它会使得HTMLJava 程式码交相混杂,对于程式的维护来说相当的麻烦,必要的时候,您可以在web.xml 中加上<script-invalid> 标签,设定所有的JSP 网页都不可以使用Scriptlet ,例如:
Xml代码
  1. <web-app ..>  
  2.     ....  
  3.     <jsp-config>  
  4.         <jsp-property-group>  
  5.             <url-pattern>*.jsp</url-pattern>  
  6.             <script-invalid>true</script-invalid>  
  7.         </jsp-property-group>  
  8.     </jsp-config>  
  9. ....  
  10. </web-app>  
 
原文地址:http://janwer.javaeye.com/blog/150217
posted @ 2010-03-09 09:51 WaveSun 阅读(597) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-16 12:02 WaveSun 阅读(256) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-16 11:54 WaveSun 阅读(230) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-09 18:38 WaveSun 阅读(222) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-09 11:22 WaveSun 阅读(212) | 评论 (0)编辑 收藏



posted @ 2009-06-08 16:44 WaveSun 阅读(213) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-08 10:56 WaveSun 阅读(1199) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-08 10:14 WaveSun 阅读(637) | 评论 (1)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-08 10:05 WaveSun 阅读(284) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-07 22:23 WaveSun 阅读(348) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-07 20:58 WaveSun 阅读(947) | 评论 (0)编辑 收藏

     摘要:   阅读全文
posted @ 2009-06-07 20:51 WaveSun 阅读(1719) | 评论 (1)编辑 收藏

     摘要:   阅读全文
posted @ 2009-05-25 12:27 WaveSun 阅读(168) | 评论 (0)编辑 收藏