struts2总结

Struts2总结

1.概述:

Struts2是基于MVC的一个经典框架。

它以webwork为核心,采用拦截器机制处理用户的请求,与servletaAPI完全解耦合,低入侵式设计,面向切面的设计思想,使用动态代理反射机制,线程安全。核心控制器是filterDispatcher.

2.框架

M:Model模型层 由JavaBean 和EJB(Enterprise JavaBean)组成 负责业务逻辑处理,数据库访问

V:view视图层 jsp文件,struts2标签库,Ognl 负责显示页面,与用户交互,接收用户信息

C:由FilterDispatcher和action组成:

FilterDispatcher:核心控制器(升级版:strutsPrepareAndExecuteFilter)

Interceptors:拦截器,对请求进行一系列的拦截过滤。

Action类:由开发人员编码实现,负责调用模型、数据传递和视图转向

3.struts1VSstruts2

Struts2:

  1. 与servletAPI解耦合,易于测试
  2. 线程安全,action存在于当前线程中,每次请求产生一个新的actionContext
  3. 面向切面的设计思想,低入侵式设计
  4. 采用动态代理和反射机制

Strutst1:

  1. 与servletAPI耦合较高
  2. 非线程安全,容易产生并发现象。
  3. 高入侵式的设计

4.执行过程:

5.核心配置文件:

Web.xml

<!-- 配置FilterDispatcher 2.3 -->  

<filter>

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

         <!—

配置FilterDispatcher 2.0

         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

         -->

</filter>

<filter-mapping>

         <filter-name>struts</filter-name>

         <url-pattern>/*</url-pattern>(不仅拦截action请求,还拦截普通请求实现通用功能)

</filter-mapping>

struts.xml

<struts>

         <!-- 设置webapp为开发模式 -->

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

         <!-- 设置字符集 -->

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

         <!-- 设置UI -->

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

         <!-- 设置上传图像最大值 -->

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

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

                   <!-- 声明interceptors -->

                   <interceptors>

                            <interceptor-stack name="myDefaultStack">

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

                            </interceptor-stack>

                   </interceptors>

                   <!—引用interceptors -->

                   <default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>

                   <global-results>

                            <result>/index.jsp</result>

                   </global-results>

         </package>

         <include file="com/guigu/config/user.xml"></include>

</struts>

Userx.xml

<struts>

         <package name="userLogic" namespace="/user" extends="basePack">

                   <!-- 初始化部门编号 -->

                   <action name="initDept" class="com.guigu.action.UserAction" method="initDept">                                     <result>/user/addUser.jsp</result>

                   </action>

                   <action name="addUser" class="com.guigu.action.UserAction" method="addUser">

                            <result>/user/showUser.jsp</result>

                   </action>

         </package>

</struts>

关于常量

常量可以定义在多个文件中,默认情况下我们按照下面的顺序来寻找常量,后面的将覆盖前面的设置:

         struts-default.xml

         struts-plugin.xml

         struts.xml

         struts.properties

         web.xml

         前3个xml文件的格式是一样的,因为它们使用同一个DTD文件,在xml文件中Constant元素有两个必须的属性:name和value;在struts.properties文件中,每一个entry都被视为一个常量;在web.xml文件中FilterDispatcher的初始化参数被载入为常量。

下面分别给出3中常量形式的例子

struts.xml文件中常量

       <struts> 

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

       </struts>

struts.properties文件中常量

        struts.devMode = true

web.xml文件中常量

    <filter>

        <filter-name>struts</filter-name>    

       <filter-class>

                   org.apache.struts2.dispatcher.FilterDispatcher

      </filter-class>

        <init-param>

                 <param-name>struts.devMode</param-name>

                 <param-value>true</param-value>

        </init-param>

    </filter>

 

5.视图模型

<result type="" name="">/user/showUser.jsp</result>

 

type:

 

转发:

dispatcher(默认)

转发至url(指jsp文件,不能转发至.action的url)

chain

转发至action

重定向

redirect

重定向至url

redirectAction

重定向至action

 

name: 视图模型对应的名称

success: success

input:验证失败返回的视图模型 如:<result name="input">/student/addStu.jsp</result>

6.struts2验证机制

6.1安全性验证:

        1.客户端         通过js验证

         2.服务器端     

                            服务器代码验证:必须

                            数据库验证:非必须

6.2 struts2验证

分为validate验证和action验证

Validate验证:主要是与业务无关的验证,如用户名不能为空

Action验证:与业务相关的验证,如用户名重复的验证

实现:

         1.action类extends ActionSupport类

         2validate验证

.重写validate()/validateXxx()方法,this.addFieldError("", "");

                   validate方法在对应的action方法执行前执行,若验证失败会自动返回“input”视图模型

         例:        

/**

          * 验证所有的action

          */

         public void validate(){

                   if(stu==null||stu.getStu_id()==null||stu.getStu_id().trim().equals("")){

                            this.addFieldError("stu_id", "学号不能为空");

                   }

                   if(stu==null||stu.getStu_name()==null||stu.getStu_name().trim().equals("")){

                            this.addFieldError("stu_name", "姓名不能为空");

                   }

                  

         }

validate Addstu ()只验证特定的action

3.action验证,

this.addActionError("");return Action.INPUT;需要显示的返回input视图模型

/**

          * 添加学生

          */

         public String addstu(){

                   if("s001".equals(stu.getStu_id())){

                            this.addActionError("用户已被注册");

                            return Action.INPUT;

                   }

                   stuSer.addStu(stu);

                   System.out.println("添加学生");

                   return "success";

                  

         }

4,页面显示错误信息

<s:fielderror fieldName="stu_id"></s:fielderror>

<s:actionerror/>

7.struts2servlet API(application interface)交互

有两种方式:

  1. ServletActionContext

耦合较高,获取真实的servlet API

使用:

ServletActionContext.getRequest()/getResponse()/getServletContext

  1. ActionContext

低耦合,struts2封装了的servlet API(主要用传值)

使用:

Map<String,Object> session = ActionContext.getContext().getSession();/getApplication()

session.put("userList", userList);

Map<String,Object>request=(Map)ActionContext.getContext().get("request");/get(“response”);

request.put("deptList", deptList);

原理:

ActionContext容器,每个线程产生一个actioncontext,用于管理该线程下的action.请求第一次到达时创建actioncontext,以及action实例,以后请求到达时重新创建action实例,线程安全。

8.ognl(object graph navigation language,对象图形导航语言)

Context

与作用域通信对象的进行交互,不推荐使用

 

ValueStack

与action属性进行交互,每次取栈顶元素的属性

 

 

 

  

主要标签:

<s:property value="user.user_id"/>取出action的属性值(该属性必须给get/set方法)

<s:property value="#session[‘user_id’] "/>取作用域通信对象的值,map的值

<s:iterator value="#session['userList']">(iterator用于从List/Map等集合中取值)

         <s:property value="user_id"/>

</s:iterator>

<s:textfield name="user.user_id">

<s:radio name="user.user_sex" list="#{0:'男',1:'女'}" ></s:radio>

<s:checkboxlist name="user.user_hobby" list="#{0:'唱歌',1:'跳舞',2:'绘画'}" value="user.user_hobby"></s:checkboxlist>(value和name给一个就可以的)

<s:select name="user.dept_id" list="deptList" listKey="dept_id" listValue="dept_name" ></s:select>

</s:from>

#的用法:

#parameters.id[0]

#request['deptList'].dept_id/#request.deptList.dept_id

#session['userList']/#session.userList

#application['user']/#application.user

关于<s:>${}html

html标签中可以放置<s:>和${}

         <a href="showAUser.action?user.user_id=<s:property value="user_id"/>">修改</a>

         <a href="delUser.action?user.user_id=${user_id }">删除</a>

.<s:>标签中不能放置<s:>和${}

         <s:form action="${basePath}">错误

         <s:textfield value="<s:text name='submit'></s:text>"/>

9.拦截器(interceptors)

9.1概念:

使用动态代理机制,(依赖于字节码工具,如asm)使得普通的action类具有处理请求的能力。

拦截器在Action执行之前和之后拦截请求,执行逻辑处理;

Struts2大多数核心功能都是通过拦截器实现的;

使用拦截器有利于系统解耦,使系统功能具有了可拔插性。

9.2工作顺序

按照配置文件中拦截器的顺序执行,返回时反顺序执行。

9.3 自定义拦截器

1.编写interceptor类,extends AbstractInterceptor

2.重写 intercept(ActionInvocation invocation) throws Exception {

                   String result = invocation.invoke();

}

3.配置拦截器:

<interceptors>

  <interceptor name="mylogger" class="com.guigu.interceptor.MyLoggerInterceptor" />

</interceptors>

3.action中引用拦截器

<action name="addUser" class="com.guigu.action.UserAction" method="addUser">

           <result>/user/showUser.jsp</result>

         <interceptor-ref name="defaultStack" /> (必须引用默认拦截器)

         <interceptor-ref name="mylogger" />

  </action>

9.4扩展:

拦截器栈

声明拦截器栈

<interceptors>

         <interceptor-stack name="myDefaultStack">

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

         </interceptor-stack>

</interceptors>

引用拦截器栈

<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>

9.5应用:避免表单重复提交

1.原理:请求到达时页面生成令牌,并在session中也存入该令牌,action中判断两者的令牌是否相同,若相同认为是有效的请求,并进行处理。若不相同,返回到无效的页面。

2.struts中通过TokenInterceptor和TokenSessionInterceptor来避免重复提交

3.实现:

a)页面:<s:token/>放置令牌

b) action中引用interceptor

1.token

<interceptor-ref name="token"/>

<interceptor-ref name="defaultStack"/>

<result type="chain">personList</result>

<result name="invalid.token">/error.jsp</result>(显示给出错误页面)

2.sessiontoken

         <interceptor-ref name="tokenSession"/>

         <interceptor-ref name="defaultStack"/>

         <result type="chain">personList</result>

         <result name="invalid.token">/error.jsp</result>(可以不显式给出错误页面)

c) 在全局资源文件中,使用下面的键自定义错误提示信息:struts.messages.invalid.token

d)显示错误信息<s:actionerror>

10上传

步骤:

1)配置上传文件的最大容量:

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

2)页面上的表单:

<s:form action=" " method="post" enctype="multipart/form-data">

<s:file name="img" label="上传头像"></s:file>

3)action中处理:

private File img;

         private String imgContentType;

         private String imgFileName;

public String addUser(){

basePath = ServletActionContext.getRequest().getRealPath("/");

FileUtils.copyFile(img, new File(basePath,imgFileName));

}

(提示:如果存数据库的话:user.setUser_photo(imgFileName)

写工具renameFile  System.currentTimeMillis()+fileName.substring(fileName.lastIndexOf("."))

11.国际化:

1.配置:

<!-- 国际化配置   -->

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

2.写属性文件:

lan_en_US.properties

lan_zh_CN.properties

      中文加密:C:\Program Files\Java\jdk1.6.0_22\bin\>native2ascii 1.txt 2.txt,其中,1.tx是中文源文件,2.txt为加密后的文件)

12.类型转换器

Struts2内置了常用的类型转换器,编者可以自行编制类型转换器

实现:

  1. 类extends StrutsTypeConverter
  2. 重写

private static final SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");

@Override

public Object convertFromString(Map arg0, String[] values, Class arg2) {

           try {

                    return df.parse(values[0]);

           } catch (ParseException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

           }

           return null;

}

 

@Override

public String convertToString(Map arg0, Object date) {

           return df.format(date);

}

  1. 编写properties文件

全局:src下xwork-conversion.properties

java.util.Date=com.guigu.convert.MyDateConvert

    

指定action:

在action包下编写 UserAction-conversion.properties

         User.user_id=com.guigu.convert.MyDateConvert

 

转载于:https://www.cnblogs.com/windy-85/archive/2012/10/02/2710473.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值