您的位置:首页 > 编程语言 > Java开发

[Struts]Struts2的开发步骤

2010-03-14 23:24 369 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: