[Struts]Struts2的开发步骤

来源:互联网 发布:淘宝虾米vip怎么兑换 编辑:程序博客网 时间:2024/04/29 13:46

1. Struts2的开发步骤

 1) 在classpath中添加如下包:

    struts2-core-2.1.8.1.jar, xwork-core-2.1.6.jar, ognl-2.7.3.jar, freemarker-2.3.15.jar, common-fileupload-1.2.1.jar, common-io-1.3.2.jar

 2) 在web.xml中添加过滤器:

    <filter>

        <filter-name>struts2</filter-name>

        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 3) 在classpath中添加Struts2的配置文件struts.xml:

 4) 编写Action类。

=======================================================================================

1. Struts2整合Spring

 1) 添加Struts2和Spring需要的Jar包到classpath中。

 2) 在应用的classpath路径下添加strut2配置文件(struts.xml)和spring配置文件(applicationContext.xml)。

 3) 把struts2-spring-plugin-xxx.jar插件包添加到应用的classpath路径下。

 4) 把strut2框架的对象工厂设置为Spring提供:在struts.xml配置文件中添加常量配置

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

 5) 在web.xml中配置监听器来初始化Spring的ApplicationContext:具体配置参见Spring应用

 6) 把需要由Spring管理的Action类等配置到Spring配置文件中。

    struts.xml中Action的配置如下:

    <action name="login" class="accountAction">

<result name="success">/success.jsp</result>

<result name="error">/error.jsp</result>

</action>

那么在Spring配置文件中需要添加如下bean的配置:

<bean name="accountAction" class="com.qiujy.web.action.AccountAction">

<property name="accountService" ref="accountService"/>

</bean>

==============================================================================================

1. Struts2中基于注解的Action配置

  1) @ParentPackage 指定父包

  2) @Namespace 指定命名空间

  3) @Results 一组结果的数组

  4) @Result(name="success",location="/msg.jsp") 一个结果的映射

  5) @Action(value="login") 指定某个请求处理方法的请求URL。注意,它不能添加在Action类上,要添加到方法上。

  6) @ExceptionMappings 一级声明异常的数组

  7) @ExceptionMapping 映射一个声明异常

==============================================================================================

1. Struts2中的OGNL的使用。

2. OGNL:对象图导航语言。通过OGNL表达式可以获取对象的属性,调用对象的方法,或构造出对象。

  1) OGNL上下文中有一个根对象。这个根对象可以直接获取。不需要#。

  2)支持常量:

         字符串常量、字符常量、

         数值常量:int、long、float、double

         布尔常量:true、false

    Null常量 : null

         支持操作符:支持Java的所有操作符,还支持特有的操作符: , {}、in、not in;

3. Struts2中的OGNL:

  1) Struts2将ActionContext设置为OGNL上下文,并将值栈(ValueStack)作为OGNL的根对象放置到ActionContext中。

  2) Struts2总是把当前Action实例放置在值栈的栈顶。所以,在OGNL中引用Action中的属性也可以省略“#”。

4. 常用标签

 1) <s:property value="OGNL"/>

 2) <s:date name="OGNL" format=""/>

 3) <s:if test="OGNL"></s:if><s:elseif test="OGNL"></s:elseif><s:else></s:else>

★4) <s:iterator value="OGNL" status="vs">...</s:iterator>

 5) <s:debug/>

==============================================================================================================

 1. Struts2中的类型转换器

  1) Struts2中内置了一些常用的类型转换器:可以把客户端提交的String数据转换成对应类型的数据。

     a) 基本类型

     b) java.util.Date:

     c) 数组和列表

  2) 自定义类型转换器:

     a) 继承自org.apache.struts2.util.StrutsTypeConverter类

  public abstract Object convertFromString(Map context, String[] values, Class toClass);

        context:OGNL上下文的Map对象

        values :需要转换的字符串数组

        toClass:要转换的目标类型

  public abstract String convertToString(Map context, Object o);

         context:OGNL上下文的Map对象

         o:需要转换的对象

     b) 注册:以全局方式

                    在应用程序的classpath下创建一属性文件,名为:xwork-conversion.properties

                    文件内容:待转换类型的全限定名=类型转换器类的全限定名

  3) 转换Set:

     0) Action中的Set属性需要进行初始化:如:

        private Set<User> userSet = new HashSet<User>();

     a) 添加针对某个Action的转换器配置文件:ActionName-conversion.properties 如:

        UserAction-conversion.properties

     b) 在这个文件中添加:Action的Set属性的相关配置

        Element_属性名=Set中的元素类型的全限定名                 #指定Set中的元素类型

        KeyProperty_属性名=Set中的元素类型中的某个属性  #指定Set的索引字段

                   如下示例:

        Element_userSet=com.qiujy.domain.User

        KeyProperty_userSet=id

     c) JSP页面: <input type="text" name="Set属性名.makeNew[0].属性名"/>

                    如:<input type="text" name="userSet.makeNew[0].loginname"/>

遗留问题

1. Map类型怎么转换?

2. 类型转换错误处理时,怎么不跳转到input结果页?

================================================================================

1. Struts2中的输入校验

2. 编码方式校验

  1) Action一定要继承自ActionSupport

  2) 针对某个要进行校验的请求处理方法编写一个 public void validateXxx()方法,在方法内部进行表单数据校验.

  3) 也可针对所有的请求处理方法编写public void validate()方法。

  4) 在校验方法中,可以通过addFieldError()方法来添加字段校验错误消息。

  5) 当校验失败时,Struts框架会自动跳转到name为input的Result页面。在校验失败页面中,可以使用<s:fielderror/>来显示错误消息

  6) 简单,灵活。但重用性不高。

3. XML配置方式校验。在编码方式之前被执行。

  1) 针对要校验的Action类,在同包下编写一个名为:Action类名-validation.xml校验规则文件。

  2) 在校验规则文件中添加校验规则:具体的校验器名,参数可参看Struts2的reference或Struts2的API。

     a) Field校验:针对Action类中每个非自定义类型的Field进行校验的规则。

    <field name="要校验的Field名">

   <field-validator type="校验规则器名" short-circuit="是否要短路径校验(默认是false)">

       <param name="校验器要使用的参数名">值</param>

            <message>校验失败时的提示消息</message>

</field-validator>

<!-- 还可添加其它的校验规则 -->

</field>


     b) 非Field校验:针对Action类的某些Field使用OGNL表达进行组合校验。

    <validator type="fieldexpression">

<param name="fieldName">pwd</param>

     <param name="fieldName">pwd2</param>

     <param name="expression"><![CDATA[pwd==pwd2]]></param><!-- OGNL表达式 -->

     <message>确认密码和密码输入不一致</message>

</validator>


     c) visitor校验:主要是用来校验Action类中的自定义类型Field。(针对使用模型驱动方式时)

       i) 在Action类的的校验规则文件中针对自定义类型Field使用visitor校验规则。

    <!-- 针对自定义Field使用visitor校验 -->

<field name="user">

<field-validator type="required" short-circuit="true">

            <message>用户的信息必填</message><!-- 消息前缀 -->

</field-validator>

<field-validator type="visitor"><!-- 指定为visitor校验规则 -->

<param name="context">userContext</param><!-- 指定本visitor校验的上下文名 -->

            <param name="appendPrefix">true</param><!-- 是否要添加校验失败消息的前缀 -->

            <message>用户的</message><!-- 消息前缀 -->

</field-validator>

</field>

  ii) 针对visitor的Field编写一个校验规则文件.文件名为: visitor字段类型名[-visitor校验的上下文名]-validation.xml. 例如: 本例中的文件名为User-userContext-validation.xml

                注意: 此文件要存放到visitor字段类型所在的包下.

  iii) 在visitor的Field校验规则文件中针对要校验的Field添加校验规则.

   3) 在校验失败页面(名为input的result页面)中,可以使用<s:fielderror/>来显示错误消息。

   4) 默认情况下,XML的校验规则对Action中所有的请求处理方法生效.此时应该只针对每个要校验的请求处理方法指定校验。有两种方式:

      i) 只为Action中的指定方法指定校验规则文件,配置文件命名为:Action类型名-别名-validation.xml,

                      别名是要校验的方法对应的Action标签的name属性值。

                      如:UserAction在struts2.xml的配置为:

    <package name="my" extends="struts-default" namespace="/">

<action name="user_*" class="com.qiujy.web.action.UserAction" method="{1}">

<result name="success">/info.jsp</result>

<result name="input">/user_{1}.jsp</result>

</action>

    </package>             

                ● UserAction中有registe方法和login方法,要对registe方法进行校验,则它的校验规则文件名为:UserAction-user_registe-validation.xml。

                 ● 如果使用visitor校验器,必需指定visitor校验的上下文名。

      ii) 在校验拦截器中指定要验证的方法。不太实用。

   <action name="user_*" class="com.qiujy.web.action.UserAction" method="{1}">

    <result name="success">/info.jsp</result>

    <result name="input">/user_{1}.jsp</result>

     <interceptor-ref name="defaultStack">

        <!-- 给校验拦截器指定不进行校验的方法列表:用逗号隔开 -->

        <param name="validation.excludeMethods">*</param>

        <!-- 给校验拦截器指定要进行校验的方法列表:用逗号隔开 -->

        <param name="validation.includeMethods">regist</param>

      </interceptor-ref>

   </action>

   5) 同时使用客户端校验和服务器端校验

      i) 设置<s:form>标签的validate属性:

         false:默认值。校验框架只执行服务器端校验。

         true:先执行客户端校验,然后再执行服务器端校验。

         form标签会根据你在服务器端配置的验证规则生成对应的JavaScript验证代码。

                      目前支持的内置校验器:required、requiredstring、stringlength、regex validator、email、url、int、double

      ii) 不太好用,不建议使用。建议使用jQuery进行页面表单校验。

   6) 自定义校验器:

      i) 继承自FieldValidatorSupport抽象类。重写validate(Object obj)方法

      ii) 注册校验器类. 在应用程序的classpath下新建一校验器注册文件。名为validators.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE validators PUBLIC

        "-//OpenSymphony Group//XWork Validator Config 1.0//EN"

        "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">

<validators>

  <validator name="校验器名" class="校验器类的全限定名"/>

</validators>

4. Annotation方式校验: Struts2提供了注解的方式校验

  1) @Validation 指明这个类或者接口将使用基于注解的校验。Struts2.1中已被标识为过时。

  2) @Validations() 在同一个方法上要使用多个注解校验时。

  3) @SkipValidation 指定某个方法不需要校验。否则所有方法都会使用校验。也可以在检验拦截器中使用validateAnnotatedMethodOnly

  4) 13个内置校验器的注解版本:(注:这些注解都只能用在方法级别上) 具体参数参见Struts2的API或Reference。

@RequiredFieldValidator

@RequiredStringValidator

@StringLengthFieldValidator

@IntRangeFieldValidator

@DoubleRangeFieldValidator

@DateRangeFieldValidator

@ExpressionValidator

@FieldExpressionValidator

@RegexFieldValidator

@EmailValidator

@UrlValidator

@VisitorFieldValidator

@ConversionErrorFieldValidator

======================================================================

5.Java对国际化的支持:java内部使用unicode编码方式:

1)java.util.Locale 表示了特定的的地理,政治和文化地区,环境信息的对象

有语言代码和区域代码组成;

语言代码小写字母:en,zh

区域代码大写字母:US,CH ,TW,HK

2)java.util.Resourcebundle 用于绑定特定语言环境的资源对象;

资源文件的命名规范:基本名_语言代码[_区域代码].properties

默认资源文件名:基本名.properties;

3)  java.util.MessageFormat 用于对含有占位符的字符进行格式化输出;

4)编码方式

Locale locale =Locale.CHINA;

ResourceBundle rb =ResourceBundle.getBundle("资源文件的基本名",locale);

String value=rb.getstring("key");

String str=messageFormat.format(value,Object... arguments);

=====================================================================

在struts2中国际化的原理:

1 ) 在classpath中天际正对特定语言环境中的配置文件

2 ) 在struts.xml中通过常量配置注册资源文件的基本名:

<constant name="struts.custom.i18n.resources" value="msg"/>

3 ) 在jsp页面中 用<s:text value="资源文件中key"/>

4 ) 在Aciotn中,可以使用ActionSupport 类提供的getText("")


=====================================================

------------------------------------------------------文件上传------------------------------------

struts2 中的文件上传

 1. 在文本应用使用common-fileupload.jar实现文件上传

 2.struts2 中文件上传:

 在jsp页面中 在Form表单中 要指定type="multpart/-data"

 在Action 中

      File upFile; String contentType , String fileName , 提供getter,setter的方法;

      public void copy(File srcfile,File destFile) throws IOException{

     BufferedInputStream bis = null;

     BufferedOutputStream bos =null;

     try{

      bis =new BufferedInputStream(new FileInputStream(srcfile));

      bos =new BufferedOutputStream(new FileOutputStream(destFile));

      byte[] buf =new byte[8192];

      for(int count=-1;(count=bis.read(buf))!=-1){

      bos.write(b,0,count);

      bos.flush();

      }

    }catch(IOException ie){

     throw ie;

    }finally{

     if(bis!=null){

      bis.close();

     }

      if(bos!=null){

      bos.close();

     } 

      }

    同时也可以使用批量上传  

      ---------------------------

  在struts.xml

  public Boolean isallowtype(String type)

  {

   List<String>types= new ArrayList<String>();

   types.add("image/pjpeg");

   types.add(text/plain);

   types.add(application/msword);

   if(types.contains(type)){

  

   token .wu

   }

  

  

  }======================================

  1)页面要求;

   Form 表单  method="post"  enctype="multipart/form-data"

   要有file域:<input type="file" name="up"/>

  2) 在Action中:

   添加一个名与页面file域同名的file属性;

   添加一个以file域名开头,后面名为ContentType 的字符串属性,这个由struts的文件传拦截器赋问价类型值。

  添加一个以file域名开头,后面名为FileName 的字符串属性,这个有strusts2的文件上传蓝假期赋文件名的值。

 3)Io流操作,把文件的上传写到指定的目录中。

 4)批量文件上传: 在Action中添加一个List<File>类型的与页面file域同名的属性。

 通过IO流循环操作,完成文件的读写。

 ====================================

  token 防止重复提交表单

   1) 在页面的表单中添加<s:token/>

   2) 在使用token 的Action配置中添加token 或tokensession拦截器

 ================================================================

 4.FreeMarker页面模板技术: 模板+数据模型=输出

  1)FreeMarker 模板: 一个普通文本文件,其中使用了一些FreeMarker的特别标记。

  2)数据模型: 存放了数据的数据结构,通常是一个Hash存储结构(如:hashMap)

  3)FreeMarker 框架负责间隔一个数据模型中的书籍合并到模板中,从而生成输出

  2.配置是使用环境,下载并把freemarker-x.x.jar 放置到应用程序中的classpath下。

  3.java应用

  1)创建数据模型:Map<String,Object> root=.....

  2)创建模板:xxx.ftl

  3)合并

 

 -----------------------------------------------------------

 //创建个configuation实例来出示FreeMarker的配置// 也可以在classpath下添加一个freemarker.properties

 Configuarion config =new Configuration();

 String basePath =Thread.currentThrad().getContextClassLoader().getResource("").getPath();

 Config.setDirectoryForTemplateLoading(new file(basePath+"/templates"));

 Temlate template =config.getTmplate("first.txt");

 //输出控制台

 template.process(getDateModel(), new OutputStreamWriter(System.out));

 //输出到文件

 BufferedWriter bw =new bufferedWriter( new FileWriter(new File(path+"/abc.txt")));

 template.process(getDataMoedl(), bw);

 bw.flush();

 <#setting number_formate="#,###.00">

 <#setting datetime_formate="yyyy年MM月dd日 HH:mm:ss">

 ${"<a href=/"#/">xxx</a>"?html}

 ${true?string("男","女")}

 ==================== Teachers Code=======================

  1. FreeMarker模板引擎的使用: 模板 + 数据模型 = 输出

  1) FreeMarker模板:一个普通文本文件,其中使用了一些FreeMarker的特别标记。

  2) 数据模型:存放了数据的数据结构,通常是一个Hash存储结构(如:HashMap)

  3) FreeMarker框架负责将一个数据模型中的数据合并到模板中,从而生成输出

2. 配置使用环境: 下载并把freemarker-2.x.x.jar放置到应用程序的classpath下。

3. Java应用:

   1) 创建数据模型: Map<String, Object> root = ....

   2) 创建模板: xxx.ftl

   3) 合并:

//创建一个Configuration实例来初始freeMarker的配置 //在classpath下添加一个名为freemarker.properties

Configuration cfg = new Configuration();

//设置模板文件的存放目录

cfg.setDirectoryForTemplateLoading(new File("templates"));

//加载指定的模板

Template t = cfg.getTemplate("first.ftl");

//处理合并

t.process(root, new OutputStreamWriter(System.out));

4. web应用中直接使用FreeMarker: 在Servlet的请求处理方法中:

//创建一个Configuration实例来初始freeMarker的配置

Configuration cfg = new Configuration();

//设置模板文件的存放目录

cfg.setServletContextForTemplateLoading(getServletContext(),"/templates");

//加载指定的模板

Template t = cfg.getTemplate("first.ftl", "UTF-8");

//处理合并

t.process(getDataModel(), response.getWriter());

★5. FTL(FreeMarker模板语言)语法:

1) 模板文件由4部分组成:

   a) 文本:直接输出的部分

   b) 注释:<#--  注释内容 -->  不会输出

   c) 插值(interpolation):${表达式} 或 #{表达式} ,将使用数据模型中的数据替换后再输出

   d) FTL指令:

                内置(预定义)指令:<#指令名 属性名="值">主体</#指令名>  如:<#if user??>${user.loginname}</#if>

                自定义指令: <@指令名 属性名="值">主体</@指令名>

2) 插值规则

 a) 表达式放置在插值语法${}之中,用于输出表达式的值。

 b) 表达式的值的类型可以是:字符串、 数字、布尔、日期时间、序列、Hash结构

 c) 表达式支持Java中的所有运算符:

    算术运算符:+、-、*、/、%

    比较运算符:==(eq)、!=(ne)、>(gt)、>=(gte)、<(lt)、<=(lte)

    逻辑运算符:&&(and)、||(or)、!(not)

    三目运算符:? :

 d) 内置函数:

    Ⅰ) 使用方式:表达式?函数名[(实参)]

    Ⅱ) 字符串的内置函数: substring(from[, to])、html、length、trim、url

             示例:<#setting url_escaping_charset="UTF-8"> 、exp?url[("UTF-8")]

    Ⅲ) 数字的内置函数:c、string[(数字模式串)]、

    Ⅳ) 布尔的内置函数:string[("男", "女")]

    Ⅴ) 内置的日期时间函数:string[("格式模式串")]、datetime、date、time

 e) 序列:

         在FTL中定义的序列:由方括号包括,各元素用英文逗号分隔如:<#assign seq=["winter", "spring", "summer", "autumn"]>

         也可以用数字范围(递增、反递增)定义数字序列: <#assign nums=101..105>  或 <#assign nums=105..101>

         在数据模型中:可以是List对象、Set对象

         序列的内置函数:size、sort[("指定字段作排序依据")]

 f) Hash结构:

         在FTL文件中直接定义时:由大括号包括,由逗号分隔键/值列表,键和值之间用冒号分隔。键必须是字符串。<#assign scores={"语文":78, "数学":89, "英语":87}>${scores.语文}

         在数据模型中:可以是Map对象

    Hash的内置函数:size、keys、values

3) FreeMarker中的空值判断

  a) 判断是否为空值:用??(?if_exists,?exists) 如果不为空返回true,否则返回false。

  b) 通过Configuration设置:Configuration cfg = new Configuration(); cfg.setClassicCompatible(true);

  c) 属性配置方式:在freemarker.properties文件中classic_compatible=true

  d) 通过ftl设置:在ftl文件头前加入<#setting classic_compatible=true>

  e) 在FTL中遍历序列、Hash结构时:<#if userList??><#list userList as user>....</#list></#if>

4) 常用内置指令:

  a) if/else

<#if condition>

  ...

<#elseif condition2>

  ...

<#elseif condition3>

  ...

...

<#else>

  ...

</#if>

  b) switch/case

<#switch value>

  <#case refValue1>

    ...

    <#break>

  <#case refValue2>

    ...

    <#break>

  ...

  <#case refValueN>

    ...

    <#break>

  <#default>

    ...

</#switch>

  c) list

<#list sequence as item>  <#-- item_index 当前迭代项的索引 -->

    ...

</#list>

  d) include 包含指定文件。类似于JSP中的include标准动作

<#include "文件路径" [encoding="charset"] [parse=true|false]>

  e) import 导入指定模板中的所有变量。

<#import "文件路径"  as hash>

  f) noparse 不处理该指令中包含的内容

<#noparse>

  …

</#noparse>

  g) assign: 为当前模板页面创建或替换一个顶层变量

<#assign name=value>

<#assign name1=value1 name2=value2 ... nameN=valueN>

  h) global:创建或替换一个命名空间全局范围作用域的顶层变量

  i) local:创建或替换一个局部作用域的顶层变量

  j)setting 设置FreeMarker运行时的属性.语法:<#setting name=value>

name常用的有:

locale:该模板所使用的语言环境选项。en,zh,zh_CN,zh_TW

number_format:数字格式化输出的格式

boolean_format:布尔值格式化输出的格式

date_format,time_format,datetime_format:日期时间格式化输出的格式

time_zone:格式化输出日期时间所使用的时区。

url_escaping_charset:URL编码的字符集。

  k) 自定义指令:<#macro 指令名 属性名...>...</#macro>

6. Web应用中整合FreeMarker:FreeMarker提供了FreemarkerServlet类来整合模板到Web应用中:

  1) 这个Servlet在数据模型中放置了三个Hash结构:Request, Session, Application,分别用来访问请求,会话,应用上下文中的属性。

             访问作用域中的属性时,没有指定Hash结构名,它会依次按Request,Session,Application顺序搜索。

  2) 它还提供了一个名为RequestParameters的Hash结构,用来访问HTTP请求中的参数数据。

7. Struts2中整合FreeMarker: Struts2默认就是使用FreeMarker来产生所有UI标签的HTML标记。

  1) 对提供了FreeMarkerResult来支持FTL页面。

     <result type="freemarker">/templates/info.ftl</result>

  2) FreeMarker针对Struts2提供了以下内置Hash结构:

     a) stack: 代表ValueStack本身,可通过如下方式来访问其中的变量"${stack.findString('ognl expr')}"

     b) action: 代表刚刚执行过的Action实例

     c) response: 代表HpptServletResponse实例

     d) res: 代表HpptServletResponse实例

     e) request: 代表HpptServletRequest实例

     f) req: 代表HpptServletRequest实例

     g) session: 代表HpptSession实例

     h) application: 代表ServletContext实例

     i) base: 代表用户请求的上下文路径.

8. 使用FreeMarker完成页面的静态化:


-----------------------------------------------------------------------------------------------------------------

  =============================================================================

 5. JFreeChar技术 画图技术

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kekeyifan/archive/2009/12/07/4958716.aspx

原创粉丝点击