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

学习笔记之Struts2

2014-12-02 16:51 190 查看
Struts2
一、   导论

Struts2是在WebWork2基础上发展而来的,相比struts1有以下优点:

a)  Struts2不依赖servlet API和struts API,属于无侵入式设计;

b)  提供了拦截器,可以进行AOP编程,实现如权限拦截等功能;

c)  提供了类型转换器;

d)  支持多种表现层技术,如jsp、freeMarker、veiocity;

e)  输入校验可以对指定的方法进行校验;

f)         提供了全局范围、包范围、action范围的国际化资源文件管理实现;

二、   开发过程

1. 导入jar包;

struts2-core-2.0.14.jar

Struts2核心包

freemarker-2.3.8.jar

表现层框架,定义了struts2的可视组件主题

xwork-2.0.7.jar

webwork的核心库

ognl-2.6.11.jar  

OGNL表达式语言,struts2支持该EL 

Commons-fileupload-xxx.jar

文件上传组建,2.1.6版本以后必须要

commons-logging-1.0.4.jar

日志处理(spring、hibernate、struts2三大框架任意一个包含此包即可)

Commons-io.XXX.jar

实现文件上传功能(可选)

 

2. 编写Action;

3. 编写struts2核心配置文件struts.xml;

服务器启动时,StrutsPrepareAndExecuteFilter的ini()方法会读取struts.xml文件完成初始化,并以javabean的形式存放到内存中,以后直接从内存中读取配置信息,而不是每次请求都重新读取。

 

<?xml
version="1.0"encoding="UTF-8"
?>
<!DOCTYPE
strutsPUBLIC
   "-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   

</struts>
4. 修改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>

三、   详细

1.Action名称的搜素顺序

http://127.0.0.1/projectName/p1/p2/p3/a.action这个地址的搜索顺序:

a)  http://127.0.0.1/projectName/p1/p2/p3/a.action

b)  http://127.0.0.1/projectName/p1/p2/a.action

c)  http://127.0.0.1/projectName/p1/a.action

d)  http://127.0.0.1/projectName/a.action

e)  Not found!

2.请求转发

访问http://localhost:8080/struts2test/p1/forward.action这个网址时,要求转到WEB-INF/pages/forward.jsp页面,则需如下配置action:
<action
name="forward">
           
<result>/WEB-INF/pages/forward.jsp</result>
</action>

3.Action配置中各项默认值

默认项

默认值

Action的class

ActionSupport

Action的method

execute()

Result的name

“success”

Result的type

“dispatcher”

4.Result的type属性决定了请求的转发类型

a)  dispatcher:服务器内部请求转发,可以访问/WEB-INF目录下的文件

b)  redirect:引导浏览器重定向,不可以访问/WEB-INF目录下的文件

result中可以使用${属性名}访问action中的属性

c)  redirectAction:重定向到action

如果重定向到同包下的action,直接在result中写action就可以了,如:

<result type="redirectAction">action</result>

如果重定向到其他包下的action,则要配置actionName、namespace属性:

<result
type="redirectAction">
              
<param name="actionName">xxx</param>
             
<param name="namespace">/ssss/wwww</param>
</result>

d)  plaintext:显示原始文件内容

<result type="plainText">sss.jsp</result>

5.为action属性注入值

//为名为forward的action的name属性注入值chenlong

<action
name="forward">
           
<paramname=”name”>chenlong</param>
</action>

6.指定action的后缀

<constant
name="struts.action.extension"
value="do,action"></constant>

Struts2中可在多个文件中配置常量,加载的时候按以下顺序,后一个文件的常量会覆盖前面文件中同名的常量:

Struts-defualt.xml

Struts-plugin.xml

Struts.xml //一般常量配置在这里

Struts.properties

Web.xml

7.常用的常量

//默认编码集

<constant
name="struts.i18n.encoding"value="utf-8"></constant>

//浏览器是否缓存静态内容

<constant
name="struts.serve.static.browserCache"value="false">

</constant>

    //配置文件被修改后,是否自动重新加载

<constant
name="struts.configuration.xml.reload"value="true"></constant>

    //开发模式,提供更多提示信息

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

    //视图主题

<constant
name="struts.ui.theme"value="simple"></constant>

    //与spring集成的时,指定对象工厂

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

    //是否支持动态方法调用

<constant
name="struts.enable.DynamicMethodInvocation"value="false">

</constant>

    //上传文件的大小限制

<constant
name="struts.multipart.maxSize"value="10701096"></constant>

8.Struts2的处理流程

9.划分多个struts2配置文件

大型项目,action数量很大,如果全部写在struts.xml中,可读性降低,文件臃肿、庞大,不利于维护和管理。此时,可将struts.xml文件中的内容按功能模块划分为多个配置文件,然后在struts.xml中用<include></include>引入即可:

<include
file="struts-user.xml"></include>

<include
file="struts-order.xml"></include>

10.     动态方法调用和通配符的使用

方法一:动态方法调用

//访问action P1的F1方法:

http://localhost:8080/strutstest/P1!F1.action

方法二:通配符

       //访问action P1的任意一个方法:

    <action
name="P1_*"
class="cn.edu.action.{1}"
method=”{1}”>
        <result
name="success">/{1}.jsp</result>
</action>

11.     接收请求参数

在action有和参数同名的属性,并且有set方法和无参构造函数,就可以自动接收到参数值。

12.     自定义类型转换器

a)   定义转换器类,继承com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter类,重写下面这个方法:

public Object convertValue(Map<String, Object>context, Object value,Class toType)

b)  注册转换器

①. 注册为全局转换器:

在/src目录下创建文件xwork-conversion.properties,文件内容为:某一类型=转换器的全路径

②. 注册为局部转换器:

在XXXaction的目录下创建文件XXXAction-conversion.properties,文件内容为:属性名=转换器的全路径

13.     访问、添加request/session/application属性

a)  Application:

添加:ActionContext.getContext().getApplication().put(key,value);

访问:Jsp中用${applicationScope.key}访问属性

b)  Session:

添加:ActionContext.getContext().getSession().put(key,value);

访问:Jsp中用${sessionScope.key}访问属性

c)  Request:

添加:ActionContext.getContext().put(key,value);

访问:Jsp中用${requestScope.key}访问属性

d)  还可以通过以下方法获得request/session/application对象,然后使用setAttribute(Strings,Object o)方法添加属性

 

ServletActionContext.getRequest();//获取Reuest对象

ServletActionContext.getResponse();//获取Response对象

ServletActionContext.getServletContext();//获取ServletContext对象

14.     文件上传

a)  文件上传的Form表单中必须有以下两个属性

enctype="multipart/form-data"

method="post"

并且form表单的<input type=”file” name=”XXX”>这里的name属性必须和action的File属性同名

b)  添加文件上传所需的jar包:

commons-fileupload-1.2.1.jar

文件上传核心包

commons-io-1.3.2.jar

文件转储时会用到这个包的FileUtils.copyFile()方法

c)  编写action

public
class
FileUploadAction {
    public File
ufile;//上传的文件
    public String
ufileFileName;//文件的名称
public String
ufileContentType;//文件的类型

 

//省略

}

①. 文件上传的action里面必须有一个File类型的属性,用来自动接收上传的文件,假如该属性名为XXX;

②. 可以用XXXFileName属性自动接收文件名

③. 可以用XXXContentType属性自动接收文件的类型

④. 处理文件上传的函数可以这样写

 

String realpath=ServletActionContext.getServletContext()
.getRealPath("/ufiles");//获取上传文件的存放路径
       if(ufile!=null){ //如果用户选择了文件
           File savafile=new File(new File(realpath),
ufileFileName);
           if(!savafile.getParentFile().exists()){//如果/ufiles目录不存在
              savafile.getParentFile().mkdirs();//则创建该目录
           }
          
           FileUtils.copyFile(ufile, savafile);//将文件由临时目录copy到目标目录
           ActionContext.getContext().put("message",
"上传成功!");
           return
"success";
       }else{
           ActionContext.getContext().put("message",
"没选择文件!");
           return
"failure";
}

15.     多文件上传

       实现多文件上传和单文件上传有以下区别:

a)  文件上传form表达中的多个<input type=”file” name=”xxx”>的name属性名必须相同,并且与action中的File []xxx属性名也要相同;

b)  Action中接收文件的不再是File xxx,而是File []xxx,因为有多个文件,同理,另外两个属性也要变成String []xxxFileName、String []xxxContentType

c)  实现转储时,用for循环

16.     自定义拦截器

a)  编写拦截器类:实现com.opensymphony.xwork2.interceptor.Interceptor接口,重写public Stringintercept(ActionInvocation invocation)
throws Exception这个方法。

b)  注册拦截器:为了不屏蔽掉struts2的拦截器,一般使用interceptor-stack,具体如下:

<interceptors>
          
<interceptor
name="myInterceptor"
class="xxx.MyInterceptor"/>
          
<interceptor-stack
name="myInterceptorStack">
              
<!-- 引入框架提供的拦截器 -->
              
<interceptor-ref
name="defaultStack"
/>
              
<!-- 引入自定义的拦截器 -->
              
<interceptor-ref
name="myInterceptor"/>
          
</interceptor-stack>
</interceptors>

 

c)  使用拦截器:在需要拦截器的action内引入拦截器即可

<interceptor-ref
name="myInterceptorStack"></interceptor-ref>

17.      输入校验

a)  让相应的action继承ActionSupport类,并重写public
void
validate()方法,在这个方法中对输入的值进行校验,如果校验失败,则用addFieldError()方法将错误信息保存起来;

b)  在Jsp页面中可通过<s:fielderror/>标签显示错误信息

这种实现方法,会对该action所有的方法进行输入校验,校验不通过,不会执行请求的action方法;

c)   如果只想对其中一个方法axx()进行输入校验,只需提供一个public
void
validateAxx()方法即可;

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

l  上面说的方法是自己编写校验方法,还可以通过配置文件配置校验器

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

a)  在对应的action的目录下新建配置文件:

①.  ActionName-validation.xml//对该Action的所有的方法输入检验

②.  ActionName-[action方法名]-validation.xml//对该Action的某个方法输入检验

<?xml
version="1.0"
encoding="UTF-8"?>
<!DOCTYPE
validators PUBLIC"-//Apache Struts//XWork Validator1.0.3//EN"  

  "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">

   
<validators>

</validators>

b)  在上面的配置文件中为需要验证的属性配置检验器:如

<field
name="user.username">
       <field-validator
type="requiredstring">
           
<param name="trim">true</param>
           
<message>用户名不能为空!</message>
</field-validator>
常用的检验器:
①.  requiredstring
<field-validatortype="requiredstring">
            <paramname="trim">true</param>
            <message>用户名不能为空!</message>
</field-validator> 
②.  regex
<field-validatortype="regex">
     <paramname="expression"><![CDATA[^1[358]\d{9}$]]></param>
     <message>手机号格式不正确!</message>
</field-validator>
③.  required
<field-validatortype="required">
     <message>性别不能为空!</message>
</field-validator>
④.  stringlength
<field-validatortype="stringlength">
    <paramname="maxLength">10</param>
    <paramname="minLength">5</param>
    <paramname="trim">true</param>
    <message><![CDATA[产品名称应在5-10个字符之间]]></message>
</field-validator>
⑤.  email
<field-validatortype="email">
     <message>电子邮件地址无效</message>
</field-validator>
18.     国际化
a)  创建资源文件:
①.  文件名格式:自定义资源文件名_语言_国家.properties

例如:  mysourse_zh_CN.properties
mysourse_en_US.properties
②.  文件内容:key
= value
对于中文,必须转为unicode编码,可以使用jdk命令:
native2ascii
源文件 目标文件
b)  配置资源文件
①.  在struts.xml中如下配置,即可将资源文件配置成全局的:
<constant name="struts.custom.i18n.resources" value="XXX"/>
②.  在某个包下面建立package_语言_国家.properties,该包下面的Action都可以访问该资源,找不到时,才会搜索全局资源文件
③.  在Action的目录下建立Action名称_语言_国家.properties即可
c)  使用国际化信息
①.  在jsp中使用<s:text name=”key”/>标签可输出国际化信息,如果要输出带占位符的信息,则在<s:text>标签中加入<s:param>标签,如下:
<s:text
name="welcome">
   <s:param>${user.username}</s:param>
   <s:param>!</s:param>
</s:text>
②.  在action中,可以继承ActionSupport,然后使用getText(String key)得到国际化信息,如果要输出带占位符的信息,则用getText(stringkey,String []params)
③.  在表单中,通过<s:textfield name=”xxx”key=”key”/>得到国际化信息
④.  Struts2也可以使用下面的方式访问国际化信息
<s:i18n name=”包名”>
    <s:text name=”key”/>
</s:i18n>
19.     Ognl表达式
OGNL,Objectnavigation Language(对象图导航语言),是struts2默认的表达式语言。
相对于EL表达式,它的优势在于:
①.  支持对象方法的调用
②.  支持静态方法的调用和静态值的访问:@类全名@静态方法名、@类全名@静态变量名
③.  能操作集合对象

ognl上下文示意图
a)  Ognl会设定一个根对象,默认为ValueStack,访问根对象,可省略命名空间

根对象也可以直接用EL表达式访问。(这就是为什么jsp页面中可以直接使用EL表达式访问action中的属性)

b)  访问除根对象以外的Context中的对象,需要使用符号#注明命名空间:

①.  Parameters对象:实际访问http的请求参数

#parameters.age/#parameters[‘age’]=>request.getParameters(“age”)

②.  Request:实际访问HttpServletRequest对象

#request.name/#request[‘name’]=>request.getAttribute(“name”)

③.  Session:实际访问的是httpSession对象

#session.name/#session[‘name’]=>session.getAttribute(“name”)

④.  Application:实际访问的是ServletContext对象

#application.name/# application[‘name’]

=>ServletContext.getAttribute(“name”)

⑤.  Attr:按照page->request->session->application的顺序访问其属性

c)  Ognl表达式需要配合struts2的标签使用

d)  使用ognl创建list/map对象

①.  ognl创建list对象:
     <s:set
scope="request"
var="list"value="{'a','b','c','d'}"/>        
<s:iterator
value="#request.list">
          
<s:property/>
        </s:iterator> 

②.  ognl创建map对象:
<s:set
scope="session"
var="map"value="#{'a':90,'b':100 }"/> 

        <s:iterator
value="#session.map">
          
<s:property/>
</s:iterator>

③.  采用ognl表达式判断对象是否存在集合中

<s:if
test="'foo' in{'foo','bar'}">true</s:if>
<s:else>false</s:else>

20.     Struts2常用标签
a)  <s:property /> :输出指定值
Default:默认值
Escape:是否格式化html代码
Value:指定输出的值
Id:标示
b)  <s:iterator />迭代标签

c)  <s:if/else/elseif/>标签
d)  <s:url/>标签

e)  <s:checkboxlist/>复选框标签

f)  <s:radio/>标签

g)  <s:select/>标签

21.     如何使用标签防止表单重复提交
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: