在struts2的action中使用字段级参数注入

上篇我们提到了使用SetAndGet注解进行自动生成set/get方法,那么在开发模式下, 我们所使用的IDE,在进行了代码修改之后,会自动地进行重新编译代码并进行hotswap操作。这个操作会使得在启动时生成的set/get失效或者被删除。解决这个问题的一个方法,就是使用字段级参数注入,即我们在开发模式下不需要生成set/get,而是直接使用相应的字段进行操作。

在当前的struts2版本中,默认是不支持字段设置值的,但是ognl本身是支持的。在ognl中,提供了以下2个方法来完成字段的获取和设置。

OgnlRuntime.setFieldValue(ognlContext, o, name.toString(), value);//设置字段的值
OgnlRuntime.getFieldValue(ognlContext, o, name.toString());//获取字段的值

那么,我们可以通过相应的处理。让在开发模式下,在使用常规参数处理之后,再启用字段级参数处理就达到相应的目的了。在整个处理中,我们需要保证以下2点就可以达到目的了。

  1. 在action进行参数注入时,可以支持字段级的注入,涉及的访问器为CompoundRootAccessor
  2. 在相应的字段为null时,我们可以按照常规的处理自动创建相应的值,以便进行注入,涉及的处理器为InstantiatingNullHandler

继续阅读“在struts2的action中使用字段级参数注入”

struts2 Action的参数处理和应用(数据访问和处理)-技术培训

这是一次为部门作的技术培训ppt,以下将其贴出,以方便大家查看。
下载地址:http://download.csdn.net/download/fly_m/5562553

本培训从最基本的数据如何进行访问和如何调用方法开始,逐步深入,讲解在数据处理当中涉及到的数据访问,转换,封装以及数据创建等内容。然后结合struts2,讲解在struts2中是如何运用这些理论来处理这些事项,并且是如何运行的;最后讲解了一个之前提到过如何在sturts2中使用带参数进行方法调用,并且是如何作到的。
涉及到以下主题

基本的数据访问
数据链
Request请求中的数据处理
数据转换和封装
泛型映射
Struts2中的数据处理
方法参数映射
Struts2中的数据增强处理

继续阅读“struts2 Action的参数处理和应用(数据访问和处理)-技术培训”

xwork classFinder在jboss 7环境不能正确处理url resource的问题以及解决方法

在struts2中,有一个组件为classFinder,它可以在整个项目中查找任意一个指定条件的类。如查找实现了某一个接口的所有实现类,或者查找有指定注解的所有类。这个组件的好处自不用说,但是在jboss7环境下,即会出现查找不到对象的问题。

如以下的条件就不能查找任何信息:只查找以com.iflym包名开头的满足指定条件的类。那么,这个classFinder的构建方法就是:

    public ClassFinder(ClassLoaderInterface classLoader, String... dirNames) {
        this(classLoader, getURLs(classLoader, dirNames));
    }

这个方法,会按照指定的包名,组装多个url地址,那么在jboss7中,就会组装成以下的一个地址:

jboss/standalone/tmp/vfs/deplymentxxx/iflym.jar-xxx/contents/com/iflym

那么,在这个目录下,肯定没有任何东西。那么xword在实现jboss vfs的查找时,会使用以下方法进行定位:

            if (s.startsWith("class org.jboss.vfs.VirtualFile")) { // JBoss 7 and probably JBoss 6
                File physicalFile = readJBossPhysicalFile(content);
                return physicalFile.toURI().toURL();

    private static File readJBossPhysicalFile(Object content) throws Exception {
        Method method = content.getClass().getDeclaredMethod("getPhysicalFile");
        return (File) method.invoke(content);
    }

这样就会返回以上的文件目录的一个url对象,而实现上,这个url对象下面没有任何class文件,自然就不会返回任何信息。
以上的问题,只存在于我们要查找的类在一个jar中的情况,如果在classes目录下,是没有问题的。

解决这个问题,我们需要使用另一个组件:reflections。官方地下:http://code.google.com/p/reflections/

继续阅读“xwork classFinder在jboss 7环境不能正确处理url resource的问题以及解决方法”

在struts2方法上直接使用参数(不带注解)进行逻辑处理

众所周知,在使用struts2时,所写的逻辑方法都是无参数的,所以的参数都是写在action内部的。如果一个action方法过多,而每个方法所使用的参数都不尽相同时,就会造成一个action内参数过多,且每个参数都有get/set,造成程序混乱,并且在可读性和使用上都不太方便。因为,你不知道你所调用的方法使用了哪些参数,而这个方法会返回哪些结果,在界面上哪些get对象是可以使用的。

那么,能否直接在方法上使用参数呢,就像在action里面一样,直接注入,直接使用,并且没有副作用呢?你想像使用spring mvc甚至更好的方式(无注解)使用struts2吗?这种想法是可以滴,当然现有的struts2是不支持滴。不过,我们可以修改之,让其支持。
本篇所使用以及参考的相关技术前提(可google之)

  • struts2(xwork)中valueStack中的工作原理
  • 在valueStack中CompoundRoot对象如何使用
  • OGNL的propertyAccessor以及扩展
  • struts2(xwork)所提供的ognl扩展
  • 使用spring中所提供的localVariable访问方法参数信息
  • java编译保存方法变量信息

本篇所提供内容工作前提

  • action中每个方法名称惟一(不支持方法重载)
  • java文件编译时保存了调试信息中的方法变量信息

本篇技术内容索引

  1. 获取方法信息
  2. 方法参数注入
  3. 方法调用调整
  4. Map及List泛型参数注入修正
  5. 方法内数据返回

继续阅读“在struts2方法上直接使用参数(不带注解)进行逻辑处理”

使用struts2的builder alias机制加载objectFactory

以下代码基于struts2版本2.1.8.1版本分析。
在使用Struts2的过程中,我们都喜欢使用struts2的spring插件来让spring作为struts2的默认对象容器,原理就在于在加载struts2之前先加载spring容器,然后将spring容器加载至applicationContext中,在struts2的objectFactory(称之为对象容器)实现中,找到spring容器并进行各项对象创建工作。

在spring插件中,使用了StrutsSpringObjectFactory类来作为struts2的对象容器,实现过程即除重写objectFactory的各项buildBean方法以符合spring规范之外,其它则就是根据struts2的各项参数设置spring参数(如autoType等)。之所以使用此类作为struts2的对象容器,原因就在于在struts2-spring.jar中的struts-plugin.xml中定义了如下的声明:

<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
    
    <constant name="struts.objectFactory" value="spring" />

第一句是声明了一个实现类objectFactory的对象,这就是spring插件所提供的对象容器,而第二句则声明属性struts.objectFactory的值为spring,即key为spring的对象将成为struts2的对象容器。

为什么这样说,我们可以看一下struts2对struts.objectFactory的解释,以下解释摘自struts2中的default.properties:

### if specified, the default object factory can be overridden here
### Note: short-hand notation is supported in some cases, such as "spring"
###       Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here

即只要设置了此值,则默认的对象容器,将被改写,那么spring插件所提供的功能就是定义了一个spring实现的对象容器,并且重写了struts2定义,将spring容器再成为struts2的对象容器。

继续阅读“使用struts2的builder alias机制加载objectFactory”