Struts2

1.MVC:模型、视图、控制器;不适合小型应用
   强制性地把应用程序的数据展示、数据处理和流程控制分开
   a.控制器接收用户的请求,并决定调用哪个模型进行处理,然后模型根据客户的请求进行相应的业务逻辑处理,
      并返回相应的数据;最后控制器调用相应的视图来格式化模型返回的数据,并通过视图呈现给用户。

    
线程安全:在一个进程中有多个线程并发执行,每个线程执行过程中,变量是相同的,执行结果也是相同的
  struts线程安全?
  每次请求都会创建新的action对象,所有线程安全(以资源为代价,效率低),根据实际考虑选择框架
  由于action是struts2 反射生成,所有必须要有公共的无参构造

Struts2中的RequestMap属性httpservletrequest修改一下:private 修改为public; 也可以提供一个读写器

 修改struts2源代码有两种方式:

1.将原来的整体代码导入到Eclipse;修改单独的文件;重新编译成class,class文件放入到JAR包中(破坏源码完整)

2. 在项目中,文件放自定义src下,创建一个和源代码同名,同包的文件名;修改相应的代码;就可以执行

执行顺序:java会先到项目中寻找class执行;如果找不到;再到JAR包中寻找;    

提取方法:
选中代码-->右键refractor-->extract method

修改源代码:
     找到对应的源码文件,新建source_folder,然后将该源码文件复制到对应的新文件,修改则项目会优先去编译自定义的source_folder文件



文件会按顺序执行
 <!-- <include file="struts_fileupload.xml"/>   -->
 <!-- <include file="struts_filedownload.xml"/>  -->
 <include file="struts_*.xml"/>                //constant常量最好放在struts.xml中

规范要求:name与namespace最好一致,不同包下的namespace最好不同,不然会冲突
<package name="down"   namespace="/testdown" extends="struts-default" strict-method-invocation="false">
参考博客:http://blog.chinaunix.net/uid-27795088-id-3802878.html

struts2.5使用通配符时需要增加:
<package name="mytest02" extends="struts-default" namespace="/my"  strict-method-invocation="false">  

http://java.sun.com/jsp/jstl/core  在standard.jar中查找c.tld ,standard.jarjstl.jar的实现类包

用到struts的信息提示,都需要继承ActionSupport

注解编程:struts.xml最好保留,即使没有内容


 <package name="json-default" extends="struts-default">    
  JSONResult文件位置:org.apache.struts2.json.JSONResult.class
  位于struts2-json-plugin-2.5.2.jar包中struts-plugin.xml

ognl中去map值#attr  一般是以#开头

validation的dtd文件拷贝

2.Struts:控制器
   FilterDispatcher和Action类  org.apache.struts2.dispatcher.FilterDispatcher(struts1的过滤器)
   struts-core:  org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
   FilterDispatcher主要负责接收HTTP请求,并根据Struts.xml的配置信息,把请求转发给对应的Action对象;
   如果该Action不存在,FilteDispatcher会先创建这个Action对象。
   Action:继承于ActionSupport
   主要负责调用模型的方法,更新模型的状态,在小型应用,可以完成一些实际的业务逻辑
   但是主要功能是将数据展示与业务逻辑分开,Action(execute())会根据客户请求调用相关的业务逻辑组件。
   
   
3.搭建Struts项目
   1.项目文件结构:将D:\MainSoftWare\structs2\struts-2.3.16.1\apps\struts2-blank\WEB-INF\lib下的jar(去除带plugin的jar)文件拷贝到对应的web->lib目录
           
   如果运行时出现  Could not find property [struts.valueStack] ,记得查看是否缺log4j-1.2.8.jar包
   2.配置struts.xml,  name="Login"就是http://localhost:8080/TestStruts/Login  
      struts.xml最大的作用:配置Action和请求之间的对应关系,并配置逻辑视图名和物理视图资源之间的对应关系,默认服务器端跳转
    
  3.编写java代码(可以不extends ActionSupport),一般命名为xxxAction,action相当于Servlet,execute相当于service 
   
   3.注意过滤器应写对
   
 4.配置result.jsp,注意uri和message(是指Login.java中的getMessage())
   
------------------------------------------------------------------------------------------------------------------------------------
为什么要使用框架:
   1.Web.xml
       1.1 Servelt数量多时,全部放到web.xml中,web.xml会和臃肿
       1.2 多人共同完成一个项目,多人修改web.xml则可能出现冲突
   2.Servlet需要写多个方法,业务逻辑代码臃肿,大量重复(如用户添加)
       
eclipse集成插件:eclipse plugin官网查找插件
打开硬盘目录:show in->System folder
遇到404但是有代码:优先项目clean,然后tomcat进行clean
开发资源网站:apache.org

5.常量配置  

   常量配置(1.在struts.xml配置  2.在src增加strtus.properties  3.团队协作开发的配置)
   struts-core内的default.properties文件struts.i18n.encoding=utf-8  //版本不用,可能是其他编码
   <constant name="struts.i18n.encoding"  value="UTF-8"/>                  //struts.xml配置编码格式
   自定义扩展名:
  <constant name="struts.action.extension" value="action,,kkk"></constant>
  则在表单提交时可以为login.kkk作为action名称
  自动重新加载:
  <constant name="struts.configuration.xml.reload"  value="true"/>
  开发模式:
  <constant name="struts.devMode" value="true"/>
  团队开发:
   <include file="team/config/struts2/login.xml"/>          //指明自定义的login.xml文件
 
   包配置:
   name 包名称,在struts2的配置文件文件中 包名不能重复 ,name并不是真正包名,只是为了管理Action 
   namespace :不同模块可以指定不同的空间   如:namespace="/user"   则访问是应该是/Demo/user/xxx.action
   但是result对应的文件须是绝对路径,如 /xx.jsp
   命名空间:同一个命名空间不能有同名的actiion,但不同的命名空间可以有同名的Action
   extends 继承哪个包,通常开发中继承 struts-default 包 (struts-default包在 struts-default.xml定义 ) 
   继承struts-default后,可以使用 包中定义拦截器和结果类型 
   action元素配置默认值   name不能再写 /
   package 的namespace 默认值""
   action 的class 默认值 ActionSupport 类     要求:包名+类名,并且要有公共的无参构造方法
   <default-class-ref  class="com.kkk.Login"/>    //配置默认的处理类
   <default-action-ref  name="login"/>         //配置默认action

   result 的 name 默认值 success
   result的type=   
       1.chain:指action链,执行actionA以后直接执行ActionB后继续执行ActionC...,用的少
          地址栏是第一个action
       2.dispather:转发(和Servlet一致);如果request中有数据要显示,则用dispatcher   
                不能转发到一个action(因为转发到新的action里面不需要上一个action的数据)
       3.redirect:重定向;对应jsp页面,可以直接重定向;重定向另一个action需注意配置了action的后缀名,如果要求有后缀名,
          那么重定向的action需要加上后缀名
       4.redirectionAction:重定向到另一个action,不用加后缀名,struts会自动加上前一个action的后缀
       5.stream:以流的形式显示,用于文件下载
   
    全局结果集配置:同样放在package里面
    
   指定LoginAction的处理方法为logout();默认为execute()
   
   
   通配符配置:可以减少action的配置,{1} 表示第一个*所代表的内容;可以配合DMI(动态方法调用),不推荐存在安全隐患(官网上说)
      {1} 会在AddAction类中查找模糊匹配的处理方法   
   

 <!-- 没有设置basepath必须写${pageContext.request.contextPath }/,否则后端识别不到url -->
 <form action="${pageContext.request.contextPath }/user/user_insertAdmin" method="post"> 
  <!-- 设置basepath之后可以不再写 ${pageContext.request.contextPath }/-->
  <form action="user/user_insertAdmin" method="post">  

6.action的实现方式:
   1.定义一个pojo类,通过action的class指向HelloAction
      好处:自定义一个普通的java类即可,不具有侵入型(可以优先考虑),默认执行execute()
      
  2.实现Action接口,好处,使得编写的代码更规范
  
 Action的五个常量 
       public static final java.lang.String SUCCESS = "success";
       public static final java.lang.String NONE = "none";
       public static final java.lang.String ERROR = "error";
       public static final java.lang.String INPUT = "input";
       public static final java.lang.String LOGIN = "login";
3.继承ActionSupport  可以继承一些ActionSupport实现功能,如:验证;
     

7.属性驱动:  复制的项目,需要改myeclipse->web->web Content-root的名称,与当前项目名称一致
   action中的属性应与前台表单属性名称一致,然后有对应的get和set方法
   前台表单写法<input  type="text"  name="name"/>
   private String name;
   满足三要素:
   1.必须为action的属性
   2.必须提供读写器(set/get)
   3.form中的name必须和action的属性一样
       时间格式要求:必须为yyyy-MM-dd HH:mm:ss
   优点:
       自动接收参数、自动处理参数、自动放到request中

8.对象驱动(模型):将对象放入ValueStack;   实体类属性较多的时候,可以先考虑对象驱动开发
   private  User  pYear;     //不能这样写,因为struts设置值会出问题
   private User  user;          //正确写法;  前台表单写法<input  type="text"  name="user.name"/>
 
   属性对象:
     三个要求:
      1.必须为action的属性
      2.必须提供读写器(set/get)
      3.form 中的name必须对应action中的对象名.属性
          时间格式要求:必须为yyyy-MM-dd HH:mm:ss
      好处:
          自动接收参数、自动处理参数、自动new对象、自动赋值、自动放到request作用域中

9.struts2两种方式获取servletAPI,解耦和耦合
   1.解耦使得struts2来进行测试的时候,不需要启动服务器,在一定程度上提高开发效率
      action(控制)-->service(业务处理)-->dao

   2.使用解耦的方式来获取servlet.api,通过ActionContext(一种map)对象获取  (建议);
      通过ActionContext获取的session、request、application获取的不是真正的HttpServletRequest、HttpServletResponse、
      ServletContext对象,而是这三个对象的值被重新包装后的map对象
     ActionContext.getContext().getSession().put("user"user);   //获取session
     Map<String,Object> application=ActionContext.getContext().getApplication();  
     Map<String,Object> parameters=ActionContext.getContext().getParameters();
     Map<String,Object> request=(Map<String, Object>) ActionContext.getContext().get("request");
  ((String[])parameters.get("name"))[0]  --paramters的参数值为数组形式

  3.通过ActionContext可以获取HttpServletRequest等多个对象,但没有session,可以另外通过request.getSession()等形式获取session
     HttpServletRequest request2=(HttpServletRequest) ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);
     request2.getSession()     //手动获取session

  4.快捷获取request对象,实现ServletRequestAware,然后重写setServletRequest()方法,将request对象赋值给对应的HttpServletRequest
      实现 ServletContextAware接口:则能访问Web应用的ServeltContext实例
      实现 ServeltRequestAware接口:则能访问HttpServletRequest实例
      实现ServletResponseAware接口:则能访问HttpServeltResponse实例

  5.通过工具类ServletActionContext(耦合)   (建议)
      HttpServletRequest request3=ServletActionContext.getRequest();

10.struts1和struts2的对比


11.
  



12.ActionContext六大对象:
    1.application
    2.session
    3.request
    4.parameters
    5.attrs(page->request->session->application)逐级找
    6.valueStack(值栈 先进后出 ,action的值存放) 不建议操作
       struts中valueStack存放的是action对象

13.Ognl(对象图形导航语言)表达式:常用的数据直接取,不常用的加#取
     常用的一般是小数据(valueStack),不常用的一般是大数据(actionContext)
     页面导入:<%@taglib prefix="s" uri="/struts-tags"%>
     LoginAction中有name属性,则ognl可以直接去<s:property  value="name"/>
     注意:要使用struts2的标签,则要通过struts2的过滤器来启用。如果过滤器的配置为*.action结尾时,
      则不能直接访问.jsp页面,需要经过action跳转;如果过滤器为/*,可以直接访问.jsp页面(推荐使用action来控制)
     使用ognl表达式访问action的属性时,可以直接访问;访问actionContext中的数据需要加#
     ValueStack vs=ActionContext.getContext().getValueStack();
  使用:<s:iterator value="list" var="bean">
                 <s:property value="id"/>
            </s:iterator>

14.类型转换:自定义类型使用的频率较高,可以使用struts2提供的类型转换器转换  
     1.编写类型转换器,继承strutsTypeConvert类,重写convertFromString()和convertToString()
     2.编写Xwork-conversion.properties,放在src下,内容为要转换的类型=类型转换器
       

15.服务端验证:如果action继承ActionSupport类,则该action类将会继承ActionSupport的相关功能,
     如验证功能(先validateXXX(),然后validate(),再execute())
     如果执行的是Action中execute方法,则只会执行validate();  如果执行的是自定义action,则先执行validateAge()--validate()--age()小写
     this.addFieldError(“非法”);  或者this.addActionError("非法");  错误提示
     前段增加<s:actionerror/>
     
16.验证框架:
    1.在对应的action包下添加一个验证框架的配置文件xxxaction-validation.xml
     

17.拦截器和过滤器类似,在action的前后执行,struts的核心功能都是通过拦截器(单例)来实现。
     拦截器栈:由多个拦截器组成
     作用:对于一些公共的处理代码可以放到拦截器中实现,如权限控制和日志
   拦截器和过滤器的区别:
     1.过滤器属于Web容器,可以过滤一切请求(如action、servlet、jsp等)
     2.拦截器属于struts2框架,只能拦截action(无法拦截对jsp的请求)
     3.过滤器内部采用函数回调来实现,拦截器采用动态代理实现
       多个拦截器之间采用责任链设计模式来实现
     
     实现拦截器步骤:
     1.编写拦截器(实现interceptor接口或者继承AbstractInterceptor类)
     2.在struts.xml中配置拦截器
     3.在action中引用拦截器
        invocation.invoke()
   

18.拦截器配置:
    a)当引用了自定义拦截器,默认拦截器将不起作用
    b)默认拦截器:在struts-default.xml中,配置了默认拦截器。当配置默认拦截器后,如果不引用拦截器,则默认拦截器将起作用。
       <default-interceptor-ref name="defaultStack"/>
   c)当引用自定义拦截器后,又想使用struts2提供的拦截器功能,则需手动引用
      <action name="hello" class="com.HelloAction">
              <result>/index.jsp</result>
              <interceptor-ref  name="time"/>           //自定义
              <interceptor-ref  name="defaultStack" />  
       </action>
    d)当action应用的拦截器个数比较多时,可以将多个拦截器放入一个拦截器栈中。
            <interceptor-stack name="myStack">
               <interceptor-ref  name="time"/>           //自定义
               <interceptor-ref  name="defaultStack" />  
            </interceptor-stack>
    e)当自定义拦截器栈在当前包下的所有action都使用的时候,可以定义为默认的拦截器栈或默认的拦截器

19.方法拦截器:继承MethodFilterInterceptor ,用于拦截method指向的具体方法
       <interceptor-stack name="myStack">
              <interceptor-ref  name="time"/>    //自定义
                    <param name="includeMethods">list,add</param>         //拦截list和add方法
                   <param name="execludeMethods">login</param>           //不拦截的方法
             </interceptor-ref>

20.文件上传:
    <input type="file" name="filename"/>      
    private File filename;         //filename必须与input的元素name值一致    
    //文件名     filename+FileName和filename+ContentType  在action中必须有
    private String filenameFileName;
    private String filenameContentType;
    String path=req.getRealPath("/uploadFile");  //获取临时文件目录,webapps/uploadFile,必须先存在才能接收文件
  OutputStream out=new FileOutputStream(new File(path,filenameFileName));  
     设置临时目录存放文件(默认最大2M):<constant name="struts.multipart.saveDir"  value="c:\"></constant>
     <interceptor-ref name="fileUpload">
            <param name="maxnumSize">20971520</param>      //最大上传文件大小
     </interceptor-ref>
     <interceptor-ref name="defaultStack"/>

22.文件下载:
     HttpServletRequest req=ServletActionContext.getRequest();
     HttpServletResponse resp=ServletActionContext.getResponse();
     String path=req.getRealPath("/downloadFile");  //获取路径
     File file=new File(path,"t_user.txt");
     resp.setContentLength((int)file.length());
     resp.setCharacterEncoding("utf-8");
     resp.setContentType("application/octet-stream");
     resp.setHeader("Content-Disposition""attachment;filename='t_user.txt'");       
     return null;                //结果返回null
    <action name="download" class="com.login.filedownload.FileDownload"></action>  //不需要配置result
StreamDownload方式下载文件:
    private String filename;
    public String execute(){
        return Action.SUCCESS;
    }
   public InputStream getInputStream() throws FileNotFoundException{
        HttpServletRequest req=ServletActionContext.getRequest();
        String path=req.getRealPath("/downloadFile");
        return new FileInputStream(new File(path,filename));
    }
 <action name="streamDownload" class="com.login.filedownload.StreamDownloadAction">
    <result type="stream">
        <param name="inputName">inputStream</param>      //inputStream则在action类中应提供对应的getInputStream方法
         <param name="contentDisposition">attachment;filename=${filename}</param>//与action类中的名字一样
    </result>
 </action>  














6.Struts框架搜索Struts常量顺序
    1.struts-default.xml:
    2.struts-plugin.xml
    3.struts.xml
    4.struts.properties:Struts的默认配置文件
    5.web.xml

7.由于过多配置在Struts.xml文件中会造成该文件过于臃肿,可以通过<include  file="struts-part01.xml"/>来解决

8.Action间接访问Servlet  Api
    ActionContext相当于HttpServletRequest的作用域:
    getApplication():返回ServletContext对象
  Action直接访问Servlet Api
   实现 ServletContextAware接口:则能访问Web应用的ServeltContext实例
   实现 ServeltRequestAware接口:则能访问HttpServletRequest实例
   实现ServletResponseAware接口:则能访问HttpServeltResponse实例
   ServletActionContext.getResponse().addCookie(cookie);  

9.action的基本配置:
   1.<action name="login" class="my.Login"/>         //name代表action的名字,访问该action的url为login
     如果name需要出现 /  则需要设置struts.enable.SlashesInActionNames为true
   2.默认的action:
       <default-action-ref  name="mydefaultAction"/>       
       <action  name="mydefaultAction"  class="my.Login">
   3.配置<action/>可以不指定class属性,则系统默认ActionSupport作为Action处理类
      action中属性的名称和表单中的属性name名称要一致,以便参数传递(因为struts2自动将用户提交的表单数据设置到
      对应的action属性,并且在jsp中可以直接获取,不用手动向request设置

10.使用Action的动态方法调用(DMI)
    1.form.action="login!regist"      //代表名为login的action里的regist来处理请求
       但是需要通过设置struts.enable.DynamicMethodInvocation常量来开启系统的动态方法调用 
    2.<action name="login"  class="my.Login"  method="regist"/>          //指定regist来处理请求
       但要求regist方法的参数列表为空,方法返回值为String
    3.使用通配符:
       form.action="regist"
       <action name="*Action" class="my.Login" method="{1}"/>        //如果请求的URL为registAction则交由
      my.Login的regist方法进行处理 
    4.<action name="*Action"  class="my.Login.{1}Action"/>       //类似3功能

11.对于使用srtuts2的应用,尽量不要让超链接指向某个具体的视图资源,因为会造成安全问题;推荐让所有
     请求发送给struts2框架,或者通过name="*Action"

12.对于多个action匹配:如果有url与属性的name值完全相同,就先匹配,否则将按action配置的先后顺序处理用户请求;
     因此推荐将name="*"的action配置放在最后

13.配置结果:
     局部结果:<result.../>作为<action.../>的子元素配置
     全局结果:<result.../>作为<global-result.../>的子元素配置
     如果一个Action里包含了与全局结果里同名结果,则Action里的局部Result会覆盖全局Result
  <result name="success"  type="dispatcher" >/WEB-INF/content/login.jsp</result>
      
       常见结果类型:1.chain:Action链式处理的结果类型
                                   2.dispatcher:用于将请求forward(转发)到指定的JSP资源    默认的结果类型:type="dispatcher"
                                   3.freemarker:指定使用freemarker模板作为视图的结果类型
                                   4.httpheader:指定特殊的Http行为的结果类型
                                   5.redirect:重定向到指定的视图资源  和dispatcher差别,会丢失所有的请求参数、请求属性和Action处理结果
                                      redirect不能重定向到/WEB-INF/路径下的任何资源,因为WEB-INF下的资源是受保护的资源
                                   6.redirectAction:用于直接跳转到其他Action
                                      与redirect区别是:redirectAction使用ActionMapperFactory的ActionMapper来重定向请求
                                      actionName:重定向指定的action名
                                      namespace:重定指定action所在的命名空间
                                      前一个action的处理结果、请求参数、请求属性都会丢失
                                   7.Stream:向浏览器返回一个InputStream(一般用于文件下载)
                                   8.velocity:指定使用Velocity模板作为视图的结果类型
                                   9.xslt:用于与XML/XSLT整合的结果类型
                                   10.plainText:显示某个页面的原始代码的结果类型
   在<result.../>中可以通过${0}.jsp指定视图资源,还可以${属性名}指定视图资源
   PreResultListener:可以在Action完成控制之后,系统转入实际的物理视图之间被回调
   一旦为拦截器添加PreResultListener监听器,则会对改拦截器所拦截的所有Action起作用。

14.Struts异常处理机制:
      execute() throws  Exception  但需要在struts-default.xml打开异常映射机制
     声明式异常处理:
     1.局部异常:<exception-mapping.../>元素作为action的子元素
     2.全局异常:<exception-mapping.../>元素作为<global-exception-mapping../>的子元素配置
    输出异常信息:
     1.<s:property  value="exception"/>   //输出异常对象本身       也可以用exception.message来输出异常信息
     2.<s:property  value="exceptionStack">   //输出异常堆栈信息

15.支持Convention,引入struts2-convention-plugin-2.3.16.1.jar
     1.Action的name属性根据Action的类名映射,规则:
         a.如果该Action类名包含Action后缀,则去掉Action后缀
             如:com.lzx.actions.LoginAction    映射到  /login.action
         b.将Action类名的驼峰写法转换成中划线写法(所有字母小写,单词与单词之间以中划线隔开)
            如:com.lzx.actions.books.GetBooks   映射到  /books/get-books.action
     2.映射Result:
        默认情况下,Convention会到web应用的WEB-INF/content路径下定位物理资源,按
       actionName+resultcode+suffix来匹配;当找不到对应的视图资源时,Convention会试图使用
       actionName+suffix作为物理视图资源。
    3.希望action处理结束之后进入action链;
       a.第一个action返回的逻辑视图字符串没有对应的视图资源
       b.第二个action与第一个action处于同一个包下
       c.第二个action映射的url:firstactionname+resultcode

16.安装struts2-config-browser-plugin-2.3.16.1.jar和struts2-config-browser-plugin-2.3.16.3.jar
      插件辅助开发调试,将其拷贝到lib目录,重启web应用即可
      http://localhost:8080/StrutsDemo/config-browser/actionNames.action

17.struts国际化:
     a.让系统加载国际化资源文件,加载国际化资源国际化资源两种方式:
         使用native2ascii命令才能生成对应的国际化文件
         1.自动加载:action范围内的国际化文件都由系统自动加载。
             action:在Action类文件所在的路径建立多个文件名格式为:ActionName_language_country.properties
         2.手动加载:Jsp(jsp一般使用<s:i18n/>)范围的国际化文件分别使用标签、配置常量来手动加载
           jsp中引入资源文件名:<s:i18n  name="目录 资源文件名">
     b.输出国际化:
        1.在视图页面输出国际化信息,使用Struts2的标签库
        2.在Action类中输出国际化信息,使用ActionSupport的getText()  
    c.包范围国际化:
        1.命名格式:package_language_country.properties,struts2会自动加载国际化文件

18.OGNL表达式语言:
     语法:#bar.foo.blah            -->获取bar.getFoo().getBlah()的返回
     struts内置命名对象:
     parameters:用于访问http请求参数,#paramters['user'] 或#paramters.user,相当于HttpServletRequest的getParamter("user");
     request:用于获取HttpServletRequest的属性,使用方法类似parameters,   getAttribute("user");
     session:获取HttpSession的属性,getAttribute("user");
     application:获取ServeltContext的属性,getAttribute("user");
     attr对象:依次搜索:PageContext、HttpServletRequest、HttpSession、ServletContext中属性
     当系统创建Action实例后,该Action的实例会被保存到ValueStack中,因此引用Action无需写#
       

   a. ValueStack(值栈):Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是
                                     OgnlContext),并将值栈设为OGNL的根对象。
   StackContext(map):stack上下文,它包含一系列对象,包括request、session、attr、applicationmap等
   b.访问Stack Context中的对象的属性时要使用"#对象名.属性名"的方式,
      使用push标签可以将原来位于StackContext中的对象放到ValueStack的栈顶。
      用push标签将对象保存在ValueStack的栈顶后,只需要使用"属性名"就可以直接访问了。  

   ognl集合:创建List:{e1,e2,e3...}   元素之间逗号隔开
                     创建Map:#{key1:value1,key2:value2....}  
     运算符:in  判断某个元素是否在指定集合中,not  in  不在集合中
     ?:取出所有符合逻辑的元素
      ^:取出符合逻辑的第一个元素
      $:取出符合逻辑的最后一个元素
      person.relatives.{? # this.gender == 'male' }

   访问静态成员:struts2默认关闭访问静态方法(设置struts.ognl.allowStaticMethodAccess为true),只许访问静态Field
    1.@className@staticField             //访问静态属性
       @className@staticMethod(val ..)   //访问静态方法

  常用控制标签:
  1.elseIf/elseif: 必须与if标签结合使用

  2.append:用于将多个集合拼接成一个新的集合

  3.generator:将一个字符串解析成一个集合(放入Stack Context)     requestScope
         count:属性,指定生成集合中元素的总数(即生成的元素不能超过count)
         separator:指定用于解析字符串的分隔符
         val:指定被解析的字符串

  4.merge: 将多个集合拼接成一个集合,与append的拼接方式不同

  5.iterator:将集合迭代输出
        <s:iterator status>    status属性带的方法:
        int  getCount()     //返回当前迭代了几个元素
        int  getIndex()      //返回当前迭代元素的索引
        boolean  isFirst()   //返回当前被迭代元素是否是第一个元素
        boolean  isLast()   //是否是最后一个
        boolean  isEven()  //索引是否是偶数
        boolean  isOdd()    //索引是否是奇数     使用形式: <s:if test="#st.odd">  

  6.sort:对集合进行排序
        comparator:指定进行排序的Comparator实例
        source:指定被排序的集合,默认对valueStack栈顶的集合排序
        var:将生成的Iterator对象设置成page范围属性,不放入Stack Context
       
  7.subset:截取集合的部分元素,形成新的子集合(不放入Stack Context)   pageScope
        count:指定子集中元素的个数,默认取得集合的全部元素
        source:指定源集合,默认取得ValueStack栈顶的集合
        start:指定子集从源集合的第几个元素开始截取,默认从0开始截取
        var:将生成Iterator对象设置成page范围的属性,同id,但推荐var属性

  8.<s:if.../> 标签可以单独使用,和<s:else>都可以接受一个test属性
     <s:if  test="表达式">   </s:if>     <s:if test="#age>50"></s:if>

list遍历:
<s:append var="myList">
    <s:param value="{'java','c++','ios'}"/>
    <s:param value="{'sss','qqq'}"/>
</s:append>
<table border="1" width="600">
    <s:iterator value="#myList" status="st" id="myelement">
      <tr>
        <td><s:property value="#st.count"/></td>        //count代表getcount()
        <td><s:property value="myelement"/></td>
      </tr>
    </s:iterator>
</table>  
map遍历:
<s:iterator value="#{'java':'lee','c++':'cee','php':'pee'}" id="score" status="sc">
   <tr 
    <s:if test="#sc.odd">
        style="background-color:#cccccc" </s:if>>
        <td><s:property value="key"/></td>
           <td><s:property value="value"/></td>
   </tr>
</s:iterator>  
generator:字符串生成集合
<s:generator  val=" ' java,c++,php ' " separator=","/>
subset生成子集:
<s:subset  source="{'java','c++','php'}" start="1"  count="2" />     取得c++,php
sort排序:  
<s:bean var="mycomparator" name="com.MyComparator"/>   //name="com.MyComparator"自定义类
<s:sort source="{'java','qqqc++','phpss','Ajx'}" comparator="#mycomparator" var="sortedList"/>
${pageScope.sortedList}                                //页面范围操作集合
<table border="1" width="300">
<s:iterator status="st" value="#attr.sortedList">      //attr属性对象
    <tr>
        <td><s:property/></td>
    </tr>
</s:iterator>
</table>  
public class MyComparator implements Comparator{
    public int compare(Object o1, Object o2) {
        return o1.toString().length()-o2.toString().length();
    }
}  

9.主题和模板:
   a.通过theme属性来指定主题,如<s:form../>        
   b.Struts模板目录是struts.ui.templateDir常量指定,默认值是template    
      select标签,指定主题为xx.html    /template/xhtml/xx.ftl
      ftl:FreeMarker木板技术 
      vm:Velocity      
  自定义模板时:需要创建包template.com   //然后存放对应的select.ftl和theme.properties作为主题文件,主题名为com

10.类型转换问题:
   a.输入数据到服务器必须进行类型转换,输出到页面时不必进行类型转换










posted on 2018-03-06 18:03  xiaojiayu0011  阅读(277)  评论(0)    收藏  举报

导航