•     又有新书可看了,2007年8月年出版的,讲的是Spring 2.0的技术

  • 2008年07月04日

    Struts 2.0与Spring整合 - [编程开发]

        struts 2中整合Spring主要是用到Spring的IoC功能,struts 2中的所有的action,interceptor等对象都是由Spring的bean工厂来生成。

    在web.xml里添加一个监听器

    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener
       </listener-class>
    </listener>

    struts.xml

    <constant name="struts.objectFactory" value="spring" />
     <constant name="struts.devMode" value="true" />

    在WEB-INF目录下创建applicationContext.xml文件

  • 2008年06月27日

    Spring 2.0使用AspectJ - [编程开发]

        Spring2.5很早就发布,当时下载Spring时,因为看到2.5只是beta版(测试版),而2.0后面标了GA(General Availability所谓的稳定版),所以只下载了2.0版,2.5跟2.0有什么变化和区别就不晓得,因为所有Spring学习都在2.0下面进行。

         AspectJ不用多说了,一个AOP的实现,AOP领域的先锋。现在是要在spring 2.0中使用AspectJ中的注解方式编程,实现AOP功能。

        不要用MyEclipse,一直使用它的话,就无法知道,我们项目有哪几个JAR包是需要的,哪几个又是不需要的。还有XML配置文件到底该怎么写,MyEclipse老是经常对XML动了一些错误的手脚。很多书上的例子都没有说要用到哪一些JAR包, 所以很多都是照书上代码打了一下,但还是运行错误,所以手工配置很重要。

         在使用Spring时,如果是Web项目,直接把Spring的JAR包拷到lib文件夹里,如果是普通的Java项目,可以在项目下新建一个文件夹名称为lib或者其他,把JAR包拷到里面。

        然后右键,add to build path,把JAR包加到项目的classpath中。当然还有其他很多方式,在这里不是重点。重点的是到底要加几个JAR包。

        首先再强调一下,那些JAR包,不要拿MyEclipse提供的那些,而是要从spring官方下载的。

        spring.jar这个是spring所有模块的集合JAR文件,commons-logging.jar,这个包不管是做spring的哪一个模块,不管是IOC还是AOP,MVC,如果没这个JAR包,运行马上就报错,这个是spring中输出错误信息的一个日志工具。log4j-1.2.14.jar这个也是缺一不可的,虽然不加这个包,程序照样可以运行,但程序中如果有错误就不知道哪里错,还有程序运行时,log4j还会打印整个运行流程。最后是aspectjrt.jar和aspectjweaver.jar要使用AspectJ的AOP功能就需要添加这两个。整个工程的结构如下:

        spring.xml这个文件也是随意命名的,MyEclipse好像把它命名为ApplicationContext.xml,那么长!还有这xml配置文件所放的目录也是随意的,只要在程序中指明它的位置就可以了。而log4j.properties 这个文件只能放在src根目录下,log4j.properties这个文件可以在下载下来的压缩包中resources目录找到它,也可以自己写,但文件名只能是log4j.properties

        按照上面项目的目录在代码中找到spring.xml文件应该是这样写ApplicationContext ac =
                new FileSystemXmlApplicationContext("bin/spring.xml");

        其中"bin/spring.xml"前面出现"bin",是因为eclipse是把.java源文件和.class文件分开的。原本是在src目录下创建的spring.xml经过eclipse编译后,就会自动在bin目录下生成spring.xml,如果写成"src/spring.xml"也是可以,但前提是发布项目时,字节码连同源代码一起发布,要不然就不存在src这个目录了。还有要注意的一点是"bin\\spring.xml"写成反斜杠是要两杠,正斜杠只需一杠,反斜杠在String中是转义符。

        再来看看spring.xml文件里的写法

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    <aop:aspectj-autoproxy />
        <bean id="stu" class="com.zhang.Student"></bean>
        <bean id="aop" class="com.zhang.Aop"></bean>
    </beans>
        beans元素里面的xmlns、 xsi:schemaLocation等等,一个字都不得有误,稍微网址有错误都不行。

        最后用AspectJ注解方式创建一个切面,其他商业逻辑代码暂不说明,直接看那个切面的代码:

    package com.zhang;
    import org.aspectj.lang.annotation.*;
    @Aspect
    public class Aop {
        @Pointcut("execution(* run*(..))")
        public void somePointcut() {
           
        }
        @Before("somePointcut()")
        public void asp() {
            System.out.println("the before aop is running");
        }
        @After("somePointcut()")
        public void asp1() {
            System.out.println("the after aop is running");
        }
    }

        先说明一下那些通配符的意思,“*”星号,代表0个或多个字符,在方法的括号内"(..)"里面两点,代表有0个或多个参数。

    * run*()是匹配所有类中所有以run开头的方法,比如public void run1();private int run2();注意第一个*后面是有空格的,有空格和没空格意义完全不同。有一本书上这样写:

     "execution("execution("* springroad.demo.chap5.exampleB.Component.business*(..))")

        它通配的是某个类的某一个方法,包名和类名都很长,真的会混淆人, 第一个“*”星号后一定要记得加空格,大部分情况下第一个“*”号都要写上去,也有不需要的,如

    execution(public void run*(..));execution(int run*(..))等等,那些方法前加修饰符的就不需要

    ——————————

    最后总结:

    要在Spring中使用AspectJ,并不需要特定把AspectJ从官网上下载安装,而是只需到Spring官网下载相关的软件包即可,里面已经包含AspectJ相应的JAR包文件。

    到底有哪几个包需要的要自己尝试,不要借助MyEclipse,因为它会导入一些根本用不到的包,而且数量还不少,要知道如果是在tomcat,JAR包越多启动时间就越长。

     要搞懂execution的写法,在Spring参考文档里有说明

  • 2008年06月22日

    Struts 2 结果(Result) - [编程开发]

        Result也是Struts的核心部分,在整个MVC中它所处的位置是视图(View),但它跟页面外观效果却没有直接联系,它的职责就是调度视图以哪种形式来体现。比如最常用的就是JSP,还可以是Freeemarker,Velocity and XSLT。

        通过实现Result接口和方法可以自定义result类型,但一般很少自己专门定义,因为扩展struts-default,它里面就默认帮我们定义好了好几种result类型,这些类型已经足够使用了。最常用的比如有dispatcher,在配置文件中如果不写明哪一种类型,默认就是 dispatcher,它的实现机制来源于RequestDispatcher.forward()。再如Redirect重定向,使用 servlet&JSP开发时,经常使用的一种跳转方式。

    写result配置文件时存在一个默认参数问题,

    <result name="success" type="redirectAction">admin</result>

    <result name="success" type="redirectAction">
                <param name="actionName">admin</param>
    </result>

        这两种配置最后的结果都是一样,第一种并没有指名admin就是actionName这个参数,原因就是actionName就是一个默认参数,所以无需要专门指定。如果一个事先result的类,它有多个属性,这是就要专门写对它具体的属性参数进行配置。如果采用不带参数名的配置方法,可以实现org.apache.struts2.dispatcher.StrutsResultSupport这个类,然后实现doExecute(String finalLocation, ActionInvocation invocation) 这个方法。其中String finalLocation的值就是不带参数名的值

    在result配置中也可以带参数

    <action name="SendUserToSearchEngineAction" class="myActionClass">
       <result type='redirect' >
          http://www.google.com/?myParam=${defaultUsername}
       </result>
    </action>   

    ${defaultUsername}是action中的属性

    如果要在result中调出request,response这样的对象,可以使用org.apache.struts2.ServletActionContext里的静态方法来获得。在使用Ajax时,这时response返回的不再是一个JSP而是XML。但那些常用的result都是返回JSP页面,这样就有必要自定义一个result

  • 1. 通过相对路径直接导入
    例如<%@ taglib uri="/WEB-INF/c.tld" prefix="c"%>,要先把c.tld文件复制到WEB-INF这个目录里
    2. 自定义link导入
    这是时候要在web.xml里面写上
    例如:
    <jsp-config>
     <taglib>
         <taglib-uri>/core</taglib-uri>
         <taglib-location>/WEB-INF/c.tld</taglib-location>
     </taglib>
    </jsp-config>
    然后jsp文件里面加上
    <%@ taglib uri="/core" prefix="c"%>
    3. META-INF导入
    可以把tld文件放在META-INF文件夹里,然后在里面的tld文件要写清楚URI
    像JSTL或Struts标签都已经把相应的TLD文件放到META-INF文件里,打开那个tld文件可以看到里面的URI属性,比如Struts 2的 struts-tags.tld文件里写着 <uri>/struts-tags</uri>所以在JSP页面可以这样导入标签库
    <%@ taglib prefix="s" uri="/struts-tags" %>。另外JSTL的c.tld里是<uri>http://java.sun.com/jsp/jstl/core</uri>所以可以写成这样
    <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
  • 2008年06月17日

    Struts 2小结 - [编程开发]

        那本《Struts 2 In Action》现在已经大致看了一遍,整个Struts的主要内容包括Action、Interceptor、Result、Taglib、Validation、I18N、conversion、OGNL、SSH integration。其中核心的部分是Action、Interceptor、Result。何谓核心部分,一个最简单的Struts程序从Client端发送一个请求,经过多层Interceptor最后到Action,再返回一个Result,整个过程分别对这三者对象操作,要使程序能跑通,这三者缺一不可。而那些经常要用到的Struts标签却不能称为核心组件,因为Struts 2在实现MVC中的View部分不再仅限于JSP,还可以以其他的Freeemarker,Velocity and XSLT形式来表现。

        其他的像Validation一般也都是通过JavaScript来实现,只是用JavaScript还需要熟悉这门脚本语言。I18N估计也是很少用到,如果页面出现乱码,需要把这部分也考虑进去。和Spring、Hibernate的集成也很简单。

        学习框架只需了解它的核心部分的原理,最重要的还是学习怎么用这个框架。说到学习怎么用,一般都是在以后实际项目开发中才会碰到,像Struts 2提供那么多标签,并不需要对每一个标签都熟悉,只有等用到的时候才去学它。

  • 2008年06月17日

    Google Web Toolkit - [编程开发]

        GWT是一个以Java语言为工具,以类似Swing的方式编写UI组件,之后通过GWT Compiler编译为JavaScritp和HTML在客户端浏览器中运行的一个开发工具和编程模型。

        书籍参考:

        这本只有245页,但里面讲的并不是和基础的东西,而是几个实际应用的例子,显然不适合初学时用。

     

        所以先看看这本了,现在大概知道怎么创建一个GWT项目和如何运行了

     

         GWT版本更新非常快,上个月下载下来还是1.4版,这个月就升级到1.5了,看到最明显的变化就是创建默认模块。原来只有一个按钮,然后旁边显示Helloworld,现在变成是弹出一个对话框了

  • 2008年06月14日

    Struts 2 类型转换 - [编程开发]

        在html表单中的文本框里输入的不管是数值类型还是字符类型,最后都是以String类传到后台。如果后台bean的属性是int、double、Date等,Struts就会自动把字符类型转换成相应的类型。

        Struts2中默认提供了一些内置的转换器,包括8个基本类型,Date,array数组,List,Map类。也可以自定义转换器。通过实现ogln.TypeConverter接口实现它的方法就可以定义其他类型的转换,不过还要配置相应的资源文件。其实那几个内置的转换器已经足够使用了,很少会专门定义一个转换器。

        基本数据类型转换器没有什么特殊要求,只要输入的值符合基本数据类型,它都会自动转换,否则会出现错误提示。比如对于int类型,前天就不能输入跟数字无关的字符。再来就是日期类型,默认好像是YY-MM-DD,比如2008-8-8,如果写成8-8-2008提交后就会出现错误提示。

        对于Array数组,List,Map则需要配合OGNL表达式一起使用。比如后台有个属性是String [] name,在前台界面

      <s:textfield name="names[0]" label="names"/>
       <s:textfield name="names[1]" label="names"/>
       <s:textfield name="names[2]" label="names"/>

    就会对这个数组赋值。List跟数组使用方式一样,但只针对不加泛型的基本数据类型的的List,如果加了泛型则是

    <s:textfield name="users[0].username" label="Usernames"/>
    <s:textfield name="users[1].username" label="Usernames"/>
    <s:textfield name="users[2].username" label="Usernames"/>

    比如User类中有个username属性,List<User> users这个属性对应上面的写法。最后是Map的转换方式

    <s:textfield name="maidenNames['beth']" label="Maiden Name"/>
    <s:textfield name="maidenNames['sharon']" label="Maiden Name"/>
    <s:textfield name="maidenNames['martha']" label="Maiden Name"/>

    []里的值对应到Map中的Key

  •     Struts2中的default.properties文件中默认设置的编码方式是struts.i18n.encoding=UTF-8。所以只要在新建的JSP页面设置charset=UTF-8就不会出现乱码问题,但前提是表单是通过post方法发送的。如果采用get方法仍然会产生乱码问题,不过只要在tomcat的server.xml文件中添加URIEncoding="UTF-8" 到<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8" />就没问题了。无需添加任何过滤器,如果对UTF-8不满意,把所有编码相关的参数改为对应的编码就行了。
  •     拦截器就是一种AOP的实现方式,传统的JSP&Servlet架构中,客户端发送一个请求,服务器端生成一个request对象,并执行相应的doget(),dopost()方法,最后由response返回一个响应到客户端,整个服务过程就结束了。所以所有的业务逻辑功能只能在doget(),dopost()里调用,这样整个业务就写死了,如果想增加新的功能,只能修改doget(),dopost方法,不符合开闭原则。

        现在只要通过拦截器就可以添加新的功能而不修改原来的代码。

        在Struts2中每发送一个请求都要经过好几层的拦截器最终才到达所调用的action。由多个拦截器组成的就是一个intercptor-stack,如果扩展了struts-default就默认集成了defaultstack。里面包含了许多常用的拦截器,比如文件上传时会用到fileUpload,要调出session对象由servletConfig来做。

        因为defaultstack里的拦截器,默认已经配好了,所以无需要专门对这些拦截器进行配置。不过Struts2提供的拦截器还有许多需要专门配置的。比如timer,它是计算执行某个action所需要的时间。

        比如在struts.xml文件中的某个action加入timer拦截器

    <action name="upload" class="com.zhang.action.UploadAction" method="execute">
        <result name="success">/pages/welcome.jsp</result>
        <result name="input">/index.jsp</result>
        <interceptor-ref name="timer"></interceptor-ref>
        </action>

    最后会在控制台上打印

    Executed action [/chapterFour/secure/ImageUpload!execute] took 123 ms.

    servlet-config这个拦截器也是在defaultstack默认配置好了,它的作用的就是判断action看它是否实现了sessionaware等接口,并执行它的setSession方法