Struts2学习笔记

我在学校时整理的笔记,我是个新手,请谅解我写不好的地方,在后面我会改,有问题可以留言,我们共同解决,共同进步,谢谢大家!

第一次课:Struts概念、运行流程

  1. J2EE应用体系结构、Java框架特点

 

  1. 概念:Struts2是在WebWork2基础发展而来的,和struts1一样,Struts2也属于MVC框架。要注意的是:Struts2与Struts1在代码编写风格上几乎是不一样的

Struts2主要有以下优点:

1)        在软件设计上Struts2没有像Struts1那样跟ServletAPI和StrutsAPI有着紧密的耦合,Strut2的应用可以不依赖于ServletAPI和StrutsAPI.Struts2的这种设计属于无侵入式设计,而Struts1却属于侵入式设计。

Public class OrderListAction extends Action{

       Public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throwsException{}

}

2)        Struts2提供了拦截器,利用拦截器可以进行AOP编程,实现如权限拦截等功能。

3)        Struts2提供了类型转换器,我们可以把特殊的请求参数转换成需要的类型。在Struts1中,如果我们要实现同样的功能,就必须向Struts1的底层实现BeanUtil注册类型转换器才行。

4)        Struts2提供支持多种表现层技术,如:Jsp、freeMarker、Velocity等

5)        Struts2的输入校验可以对指定方法进行校验,解决了Struts1长久之痛。

6)        提供了全局范围、包范围和Action范围的国际化资源文件管理实现

 

  1. Struts2在web中的启动配置

在struts1.x中,struts框架是通过Servlet启动的。在struts2中,struts框架是通过Filter启动的。他在web.xml中的配置如下:

 1 <filter>
 2       <filter-name>struts2</filter-name>
 3       <filter-class>
 4       org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 5       </filter-class>
 6     <!--自从Struts2.1.3以后,下面的FilterDispatcher已经标注为过时
 7     <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> -->
 8   </filter>
 9   <filter-mapping>
10       <filter-name>struts2</filter-name>
11       <url-pattern>*.action</url-pattern>
12   </filter-mapping>

 

 

在StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。

 

注意:struts2读取到struts.xml的内容后,以javabean形式放在内存中,以后struts2对用户的每次请求处理将使用内存中的数据,而不是每次都读取struts.xml文件

 

  1. Struts.xml配置中的包介绍

 

1 <package name=”itcast” namespace=”/test” extends=”struts-default”>
2 <action name=”helloworld” class=”cn.itcast.action.HelloWorldAction” method=”execute”>
3     <result name=”success”>/WEB-INF/page/hello.jsp</result>
4 </action>
5     </package>

 

 

1)        在struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的,它主要用于管理一组业务功能相关的action,在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下。

2)        配置包时必须指定name属性,该name属性值可以任意取名,但必须唯一,他不对应java的类包,如果其他包要继承该包,必须通过该属性进行引用,包的namespace属性用于定义该包的命名空间,命名空间作为该包下Action的路径一部分,如访问上面例子的Action,访问路径为:/test/helloworld.action.  namespace可以不配置,对本例而言,如果不指定该属性,默认的命名空间为””(空字符串).

3)        通常每个包都应该继承struts-default包,因为Struts2很多核心的功能都是拦截器来实现,如:从请求中把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。Struts-default.xml定义了这些拦截器和Result类型。可以这么说:当包继承了struts-default才能使用struts2提供的核心功能.struts-default包是在struts2-core-2.x.x.jar文件中的struts-default.xml中定义。Struts-default.xml也是struts2默认配置文件。Strutst每次都会自动加载struts-default.xml文件

4)        包还可以通过abstract=”true”定义为抽象包,抽象包中不能包含action

  1. A ction名称的搜索顺序

1)        获得请求路径的URI,例如url是:http://server/struts2/path1/path2/path3/test.action

2)        首先寻找namespace为/path1/path2/path3的package,如果不存在这个package则执行步骤3;如果存在这个package,则在这个package中寻找名字为test的action,当在该package下寻找不到action时就会直接跑到默认namespace的package里面去寻找action(默认的命名空间为空字符串””),如果在默认namespace的package里面还寻找不到该action,页面提示找不到action

3)        寻找namespace为/path1/path2的package,如果不存在这个package,则转至步骤4;如果存在这个package,则在这个package中寻找名字为test的action,当在该package中寻找不到action时就会直接跑到默认namespace的package里面去找名字为test的action,在默认namaspace的package里面还寻找不到该action.页面提示找不到action

4)        寻找namespace为/path1的package,如果不存在这个package则执行步骤5;如果存在这个package,则在这个package中寻找名字为test的action,当在该package中寻找不到acton时就会直接跑到默认namespace的package里面去找名字为test的action,在默认namespace的package里面还寻找不到action,页面提示找不到action

5)        寻找namespace为/的package,如果存在这个package,则在这个package中寻找名字为test的action,当在package中寻找不到action或者不存在这个package时,都会去默认namespace的package里面寻找 action,如果还是找不到,页面提示找不到action

 

  1. Action配置中的各项默认值
1 <package name=”itcast” namespace=”/test” extends=”struts-default”>
2     <action name=”helloworld” class=”cn.itcast.action.HelloWorldAction” method=”execute”>
3         <result name=”success”>/WEB-INF/page/hello.jsp</result>
4     </action>
5 </package>

 

1)        如果没有为action指定的class,默认是ActionSupport.

2)        如果没有为action指定的method,默认执行action中的execute()方法

3)        如果没有指定result的name属性,默认值为success.

  1. Action中result的各种转发类型

<action name=”helloworld” class=”cn.itcast.action.HelloWorldAction” method=”execute”>

              <result name=”success”>/WEB-INF/page/hello.jsp</result>

</action>

Result配置类似于struts1中的forward,但struts2中提供了多种结果类型,常用的类型有:dispatcher(默认值)、redirect(重定向,外部跳转)、redirectAction、plainText..

 

下面是redirectAction结果类型的例子,如果重定向的action中同一个包下:

<result type=”redirectAction” >helloworld</result>

如果重定向的action在别的命名空间:

<result type=”redirectAction”>

       <param name=”actionName”>helloworld</param>

       <param name=”namespace”>/test</param>

</result>

Plaintext:显示原始文件内容,例如:当前我们需要原样显示jsp文件码的时候,我们可以使用此类型

<result name=”source” type=”plainText”>

       <param name=”location”>/xxx.jsp</param>

       <param name=”charSet”>UTF-8</param><!--指定读取文件的编码-->

</result>

 

 

  1. Struts2运行流程分析

1)        在项目启动之初: Struts的过滤器会运行 此过滤器有两个目的:过滤*.action的请求, 加载Struts.xml struts-default.xml 配置文件   

2)        如果前台的请求扩展名是action的.则会被StrutsPrepareAndExecuteFilter 过滤.此过滤器会去Strut.xml中找到相应的Action并且实例化,Action实例化之后会和前台页面的名字自动匹配(因为所有自定义的包都继承了extends="struts-default")

3)        到达Action到底要进去到哪个方法不再取决于隐藏域.而是配置文件中的method属性

 

  1.  
  2. Action与Servlet的区别:

1)        Action没有以来request reponse 是一个普通的Java类

2)        Action声明一个全局变量用来方便的与前台表单数据匹配

3)        Action是每一个请求都会实例化,一个Servlet处理所有的请求

4)        Action:缺点:耗资源,优点:数据自动获取

第二次课:Struts2的验证框架

  1. 服务器端验证的必要:

a)         客户端验证更多起着提示作用

b)        服务端验证是数据完整性的有利保证

  1. 采用ActionSupport完成服务器端验证

a)         命名规范为: validate+方法名()

b)        验证流程:Action要继承ActionSuport类 此类可以实现基于代码和XML的验证

c)         验证方法的命名为: validate+方法名() 在调用方法之前,会自动进入validate验证方法

d)        如果验证成功则调转到目标方法,失败则跳转到Input指定的页面

e)         缺点:代码验证维护性不高.代码量大.

  1. 采用XML配置的方式完成服务器端验证

a)         命名规范为:Aciton名称-请求的名称- validation.xml

                       

com.opensymphony.xwork2.validator.validators 下面有Struts已经实现的验证类,和验证类的

配置文件

 

例如:

 

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE validators PUBLIC  "-//OpenSymphony Group//XWork Validator 1.0.2//EN" 
 3 "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
 4 <validators>
 5     <field name="goods.sgname">
 6         <!—-非空验证-->
 7         <field-validator type="requiredstring">
 8             <message>查询内容不能为空!</message>
 9         </field-validator>
10         <!—-长度验证-->
11         <field-validator type="stringlength">
12             <param name="minLength">4</param>
13             <param name="maxLength">16</param>
14             <param name="trim">true</param>
15             <message>字符长度在${minLength}-${maxLength}位</message>
16         </field-validator>
17     </field>
18 
19     <field name="goods.sgprice">
20         <!—-double范围之间的验证-->
21         <field-validator type="double">
22             <param name="minExclusive">0.00</param>
23             <param name="maxExclusive">100.00</param>
24             <message>请输入${minExclusive}-${maxExclusive}之间的价钱</message>
25         </field-validator>
26     </field>
27 
28     <field name="email">
29         <field-validator type="requiredstring">
30             <message>邮箱为必填项</message>
31         </field-validator>
32         <!—-邮箱验证-->
33         <field-validator type="email">
34             <message>邮箱不正确!</message>
35         </field-validator>
36     </field>
37 
38     <field name="phone">
39         <!—-正则表达验证-->
40         <field-validator type="regex">
41             <param name="expression"><![CDATA[1[358]\d{3}]]></param>
42             <message>手机号码不正确</message>
43         </field-validator>
44     </field>
45 </validators>

 

 

 

 

 

说明:struts2.1包各包的说明

       commons-fileupload-1.2.1.jar:文件上传组件,2.1.6版本后必须加入些文件

       commons-io-1.3.2.jar:文件操作包

       commons-logging-1.1.jar:ASF出品的日志包,Struts2框架使用这个日志包来支持Log4J和JDK1.4+的日志记录

       freemarker-2.3.13.jar:struts2的UI标签的模板使用FreeMarker编写

       ognl-2.6.11.jar:对象图导航语言(Object Graph Navigation Language),Struts2框架通过其读写对象的属性

struts2-core-2.1.6.jar:Struts2框架的核心类库

xwork-2.1.2.jar:XWork类库,Struts2在其上构建,验证类

 

 

第三次课:Struts2自定义验证框架、文件上传

  1. Struts关于Double验证Bug问题解决

使用新版本Struts2

2.3.4必须包:

  1. Struts文件上传于原理解析

a)         Form如果需要上传多媒体数据,则要post提交 而且表单指定为多媒体表单

enctype="multipart/form-data"

b)        编写一个文件上传的工具类:修改文件名,验证文件格式,实现文件上传功能

 

 1 public class FileUploadUtil {
 2     
 3     FileUploadUtil(){}
 4     
 5     public static String getFileExt(String fileName)
 6     {
 7         //返回文件名称的后辍名
 8         return fileName.substring(fileName.lastIndexOf(".")+1);
 9     }
10     
11     public static String updateFileName(String oldName)
12     {
13         //返回随机生成的32位数值+.后辍名
14       return UUID.randomUUID().toString()+"."+getFileExt(oldName);
15     }
16     
17     public static void uploadFile(String filePath,File file) throws IOException
18     {
19         InputStream inputStream=new FileInputStream(file);
20         OutputStream outputStream=new FileOutputStream(filePath);
21         byte[] bytes=new byte[1024];
22         while(inputStream.read(bytes)>0)
23         {
24             outputStream.write(bytes);
25         }
26         inputStream.close();
27         outputStream.close();
28     }
29 }

 

 

 

c)         在Struts的Action中.可以通过ServletActionContext 来对requst response session application进行获取

 

1 ServletActionContext.getRequest();
2         ServletActionContext.getServletContext();
3         ServletActionContext.getResponse();
4         ServletActionContext.getRequest().getSession();

 

 

 

d)        在Action 调用上传文件的方法

 

 1 public String saveGoods() throws IOException
 2     {
 3     //文件名入库
 4     goods.setSgpic(FileUploadUtil.updateFileName(goodsFile.getGoodsImageFileName()));    
 5     //实现文件上传功能
 6 String filePath=ServletActionContext.getServletContext().getRealPath("\\")+"image\\"+goods.getSgpic();//得到文件路径(包括文件名)
 7     System.out.println(filePath);
 8     FileUploadUtil.uploadFile(filePath, goodsFile.getGoodsImage());
 9         return "index";
10 }

 

 

 

 

  1. 采用自定义验证规则验证文件格式

a)         自定验证类, 此类要继承FieldValidatorSupport类

如:

 1 public class FileFormatValidate extends FieldValidatorSupport {
 2     private String type = "jpg";
 3     public void validate(Object object) throws ValidationException {
 4         // TODO Auto-generated method stub
 5         String fieldName = getFieldName();
 6         Object value = this.getFieldValue(fieldName, object);
 7         if (value instanceof String) {
 8             String ext = FileUploadUtil.getFileExt((String) value);
 9             for (String temp : type.split(",")) {
10                 if (temp.equalsIgnoreCase(ext)) {
11                     return;
12                 }
13             }
14         }
15         //验证失败,添加错误消息
16         addFieldError(fieldName, object);
17     }
18     public String getType() {
19         return type;
20     }
21 
22     public void setType(String type) {
23         System.out.println("====setType====");
24         this.type = type;
25     }
26 }

 

b)        然后创建一个validators.xml 把自定义的验证类配置到此文件中

 

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE validators PUBLIC
3         "-//Apache Struts//XWork Validator Definition 1.0//EN"
4         "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
5 <validators>
6     <validator name="fileFormatValidate" class="it.shopping.util.FileFormatValidate" />
7 </validators>

 

 

c)         Struts先加载validators.xml 然后在加载系统default.xml的配置文件

 

 

 

第四次课:Struts拦截器的应用

  1. 文件大小设置、上传多个文件

d)     <constant name="struts.multipart.maxSize" value="2097152" />  

e)     Action

 

 1 public String saveGoods() throws IOException
 2     {
 3 
 4         String basePath=ServletActionContext.getServletContext().getRealPath("/")+"image/";
 5         StringBuffer sgpic=new StringBuffer();
 6         //获取第i个文件名
 7         for(int i=0;i<goodsFile.getGoodsImage().length;i++)
 8         {
 9             String oldName=goodsFile.getGoodsImageFileName()[i];
10             String newName=FileUploadUtil.updateFileName(oldName);
11             FileUploadUtil.uploadFile(basePath+newName,goodsFile.getGoodsImage()[i]);
12             sgpic.append(newName).append("?");
13         }
14         goods.setSgpic(sgpic.substring(0,sgpic.length()-1));
15         return "index";
16 }

 

f)      自定义验证类,验证文件类型

 

 1 public void validate(Object object) throws ValidationException {
 2         String fieldName=getFieldName();
 3         Object value=this.getFieldValue(fieldName,object);
 4         String[] types=type.split(",");
 5         if(value instanceof String[])
 6         {
 7             //把文件拿出来
 8             for(String temp:(String[]) value)
 9             {
10                 //获取后辍名
11                 String ext=FileUploadUtil.getFileExt(temp);
12                 //ext与types判断,只要有一个ext不符合规整,则添加错误消息
13                 int i=0;
14                 for(;i<types.length;i++)
15                 {
16                     if(ext.equalsIgnoreCase(types[i]))
17                     {
18                         break;
19                     }
20                 }
21                 //正常退出
22                 if(i==types.length)
23                 {
24                     addFieldError(fieldName, object);
25                     return;
26                 }
27             }
28         }
29     }

 

 

  1. 拦截器的概念:AOP的一种实现,同过滤器

org.apache.struts2.interceptor 里面有Struts自定义的拦截类

  1. 过滤器类,在web.xml中配置了

 

 1 <filter>
 2       <filter-name>struts2</filter-name>
 3       <filter-class>
 4       org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 5       </filter-class>
 6   </filter>
 7   <filter-mapping>
 8       <filter-name>struts2</filter-name>
 9       <url-pattern>*.action</url-pattern>
10   </filter-mapping>

 

则项目启动时过滤器加载,struts-dafault.xml,struts-plugin.xml,struts.xml在过滤器加载时初始化,在StrutsPrepareAndExecuteFilter初始化方法中,strutsPrepareAndExecuteFilter类中创建了ActionContext上下文对象

 

  1. ActionContext

在Struts中通过ServletActionContext来获取request response application 从而把数据存储到内置对象中.通过源码可以看出:ServletActionContext 继承了ActionContext类

 

Map requestMap = new RequestMap(request);

Map params = new HashMap(request.getParameterMap());

  1. 自定义拦截器实现”空字符”拦截

a)   定义一个StringTrimInterceptor类,实现从请求中参数去空格,要继承AbstractInterceptor

 

代码如下:

 

 1 public class StringTrimInterceptor extends AbstractInterceptor {
 2 
 3     private static final long serialVersionUID = 1L;
 4 
 5     @Override
 6     public String intercept(ActionInvocation invocation) throws Exception {
 7         ActionContext context=invocation.getInvocationContext();
 8         //从ActionContext中获取客户端所有的参数名称和值
 9         Map<String,Object> params=context.getParameters();
10         for(String key:params.keySet())
11         {
12             Object o=params.get(key);
13             //判断是否为String数组
14             if(o instanceof String[])
15             {
16                 String[] values=(String[]) o;
17                 for(int i=0;i<values.length;i++)
18                 {
19                     values[i]=values[i].trim();
20                 }
21                 params.put(key, values);
22             }
23         }
24         //跳转到下一个拦截器
25         return invocation.invoke();
26         }
27 }


 

b)   在struts.xml配置文件中配置拦截器

 

 1 <struts>
 2     <package name="shopping" extends="struts-default">
 3         <!--  配置拦截器 -->
 4         <interceptors>
 5             <!-- 配置拦截器,name:名字  class:对应的拦截器类 -->
 6             <interceptor name="stringTrimInterceptor" class="it.shopping.util.StringTrimInterceptor" />
 7             <!-- 创建拦截器栈  (拦截器的集合) -->
 8             <interceptor-stack name="shoppingStack">
 9                 <interceptor-ref name="stringTrimInterceptor" />
10                 <!—-struts内容默认的拦截器—->
11                 <interceptor-ref name="defaultStack" />
12             </interceptor-stack>
13         </interceptors>
14         <action name="goodsAction_*" class="it.shopping.action.GoodsAction"
15             method="{1}">
16             <result name="index" type="redirect">/index.jsp</result>
17             <result name="input">/error.jsp</result>
18             <!—-调用拦截器栈-->
19             <interceptor-ref name="shoppingStack" />
20         </action>
21     </package>
22 </struts>

 

转载于:https://www.cnblogs.com/zhjcnblog/archive/2012/10/10/2719213.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值