struts2的学习笔记

struts2的学习笔记
struts2的文档,主要看主页面的Guides下的内容
1、在struts.xml中加<constant name="struts.devMode" value="true"/>设置为开发模式,会自己检测配置文件的改动,在产品发布时设置value="fasle"
<constant name="struts.i18n.encoding" value="gbk"/>设置struts2的国际化(internationalization因为在i和n之间有18个字母)
constant的name的属性可以在struts2-core-2.16.jar下的org.apache.struts2下的static下的default.properties文件中找
2、在配置文件package标签的配置
namespace决定了action的访问路径,默认为""(不写namespace),可以接受所有路径的action。
例如:
<package name="main" extends="struts-default">
    <action name="index">
        <result>/namespace.jsp</result>
    </action>
</package>
对于这样的配置,url可以是:http://127.0.0.1:8080/appname/index.action或是http://127.0.0.1:8080/appname/xxx/index.action都可以响应。
namespace可以写为/,或者/xx,或者/xx/yy,对应的action说路径为/index.action,/xx/index.action,/xx/yy/index.actiion
    一般namespace用的是模块名进行命名。
3、struts2中的三种action
    1) 普通的java类,但要有一个方法:public String execute()
    2) 直接实现Action接口
    3) 继承抽象类ActionSupport(一般都只用这种,因为ActionSupport封装了许多有用的方法)
4、路径问题
    struts2中的路径问题是根据action的路径,而不是jsp路径来确定的,所以不要使用相对路径。解决方法:
    1) 用redirect方式解决;
    2) 在jsp中用request.getContextPath方式来拿到webapp的路径(用webapp的相对路径);
    例如<a href="${request.getContextPath}/index.jsp">首页</a>
    3) 使用myeclipse经常用的,指定basePath
    <% String path=request.getContextPath;
    String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%>
    在页面的head标签中加入<base href="basePath"/>,用的时候直接写<a href="index.jsp">首页</a>
    或者 <a href="<%=basePath%>index.jsp">首页</a>
5、struts中对action的三种配置(action继承自ActionSupport)
    例如:
    com.aliang.action.UserAction
        添加用户的方法 add_User()、删除用户的方法delete_User()
       
    1) 一个action的方法对应一个action的配置
    <package name="user" extends="struts-default" namespace="/user">
        <action name="add_User" class="com.aliang.action.UserAction" method="add_User">
            <result>/add_User_Success.jsp</result>
        </action>
        <action name="delete_User" class="com.aliang.action.UserAction" method="delete_User">
            <result>/delete_User_Success.jsp</result>
        </action>
    </package>
    访问方法 http://127.0.0.1:3306/webappname/user/add_User 访问的是UserAction的add_User()方法
    2) 同一个action类的所有action方法配置在一action标签中(DMI 动态方法调用)
    <package name="user" extends="struts-default" namespace="/user">
        <action name="user" class="com.aliang.action.UserAction">
            <result>/result.jsp</result>
        </action>
    </package>
    访问方法 http://127.0.0.1:3306/webappname/user/user!add_User或者 http://127.0.0.1:3306/webappname/user/user!delete_User
    但这种的result中要么共享同一个、要么每个返回一种,都在action标签中配置一种Result
    3) 使用*来通配
    <package name="user" extends="struts-default" namespace="/user">
        <action name="*-*" class="com.aliang.action.{2}Action" method="{1}_{2}">
            <result>/{1}_{2}_Success.jsp</result>
        </action>
    </package>
    访问方法 http://127.0.0.1:3306/webappname/user/add_User访问调用的是com.aliang.action.UserAction的add_User方法,跳转的页面是add_User_Success.jsp
    这样的配置可以用于多个action,但要求命名要统一。
6、action封装参数(action要继承处ActionSupport)
    1) 用action的属性来接受并封装参数
            为属性添加set和get方法,并在页面中的名字要与set方法的后部分相同
    2) 用对象封装属性(域模型domain model)
        在action的属性为对象,并为其添加set和get方法
        如有一个 User user=null;的属性
        在页面中用user.name、user.age将参数的值传给action的user属性
    3) 用ModelDriven接受参数,(让action实现ModelDriven接口)
    例如:有如下的action
    public class UserAction extends ActionSupport implements ModelDriver<User>{
        private User user=new User();
        @Override
        public User getModel(){
            return user;
        }
        public String add(){
             System.out.println("user.name="+name);
             System.out.println("user.age="+age);
             return SUCCESS;
        }
    }
    struts2先new 一个UserAction,当struts2发现该action实现了ModelDriven接口,就会调用它的getMode()方法,并返回一个Mode(User),再调用mode的get方法将其set到user的属性名相对应的属性
7、struts2的中文问题
    一般如果要使用中文,form的method一般设置为post
    2.1.7版本以后加<constant name="struts.i18n.encoding" value="gbk"/> 国际化后可以正常显示中文,不加默认是utf8
    2.1.6版本及以前的版本在web.xml中的使用
    <filter-class>org.apache.struts2.dispatch.FilterDispatcher</filter-class>这个过滤器,可以将中文乱码问题解决
    但apache推荐使用的是新版本的过滤器,新版本的在2.1.6之后的版本中才支持国际化解决中文问题,或者也可以使用spring来解决这个问题新过滤器是:
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
7、数据验证、取得web元素
    ActionSupport的addFieldError("name","name is error");
    在action中调用this.addFieldError("name","name is error");当name属性验证没通过时设置错误信息"name is error",可以对同一个属性加多次错误信息。在页面中用struts2的标签来显示错误,要使用struts2标签首先要引入标签库:
    <%@taglib uri="/struts-tags" prefix="s"%>
    struts-tags.tld在struts2-core-2.16.jar下的META-INF目录下
    然后使用标签<s:fielerror fieldName="name" theme="simple"/>fileName属性对应action中的addFieldError("name","name is error")方法的"name"。这样的样式固定,要加样式,在css中要定义一个与生成的标签的class属性名相同的样式来控制
    <s:debug></s:debug>该标签会生成一个用于调试程序的链接,该链接可以查看Value Stack Contents、Stack Context(访问stack Context中的值要加#,例如<s:property value="#request.student.name">)中的详细信息
    <s:property value="属性名"/>只能用于取Value Stack Contents和Stack Context中的值
    value="属性名"取Value Stack Contents中的值、value="#属性名"取Stack Context中的值。
    这里取出的是一个map,例如<s:property value="errors"/>取出的是:{name={name is error}},而map的value又是一个数组,如<s:property value="errors.name"/>取出的是:[name is error];正确的用法是:<s:property value="errors.name[0]"/>这样取出的值才是:name is error。errors.name[0]这样的表达式就是一个OGNL表达式
8、取得Map类型的request、session、application和真实类型的HttpServletRequest、HttpSession、ServletContext
    1) 取得Map类型的request、session、application:
    方法1(一般加在构造方法中)
        request=(Map)ActionContext.getContext().get("request");
        session=ActionContext.getContext().getSession();
        application=ActionContext().getContext().getApplication();
    方法2(一般都只用这种方法,session最常用)
        让action实现RequestAware、SessionAware、ApplicationAware接口
        在action中加map类型的request、session、application属性(带get和set方法)就可以直接使用,因为只要你的程序实现了xxxAware接口,struts2的IOC机制会自动将xxx属性注入进来。
    2) 取得真实类型的HttpServletRequest、HttpSession、ServletContext
    方法1(一般加在构造方法中)
        request=ServletActionContext.getRequest();
        session=request.getSession();
        application=session.getServletContext();
    方法2(使用IOC)
        让action实现ServletRequestAware接口
        为action定义:
        HttpServletRequest request;
        HttpSession session;
        ServletContext application;
        这个三个属性(有set和get方法),struts容器会自动将这三个属性注入进来
        直接使用就可以。
9、模块包含(包含struts的子配置文件)
    在struts.xml的<struts></struts>之内加<include file="xxx.xml">将xxx.xml文件包含进来
10、默认action
    在struts.xml的<struts></struts>之内加<default-action-ref name="index"></default-action-ref>当用户请求的action找不到时默认会找index.action
11、Result的配置
    1) type 不配置默认是:dispatcher(相当于forward到一个jsp页面)
    type的取值:dispatcher(forward到一个jsp或者html页面)、redirect(重定向到另一个页面)、chain(跳转到另外一个action)、redirectAction(重定向到另一个action)、freemarker、httpheader(http头信息)、stream(一般下载时使用)、velocity(和freemarker差不多)、xslt、plaintext(显示页面的源码、html的源码,一般做教学时会用到)、tiles
    2) 全局的result
        <global-results>
            <result name="mainpage">main.jsp</result>
        </global-results>
        可以加在<package></package>标签内,如果一个package中的action想访问另一个包中的global-results可以将要访问的action所在的package的extends属性设置为想要访问的global-results所在的package的名字
    3) 动态的result
        <action name="user" class="com.aliang.action.UserAction">
            <result>${r}</result>
        </action>
        r是UserAction中的一个String类型的成员变量(不是属性)用来在action中动态的保存要跳转的jsp页面的路径。$用来在配置文件中取Value Static取值
    4) 利用result传递参数
    <action name="user" class="com.aliang.action.UserAction">
        <result type="redirect">/user_success.jsp?t=${type}</result>
    </action>
    type是action中的属性
    一个request一个Value Stack Contents(值栈)所以当原始页面请求user.action的时候产生一个值栈,而当原始页面再次请求user_success.jsp时没有action所以产生的值栈是空的,因此在user_success.jsp页面不能用<property value="t"/>来取值,这样取是在Value Stack Contents中取值因此取到的也是空
12、OGNL(Object Graph Navigation language)
    当使用user.xxx给user传参数时才创建user实例,或者在action直接先new一个对象,否则在值栈中是一个空值。因此,如果想要初始化domain model时可以给要初始的domain model传一个参数,或直接在action中new 一个domain model
    1) 访问值栈中的action的普通属性 <s:property value="username"/>
    2) 访问值栈中对象的普通属性(get set方法) <s:property value="user.age"/>
    3) 访问值栈中对象的对象类型的属性(get set方法) <s:property value="cat.friend.name"/>
    4) 访问值栈中的普通方法 <s:proerty value="password.length()"/>
    5) 访问action的普通方法 <s:property value="actionDoIt()"/>
    --------------------------------------------------------
    在Struts2.0中访问静态方法可直接按下面的写,在struts2.1及以后还要在struts.xml中的<struts></struts>标签中加<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    6) 访问一个类的静态方法 <s:property value="@com.aliang.Test@getStr()"/>,访问com.aliang.Test类的静态方法getStr()
    7) 访问一个类的静态属性 <s:property value="@com.aliang.Test@NAME"/>
    8) 访问Math类的静态方法 <s:property value="@@max(2,3)"/>
    ---------------------------------------------------------
    9) 访问普通类的构造方法<s:property value="new com.aliang.User(8)"/>返回一个利用相应构造方法构造的User类型的对象
    10) 访问List <s:property value="users"/>users是一个List<User>;
    11) 访问List中某个元素 <s:property value="users[1]"/>
    12) 访问List中元素某个属性的集合 <s:property value="users.{age}"/>
    13) 访问List中元素某个属性的集合中特定值 <s:property value="users.{age}[0]"/>或者<s:property value="users[0].age"/>
    14) 访问Set <s:property value="dogs"/> dogs是Set<Dog>
    15) 访问Set中某个元素 <s:property value="dogs[1]"/>这样是访问不到的,因为set没有顺序
    16) 访问Map <s:property value="dogMap"/> dogMap是Map<String,Dog>
    17) 访问Map中某个元素 <s:property value="dogMap.dog001"/>或者<s:property value="dogMap['dog001']"/>或者<s:property value="dogMap[/"dog001/"]"/> dog001是key的值
    18) 访问Map中所有的key <s:property value="dogMap.keys"/>
    19) 访问Map中所有的values <s:property value="dogMap.values"/>
    20) 访问集合的大小 <s:property value="dogMap.size()"/>或者<s:property value="dogMap.size"/>
    21) project投影(过滤) ?代表过滤条件,^代表开头,$代表结束
        (1) <s:property value="users.{?#this.age==1}.{age}"/>找出users中age等1的所有User的age的集合  其中users是一个List<User>,this是指循环遍历的当前对象。<s:property value="users.{?#this.age==1}"/>得到的也是一个集合
        (2) <s:property value="users.{^#this.age>1}.{age}"/>找出users中age大于1的集合中的第一个user的age
        (3) <s:property value="users.{$#this.age>1}.age"/>找出users中age大于1的集合中的最后一个user的age
        (4) <s:property value="users.{$#this.age>1}.{age}==null"/>判断集合是不是空
    22) []访问集合
        <s:property value="[0]"/>这样会从Value Stack的栈顶开如访问整个栈
13 struts标签
    1) 通用标签
    struts中标签的属性是Object类型的都可以解析成一个ognl表达式
        a) property(value default escape)
            default给属性设置默认值<s:property value="admin" default="管理员"/>
            escape用于设置是否显示value中的html代码,默认是true <s:property value="<hr/>" escape="false"/>就会显示一条水平线
        b) set(id name scope value var)用于给变量赋值、重新命名
            id 和 name都不赞成使用
            scope定义默认的范围是action 在request和Action Context中都有变量
            如果指定了其它的scope则在action中不一定有这个对象
            <s:set var="adminName" value="username"/> username是action的一个User类型的属性
        c) bean(name var) 定义bean,并使用param来设定新的属性值
            <s:bean name="com.aliang.struts.Dog" var="myDog">
                <s:param name="name" value="'lostDog'"></s:param>
            </s:bean>
            这里定义了一个Dog类型的实例,并给其name属性赋值为"lostDog"因为value的值是一个对象类型,如果不加'号会当成ognl表达式处理
        d) include存在中文字符编码的问题
            <s:set var="incPage" value="'/_include1.html'">
            <s:include value="%{#incPage}"></s:include>
            include的value是string类型,在这儿想用ognl表达式 %{XXX}强制把XXX当作ognl表达式使用
        e) param(name value)
        f) debug用于调试
            <s:debug>调试</s:debug>
    2) 控制标签
        if elseif else
            <s:if test="#parameters[0].age < 0">wrong age!</s:if>
            <s:elseif test="parameters[0].age < 22">too young!</s:elseif>
            <s:else>you can marray!</s:else>
        iterator
            可以遍历:collections map 实现了enumeration或iterator接口的类 array
            <s:iterator value="{23,22,33}">
                <s:property />
            </s:iterator>           
           
            <s:iterator value="{'abc','aa','ab'}" var="x">
                <s:property value="#x.toUpperCase()"/>
            </s:iterator>
           
            <s:iterator value="{'abc','aa','ab'}" status="sta">
                遍历过的元素的总数:<s:property value="#sta.count"/>
                遍历过的元素的索引:<s:property value="#sta.index"/>
                当前遍历的个数是否是偶数:<s:property value="#sta.even"/>
                当前遍历的个数是否是奇数:<s:property value="#sta.odd"/>
                当前遍历的个数是否是第一个元素:<s:property value="#sta.first"/>
                当前遍历的个数是否是最后一个元素:<s:property value="#sta.last"/>
            </s:iterator>
           
            遍历map
            <s:iterator value="{1:'abc',2:'aa',3:'ab'}">
                <s:property value="key"/>或者<s:property value="value"/>
            </s:iterator>
           
            <s:iterator value="{1:'abc',2:'aa',3:'ab'}" var="x">
                <s:property value="#x.key"/>或者<s:property value="#x.value"/>
            </s:iterator>
           
        subset从集截取一部分
            <s:subset source="myList" count="12" start="3" var="mySubset">
                从myList这个集合中的第3个元素开始截12个元素出来,生成一个名叫mySubset的子集合
            </s:subset>
    3) UI标签
        theme主题有4种值(simple xhtml(默认) css ajax)
    4) AJAX标签
    5) $、#、%的区别
        $用于i18n和struts配置文件
        #取得Action Context的值
        %将原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用


14、异常处理
    有异常一般都抛到表示层来处理
    在struts.xml中配置如下:
    <action name="category" class="com.aliang.bbs.action.CategoryAction">
        <result>/WEB-INF/a.jsp</result>
        <exception-mapping result="error" exception="java.sql.SQLException"/>
        <result name="error">/WEB-INF/error.jsp</result>
    </action>
    全局异常的配置(大多数都是这种异常处理):
    在<package></package>标签中:
    <global-results>
        <result name="error">/WEB-INF/error.jsp</result>
    </global-results>
    <global-exception-mappings>
        <exception-mapping result="error" exception="java.sql.SQLException"/>
    </global-exception-mappings>
    注意:<global-result>要配在前边
15、国际化
    java.util.Locale
    java.util.ResourceBundle
    ResourceBundle rb=ResourceBundle.getBundle("app",Locale.US);
    第一个参数"app"传入的参数是资源文件的前部分,第二个参数代表的是国家Locale.CHINA
    rb.getString("资源文件中的key");
    这样会自动根据Locale的值来加载相应的资源文件
    资源文件是:app_en_US.properties    app_zh_CN.properties
    注意:在资源文件中不能放中文,要使用native2ascii 将其转换为utf8格式的,或者用myeclipse的PropertiesEditor(一个插件,要自己安装)来打开就直接写中文
    struts2的资源文件分三个级别:Action级-Package级-Application级
    Action级(很少用):要跟action在同个目录且名字要相同,如LoginAction对应的资源文件:LoginAction_en_US.properties,在页面用<s:property value="getText('login.username')"/>参数login.username是资源文件中的key,要换语言只要将浏览器中的语言改变就会自动选择对应的资源文件,getText()方法是ActionSupport中的方法
    packate级(很少使用):资源文件的名字必须要用package_en_US.properties
    Application级(一般只用这种):资源文件的命名根据自己起,如XXX_en_US.properties,放在src目录下。在struts.xml加入<constant name="struts.custom.i18n.resources" value="XXX"/>这里的value的值是资源文件名的开头部分。
    三种级别的国际化在页面中的使用都是 <s:property value="getText('资源文件中的key')"/>或<s:text value="资源文件中的key"/>来取得相应的语言表达的内容
    在资源文件中使用点位符:
    例如在资源文件中有: welcome.message=欢迎您:{0}登陆本系统
        的内容,在页面中可以用:
        <s:text name="welcome.message">
            <s:param value="username"></s:param>
        </s:text>
        来取得资源文件并为占位符0处填充值
    动态语言切换:在请求的url后边加:?request_locale=en_US或者zh_CN
16、重复提交的问题
    在struts2中有token拦截器,专用来处理重复提交
    <action name="user" class="com.aliang.action.UserAction">
        <result>addOK.jsp</result>
        <interceptor-ref name="defaultStack"></interceptor-ref>
        <interceptor-ref name="token"></interceptor-ref>
        <result name="invalid.token">error.jsp</result>如果重复提交,跳转的页面
    </action>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值