`

Struts2参数传递

阅读更多

本篇主要通过实例来讲述Struts2中各种各样的参数传递。这个参数传递的过程主要指数据从View层传递到Control层时Struts2的工作方式。根据前两篇文章的知识,我们知道,Struts2完成参数传递处理工作的基础是OGNL和ValueStack。而在这个过程中,我也把Struts2所要做的工作大致归纳为两个方面:

1. 对OGNL操作进行封装,完成OGNL表达式所表示的值到Java对象的值传递机制

2. 在参数传递的过程中,做恰当的类型转化,保证页面上的字符串能够转化成各式各样的Java对象


接下来,通过四个不同的角度,来具体讲述Struts2在这两个方面的工作。

最简单的参数传递

使用OGNL的最基本的功能,就能完成普通的Java对象的赋值工作。Struts2在内部已经完成了OGNL的基本封装。这些封装包括对OGNL表达式到Java对象的赋值机制,以及对基本的Java类型的类型转化支持。这些基本类型包括String、Number(以及其基本类型int、float、double等)、Boolean(boolean)、数组、Class、Date等类型。

在这里我想额外强调的是XWork对JDK5.0中的Enum类型和Date类型的支持。

Enum类型

枚举类型是JDK5.0引入的新特性。枚举类型也能解决很多实际问题,是J2EE编程中的最佳实践之一。XWork中,有一个专门的EnumTypeConverter负责对Enum类型的数据进行转化。

Java代码 复制代码
  1. public class EnumTypeConverter extends DefaultTypeConverter {   
  2.   
  3.     /**  
  4.      * Converts the given object to a given type. How this is to be done is implemented in toClass. The OGNL context, o  
  5.      * and toClass are given. This method should be able to handle conversion in general without any context or object  
  6.      * specified.  
  7.      *  
  8.      * @param context - OGNL context under which the conversion is being done  
  9.      * @param o       - the object to be converted  
  10.      * @param toClass - the class that contains the code to convert to enumeration  
  11.      * @return Converted value of type declared in toClass or TypeConverter.NoConversionPossible to indicate that the  
  12.      *         conversion was not possible.  
  13.      */  
  14.     public Object convertValue(Map context, Object o, Class toClass) {   
  15.         if (o instanceof String[]) {   
  16.             return convertFromString(((String[]) o)[0], toClass);   
  17.         } else if (o instanceof String) {   
  18.             return convertFromString((String) o, toClass);   
  19.         }   
  20.   
  21.         return super.convertValue(context, o, toClass);   
  22.     }   
  23.   
  24.     /**  
  25.      * Converts one or more String values to the specified class.  
  26.      * @param value - the String values to be converted, such as those submitted from an HTML form  
  27.      * @param toClass - the class to convert to  
  28.      * @return the converted object  
  29.      */  
  30.     public java.lang.Enum convertFromString(String value, Class toClass) {   
  31.         return Enum.valueOf(toClass, value);   
  32.     }   
  33.   
  34. }  
public class EnumTypeConverter extends DefaultTypeConverter {

    /**
     * Converts the given object to a given type. How this is to be done is implemented in toClass. The OGNL context, o
     * and toClass are given. This method should be able to handle conversion in general without any context or object
     * specified.
     *
     * @param context - OGNL context under which the conversion is being done
     * @param o       - the object to be converted
     * @param toClass - the class that contains the code to convert to enumeration
     * @return Converted value of type declared in toClass or TypeConverter.NoConversionPossible to indicate that the
     *         conversion was not possible.
     */
    public Object convertValue(Map context, Object o, Class toClass) {
        if (o instanceof String[]) {
            return convertFromString(((String[]) o)[0], toClass);
        } else if (o instanceof String) {
            return convertFromString((String) o, toClass);
        }

        return super.convertValue(context, o, toClass);
    }

    /**
     * Converts one or more String values to the specified class.
     * @param value - the String values to be converted, such as those submitted from an HTML form
     * @param toClass - the class to convert to
     * @return the converted object
     */
    public java.lang.Enum convertFromString(String value, Class toClass) {
        return Enum.valueOf(toClass, value);
    }

}



有了这个类,我们就可以比较轻松的对枚举类型进行数据赋值了。

Java代码 复制代码
  1. public enum Gender {   
  2.        
  3.     MALE, FEMALE   
  4.   
  5. }  
public enum Gender {
    
    MALE, FEMALE

}


Html代码 复制代码
  1. <form method="post" action="/struts-example/enum-conversion.action">  
  2.     <input type="text" name="user.name" value="downpour" />  
  3.     <select name="user.gender">  
  4.        <option value="MALE"></option>  
  5.        <option value="FEMALE"></option>  
  6.     </select>  
  7.     <input type="submit" value="submit" />  
  8. </form>  
<form method="post" action="/struts-example/enum-conversion.action">
    <input type="text" name="user.name" value="downpour" />
    <select name="user.gender">
       <option value="MALE">男</option>
       <option value="FEMALE">女</option>
    </select>
    <input type="submit" value="submit" />
</form>


Java代码 复制代码
  1. public class EnumConversionAction extends ActionSupport {   
  2.   
  3.     private static final Log logger = LogFactory.getLog(Policy.class);   
  4.        
  5.     private User user;   
  6.        
  7.     /* (non-Javadoc)  
  8.      * @see com.opensymphony.xwork2.ActionSupport#execute()  
  9.      */  
  10.     @Override  
  11.     public String execute() throws Exception {   
  12.         logger.info("user's gender:" + user.getGender());   
  13.         return super.execute();   
  14.     }   
  15.        
  16.     // setters and getters   
  17. }  
public class EnumConversionAction extends ActionSupport {

    private static final Log logger = LogFactory.getLog(Policy.class);
    
    private User user;
    
    /* (non-Javadoc)
     * @see com.opensymphony.xwork2.ActionSupport#execute()
     */
    @Override
    public String execute() throws Exception {
        logger.info("user's gender:" + user.getGender());
        return super.execute();
    }
    
    // setters and getters
}



通过上面的代码,就完成了对枚举类型的赋值。不过这里有一点需要特别指出:那就是XWork在XWork-2.1.X的版本之前,枚举类型不被默认支持。如果你需要获得枚举类型的自动赋值,还需要增加一个配置文件xwork-conversion.properties到classpath下:

Java代码 复制代码
  1. java.lang.Enum=com.opensymphony.xwork2.util.EnumTypeConverter  
java.lang.Enum=com.opensymphony.xwork2.util.EnumTypeConverter


对于使用新的版本的XWork的朋友,则不需要增加这个配置文件。

Date类型

XWork默认是支持Date类型的转化的。不过从源码上来看,貌似我们很难用上它默认的类型转化。

Java代码 复制代码
  1. private Object doConvertToDate(Map context, Object value, Class toType) {   
  2.         Date result = null;   
  3.   
  4.         if (value instanceof String && value != null && ((String) value).length() > 0) {   
  5.             String sa = (String) value;   
  6.             Locale locale = getLocale(context);   
  7.   
  8.             DateFormat df = null;   
  9.             if (java.sql.Time.class == toType) {   
  10.                 df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);   
  11.             } else if (java.sql.Timestamp.class == toType) {   
  12.                 Date check = null;   
  13.                 SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,   
  14.                         DateFormat.MEDIUM,   
  15.                         locale);   
  16.                 SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,   
  17.                         locale);   
  18.   
  19.                 SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,   
  20.                         locale);   
  21.   
  22.                 SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};   
  23.                 for (int i = 0; i < fmts.length; i++) {   
  24.                     try {   
  25.                         check = fmts[i].parse(sa);   
  26.                         df = fmts[i];   
  27.                         if (check != null) {   
  28.                             break;   
  29.                         }   
  30.                     } catch (ParseException ignore) {   
  31.                     }   
  32.                 }   
  33.             } else if (java.util.Date.class == toType) {   
  34.                 Date check = null;   
  35.                 SimpleDateFormat d1 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);   
  36.                 SimpleDateFormat d2 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);   
  37.                 SimpleDateFormat d3 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);   
  38.                 SimpleDateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");   
  39.                 SimpleDateFormat[] dfs = {d1, d2, d3, rfc3399}; //added RFC 3339 date format (XW-473)   
  40.                 for (int i = 0; i < dfs.length; i++) {   
  41.                     try {   
  42.                         check = dfs[i].parse(sa);   
  43.                         df = dfs[i];   
  44.                         if (check != null) {   
  45.                             break;   
  46.                         }   
  47.                     }   
  48.                     catch (ParseException ignore) {   
  49.                     }   
  50.                 }   
  51.             }   
  52.             //final fallback for dates without time   
  53.             if (df == null) {   
  54.                 df = DateFormat.getDateInstance(DateFormat.SHORT, locale);   
  55.             }   
  56.             try {   
  57.                 df.setLenient(false); // let's use strict parsing (XW-341)   
  58.                 result = df.parse(sa);   
  59.                 if (!(Date.class == toType)) {   
  60.                     try {   
  61.                         Constructor constructor = toType.getConstructor(new Class[]{long.class});   
  62.                         return constructor.newInstance(new Object[]{new Long(result.getTime())});   
  63.                     } catch (Exception e) {   
  64.                         throw new XWorkException("Couldn't create class " + toType + " using default (long) constructor", e);   
  65.                     }   
  66.                 }   
  67.             } catch (ParseException e) {   
  68.                 throw new XWorkException("Could not parse date", e);   
  69.             }   
  70.         } else if (Date.class.isAssignableFrom(value.getClass())) {   
  71.             result = (Date) value;   
  72.         }   
  73.         return result;   
  74.     }  
private Object doConvertToDate(Map context, Object value, Class toType) {
        Date result = null;

        if (value instanceof String && value != null && ((String) value).length() > 0) {
            String sa = (String) value;
            Locale locale = getLocale(context);

            DateFormat df = null;
            if (java.sql.Time.class == toType) {
                df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
            } else if (java.sql.Timestamp.class == toType) {
                Date check = null;
                SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,
                        DateFormat.MEDIUM,
                        locale);
                SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,
                        locale);

                SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,
                        locale);

                SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};
                for (int i = 0; i < fmts.length; i++) {
                    try {
                        check = fmts[i].parse(sa);
                        df = fmts[i];
                        if (check != null) {
                            break;
                        }
                    } catch (ParseException ignore) {
                    }
                }
            } else if (java.util.Date.class == toType) {
                Date check = null;
                SimpleDateFormat d1 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);
                SimpleDateFormat d2 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
                SimpleDateFormat d3 = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);
                SimpleDateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                SimpleDateFormat[] dfs = {d1, d2, d3, rfc3399}; //added RFC 3339 date format (XW-473)
                for (int i = 0; i < dfs.length; i++) {
                    try {
                        check = dfs[i].parse(sa);
                        df = dfs[i];
                        if (check != null) {
                            break;
                        }
                    }
                    catch (ParseException ignore) {
                    }
                }
            }
            //final fallback for dates without time
            if (df == null) {
                df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
            }
            try {
                df.setLenient(false); // let's use strict parsing (XW-341)
                result = df.parse(sa);
                if (!(Date.class == toType)) {
                    try {
                        Constructor constructor = toType.getConstructor(new Class[]{long.class});
                        return constructor.newInstance(new Object[]{new Long(result.getTime())});
                    } catch (Exception e) {
                        throw new XWorkException("Couldn't create class " + toType + " using default (long) constructor", e);
                    }
                }
            } catch (ParseException e) {
                throw new XWorkException("Could not parse date", e);
            }
        } else if (Date.class.isAssignableFrom(value.getClass())) {
            result = (Date) value;
        }
        return result;
    }



这段代码就是XWork处理将String转成Date类型的过程,从整个过程上来看,我们很难用上这段代码,因为我们在界面上的Date类型的表现形式往往是:'yyyy-MM-dd'或者相关的形式,很明显,上面的流程无法匹配这样的日期类型。

所以,针对Date,我们往往会自定义一个日期转化的类进行处理,这个在下面会有具体的介绍。

Array、List、Map等容器类型的参数传递

除了简单的基于JavaBean方式的参数传递支持,Struts2还支持对Array、List、Map等容器类型的数据结构做数据赋值。不过历史一路走来,XWork针对容器类型的数据赋值一直有变化,让我们慢慢解读这些变化,从而也来看看编程思路是如何改变的。

1. 2004年,XWork-1.0.X的年代

当时XWork所支持的针对容器的数据赋值还比较土。这方面moxie在论坛上有一篇文章专门来讲述:http://www.iteye.com/topic/8770

总的来说,那个年代对于容器的数据赋值,需要依赖于XWork的辅助类。我们可以看到,如果你要对List进行赋值,需要新建一个XWorkList的实现类,并把所需要进行数据赋值的Java类传递到XWorkList的构造函数中。而对Map等对象的赋值,也同理可得。

这种数据赋值的方式的优缺点都非常明显。优点在于简单,你不需要额外定义任何其他的内容,而是直接使用XWork的辅助类来实现类型转化。缺点在于扩展性很弱,很明显,针对某一个具体的容器,就需要一个XWork的实现类,List有XWorkList对应,Map有XWorkMap对应。甚至在那个时候,还没有Set的支持,因为没有XWorkSet的实现。所以使用这种方式,在扩展性方面需要遭受严重的考验。

2. 2006年,XWork-2.0.X的年代

也许是XWork团队看到了扩展性上的问题,所以在XWork和Webwork同时升级以后,采用了新的方式来处理容器赋值。而此时,Javaeye上也涌现出了新的文章,Tin同学对新的方式做了详细的表述:http://www.iteye.com/topic/17939

不过这个新的整合方式似乎并不被大家所看好。

lllyq 写道
我觉得XWorkList, XWorkMap还是很有用的,挺好的设计,其实没有必要deprecated。


moxie 写道
集合支持不向下兼容。XWorkList已经是@deprecated,用它就错,还不如直接删除掉。在webwork2.2中,它需要为集合另外配置一个conversion.properties文件。真不明白,这样有什么优点?



这种新的整合方式,实际上只是解决了针对容器赋值,不需要依赖XWork的辅助类这样的一个问题,不过其付出的代价,却是多了一个配置文件,这也让人非常郁闷。好好的类型转化,平白无故多出了一个同package下的配置文件,这也无形中增加了编程的复杂度。

3. 现在,拥抱了泛型和Annotation的年代

实际上,在XWork发展到XWork-2.0.X之后,也开始注重了对泛型和Annotation的支持。所以,容器类型的转化,我们也可以尝试一下使用JDK的新特性来进行,当然这也是目前最为推荐的做法。

下面分别给出使用泛型和Annotation的代码示例:

Html代码 复制代码
  1. <form method="post" action="/struts-example/ognl-collection-conversion.action">  
  2.     <input type="text" name="users[0].name" value="aaa" />  
  3.     <input type="text" name="users[1].name" value="bbb" />  
  4.     <input type="text" name="users2[0].name" value="ccc" />  
  5.     <input type="text" name="users2[1].name" value="ddd" />  
  6.     <input type="text" name="userMap['user1'].name" value="eee" />  
  7.     <input type="text" name="userMap['user2'].name" value="fff" />  
  8.     <input type="text" name="userMap2['user3'].name" value="ggg" />  
  9.     <input type="text" name="userMap2['user4'].name" value="hhh" />  
  10.     <input type="submit" value="submit" />  
  11. </form>  
<form method="post" action="/struts-example/ognl-collection-conversion.action">
    <input type="text" name="users[0].name" value="aaa" />
    <input type="text" name="users[1].name" value="bbb" />
    <input type="text" name="users2[0].name" value="ccc" />
    <input type="text" name="users2[1].name" value="ddd" />
    <input type="text" name="userMap['user1'].name" value="eee" />
    <input type="text" name="userMap['user2'].name" value="fff" />
    <input type="text" name="userMap2['user3'].name" value="ggg" />
    <input type="text" name="userMap2['user4'].name" value="hhh" />
    <input type="submit" value="submit" />
</form>


Java代码 复制代码
  1. public class OgnlConversionAction extends ActionSupport {   
  2.   
  3.     private static final long serialVersionUID = 4396125455881691845L;   
  4.   
  5.     private static final Log logger = LogFactory.getLog(Policy.class);   
  6.        
  7.     private List<User> users;   
  8.        
  9.     @Element(value = User.class)   
  10.     private List users2;   
  11.        
  12.     private Map<String, User> userMap;   
  13.        
  14.     @Element(value = User.class)   
  15.     private Map userMap2;   
  16.        
  17.     /* (non-Javadoc)  
  18.      * @see com.opensymphony.xwork2.ActionSupport#execute()  
  19.      */  
  20.     @Override  
  21.     public String execute() throws Exception {   
  22.            
  23.         // -> aaa   
  24.         logger.info("users[0].name : " + users.get(0).getName());   
  25.         // -> bbb   
  26.         logger.info("users[1].name : " + users.get(1).getName());   
  27.         // -> ccc   
  28.         logger.info("users2[0].name : " + ((User)users2.get(0)).getName());   
  29.         // -> ddd   
  30.         logger.info("users2[1].name : " + ((User)users2.get(1)).getName());   
  31.            
  32.         // -> [user1, user2]   
  33.         logger.info("userMap.key : " + userMap.keySet());   
  34.         // -> eee   
  35.         logger.info("userMap.key = " + "user1" + " : " + "userMap.value(user1's name) = " + userMap.get("user1").getName());   
  36.         // -> fff   
  37.         logger.info("userMap.key = " + "user2" + " : " + "userMap.value(user2's name) = " + userMap.get("user2").getName());   
  38.         // -> [user3, user4]   
  39.         logger.info("userMap2.key : " + userMap2.keySet());   
  40.         // -> ggg   
  41.         logger.info("userMap2.key = " + "user3" + " : " + "userMap.value(user3's name) = " + ((User)userMap2.get("user3")).getName());   
  42.         // -> hhh   
  43.         logger.info("userMap2.key = " + "user4" + " : " + "userMap.value(user4's name) = " + ((User)userMap2.get("user4")).getName());   
  44.            
  45.         return super.execute();   
  46.     }   
  47.        
  48.     // setters and getters   
  49. }  
public class OgnlConversionAction extends ActionSupport {

    private static final long serialVersionUID = 4396125455881691845L;

    private static final Log logger = LogFactory.getLog(Policy.class);
    
    private List<User> users;
    
    @Element(value = User.class)
    private List users2;
    
    private Map<String, User> userMap;
    
    @Element(value = User.class)
    private Map userMap2;
    
    /* (non-Javadoc)
     * @see com.opensymphony.xwork2.ActionSupport#execute()
     */
    @Override
    public String execute() throws Exception {
        
        // -> aaa
        logger.info("users[0].name : " + users.get(0).getName());
        // -> bbb
        logger.info("users[1].name : " + users.get(1).getName());
        // -> ccc
        logger.info("users2[0].name : " + ((User)users2.get(0)).getName());
        // -> ddd
        logger.info("users2[1].name : " + ((User)users2.get(1)).getName());
        
        // -> [user1, user2]
        logger.info("userMap.key : " + userMap.keySet());
        // -> eee
        logger.info("userMap.key = " + "user1" + " : " + "userMap.value(user1's name) = " + userMap.get("user1").getName());
        // -> fff
        logger.info("userMap.key = " + "user2" + " : " + "userMap.value(user2's name) = " + userMap.get("user2").getName());
        // -> [user3, user4]
        logger.info("userMap2.key : " + userMap2.keySet());
        // -> ggg
        logger.info("userMap2.key = " + "user3" + " : " + "userMap.value(user3's name) = " + ((User)userMap2.get("user3")).getName());
        // -> hhh
        logger.info("userMap2.key = " + "user4" + " : " + "userMap.value(user4's name) = " + ((User)userMap2.get("user4")).getName());
        
        return super.execute();
    }
    
    // setters and getters
}



上面的代码中,我们可以看到,如果你使用泛型,那么你无需再使用任何额外的配置文件或者Annotation,XWork会把一切都为你准备好。如果你没有使用泛型,那么你可以使用Annotation来指定你需要进行转化的对象类型。其中,对Map对象使用Annotation时,Element中的value所对应的值,是Map中的value所对应的class。

由此可见,泛型和Annotation,在一定程度上,还是可以简化我们很多工作的。

文件上传

文件上传其实也是参数传递的一种,所以从方案上来讲,Struts2同样使用了一个拦截器来处理。而这个拦截器,同样来自于原来的Webwork,基本上没有做什么很大的改变。有关这个拦截器的详细内容,我们也留一个悬念,在后续章节中详细讲解。目前,你只要知晓,这个拦截器能帮助你完成一切文件上传相关的机制。

早在2005年,Quake Wang就对Webwork的文件上传机制有了详细的讲解:http://www.iteye.com/topic/10697

在这里我简单小结一下在进行文件上传时的三大要点:

1. 在配置文件上传时,拦截器的顺序非常关键

Xml代码 复制代码
  1. <interceptor-stack name="uploadStack">     
  2.     <interceptor-ref name="upload"/>                     
  3.     <interceptor-ref name="defaultStack"/>     
  4. </interceptor-stack>  
<interceptor-stack name="uploadStack">  
    <interceptor-ref name="upload"/>                  
    <interceptor-ref name="defaultStack"/>  
</interceptor-stack>



具体来说,upload的拦截器,必须在params的拦截器之前

2. 拦截器额外提供了一些额外的文件信息

Quake Wang 写道
ContentType: 文件的ContentType(可以用在做download的时候)
FileName: 实际的文件名
在上面的action例子里, 那么有uploadFilesContentType和uploadFilesFileName这2个属性, 也能够被自动绑定



3. 拦截器提供的文件上传功能,你得到的是一个临时文件

robbin 写道
在webwork的file upload 拦截器功能中,它提供的File只是一个临时文件,Action执行之后就会被自动删除,因此你必须在Action中自己出来文件的存储问题,或者写到服务器的某个目录,或者保存到数据库中。如果你准备写到服务器的某个目录下面的话,你必须自己面临着处理文件同名的问题



而时代发展到Struts2的年代,对于文件上传的整体机制没有做

分享到:
评论

相关推荐

    struts2 向结果传参数

    NULL 博文链接:https://cdxs2.iteye.com/blog/1926357

    Struts2中的参数传递

    我们知道,Struts2完成参数传递处理工作的基础是OGNL和ValueStack。而在这个 过程中,我也把Struts2所要做的工作大致归纳为两个方面: 1. 对OGNL操作进行封装,完成OGNL表达式所表示的值到Java对象的值传递机制 2. ...

    AJAX和struts2传递JSON数组

    利用AJAX传递JSON数组,后台struts2的action接收。 详细代码简单易懂。

    struts2支持方法上传递参数

    在struts2中可以在方法上传递相应的参数,不需要使用注解,直接使用参数名进行界面传递参数信息,并且可以在界面进行访问

    Struts2学习笔记(5)-参数传递方法

    本文主要介绍Struts2中参数传递方法,希望能给大家做一个参考。

    uploadify3与struts2结合实现有进度条文件上传实例

    这是根据uploadify3 2结合struts2搭建的文件上传环境 可以直接导入eclipse运行 每步实现基本都加了注释 以下是我碰到的问题: 1 判断session是否失效 本实例没测试这个问题 但在工作项目中碰到了 但原因在这里...

    struts2传递参数及ModelDriven的使用示例

    刚开始学struts2时,自己写的小工程。

    struts2验证框架

    struts2 验证框架,彻底简化判断页面传递过来的参数,必学内容

    Struts2+JasperReport报表应用

    而随着Struts2的流行,就应该研究一下在Struts2下如何利用JasperReports进行报表输出。本示例比较简单,采用的数据源即为JavaBean,而没有采用复杂的数据库,其实原理是一样的。只是传递给JasperReports的参数随着...

    struts2 +jquey uploadify3.2 实现多文件上传

    fileID:要取消的列队文件id 不传递参数时 表示取消列队中的第一个文件上传 传递星号 表示取消列队中的所有文件上传 suppressEvent:设置为true将禁止onUploadCancel事件 取值:String &quot;true&quot;|&quot;事件...

    Struts2 in action中文版

    第1章 Struts 2:现代Web框架 2 1.1 Web应用程序:快速学习 2 1.1.1 构建Web应用程序 2 1.1.2 基础技术简介 3 1.1.3 深入研究 6 1.2 Web应用程序框架 7 1.2.1 什么是框架 7 1.2.2 为什么使用框架 8 1.3 Struts 2框架...

    struts2的详细资料

    struts2的资料以及struts的ui标签的使用,struts2如何和ajax进行参数传递

    struts2中action接收参数的方式

    程序参考源代码 博文链接:https://honly-java.iteye.com/blog/1605764

    非常不错的中文struts2教程[CHM]

    内容: 1、OGNL —— 数据运转的催化剂 2、Result机制,让视图更丰富 ...5、Struts2中的参数传递 6、标签库,永恒的争论话题 7、拦截器详解 8、配置,灵活还是简单? 9、深入plugin 10、在Struts2中使用OGNL

    uploadify+struts2+json前台动态向后台传数据

    uploadify+struts2+json 前台动态向后台传数据,并显示后台返回参数完成文件上传功能

    struts2重定向实例源码

    struts result类型中redirect与redirectAction的使用 包括参数传递。

    struts2的总结,适合初学者

    4、在action中把HttpServletRequest参数和HttpServletResponse参数传递过去。 5、在过滤器中通过java的反射机制调用action。 6、详细过程参照cn.itcast.action包中的内容 3Struts2介绍 1、struts2是apache组织发明的...

    一步步学习Struts2

    内容包括ognl,result机制,struts2配置详解,struts2中的action,struts2中的参数传递,标签库,拦截器的详解,深入plugin

    深入浅出Struts2(附源码)

    3.3 把静态参数传递给一个动作 41 3.4 ActionSupport类 41 3.5 结果 42 3.5.1 Chain 43 3.5.2 Dispatcher 44 3.5.3 FreeMarker 44 3.5.4 HttpHeader 44 3.5.5 Redirect 45 3.5.6 Redirect Action 46 3.5.7 ...

    Struts2 完整的日本项目

    刚完成的 日本的项目 struts2 jdom解析 远端服务器 xml 文件 自定义struts2 标签分页 分页只需要向 其 传递2参数 页面上 自定义的标签 自动分页

Global site tag (gtag.js) - Google Analytics