struts2学习(word文档备注不能正常显示,如有错误,忘不吝指正)

来源:互联网 发布:最准确的平码公式算法 编辑:程序博客网 时间:2024/05/09 13:18

 

1.        与struts1类似的还有webwork

2.        此文档中的action如果感觉语义理解不畅,就可以理解为action标签里面的name属性对应的类即可。

3.        Struts2主要是webwork技术,名字叫struts而已。与struts1区别相对比较大

4.        struts.xml不要直接拷贝到web-inf下的classes目录下面,考到项目下面src目录下,会自动编译到web-inf下的classes目录下。将要用到的struts包拷贝在web-inf下面的lib目录下,会自动的产生对应的webapp libraries目录。

5.        配置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>/*[f1] </url-pattern>

    </filter-mapping>

         上面的代码类似于servlet配置文件中的servlet和servlet-mapping标签

6.        Struts2的action配置中name属性值一般小写

7.        struts.xml文件内容解析:

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

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

    <package name="default" namespace="/"[f2] extends[f3] ="struts-default">

        <default-action-ref name="index" />

        <global-results>

            <result name="error">/error.jsp</result>

        </global-results>

        <global-exception-mappings>

            <exception-mapping exception="java.lang.Exception" result="error"/>

        </global-exception-mappings>

        <action name="index">

            <result type="redirectAction">

                <param name="actionName">HelloWorld</param>

                <param name="namespace">/example</param>

            </result>

        </action>

    </package>

    <include file="example.xml"/>

8.        struts2中访问的时候,路径名字后面的.action可以省略。

9.        struts.xml中有配置开发模式的常量:放置在package标签外面

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

devMode即开发模式   value=ture意思是激活开发模式,改动action的属性name值等的时候可以不用手动重新部署,系统会自动重新部署

10.    给struts2-core-2.3.14.jar包添加源码的时候,右键属性-java SourceAttachment-External Folder-J:/尚学堂/S19-struts2教程/struts-2.3.14/src/core/src/main/java 确定即可

11.    给struts2-core-2.3.14.jar包添加javadoc文档,即api,右键属性-javadocLocation-javadoc URL -file:/J:/尚学堂/S19-struts2教程/struts-2.3.14/docs/struts2-core/apidocs/ 确定即可

12.    选中某个类,然后按F1,就可以在myeclipse新窗口中看到关于此类的API文档。当然前提是要给该类已经添加了javadoc文档

13.    在xml文档中键入“<”符号的时候,应该要可以给出提示才可,默认没有,原因是myeclipse根本不知道提示什么,它根本不知道这篇xml文档的语法、关键字是那些。http://struts.apache.org/dtds/struts-2.3.dtd文件头部的的这个定义该文档语法的位置,该位置为网络位置,每次去网上拿就很费力。可以如下解决:window-preferences-XML Catalog-Add:

Location:J:\尚学堂\S19-struts2教程\struts-2.3.14\lib\struts2-core-2.3.14\struts-2.3.dtd

Key type:URI

Key: http://struts.apache.org/dtds/struts-2.3.dtd

确定即可

一般打开配置文件用对应的打开方式打开即可出现提示,不需要如上配置

14.    Struts2运行机制,客户端在浏览器输入url地址,然后url地址的请求通过http协议发给tomcat,tomcat收到这个请求之后,tomcat看到端口后面的字符串即明白是哪个webapp,它就把这个webapp交给对应的程序去处理,读取该webapp的配置文件web.xml,发现里面有个filter配置:

<filter>

   <filter-name>struts2</filter-name>

   <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter[f4] </filter-class>

</filter>

<filter-mapping>

   <filter-name>struts2</filter-name>

   <url-pattern>/*[f5] </url-pattern>

</filter-mapping>

struts2配置文件中的action是个class,这个对象一般来讲,每次访问就new一个;struts1每次访问很可能用的是同一个。

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

15.    Struts2解决请求和展现分开的问题。即客户端浏览器请求不直接对应于jsp页面(展现),而是通过struts2分开。要改变展现的时候可以很方便的在struts配置文件中搞定。

16.    Namespace决定了action的访问路径,默认为“”,可以接收所有路径的action

Namespace可以写为/,或者/xxx,或者/xxx/yyy,对应的action访问路径为/index.action,/xxx/index.action,或者/xxx/yyy/index.action.

Namespace最好也用模块来进行命名

namespace属性值如果不为空,则必须以“/”开头

17.    Java中的package作用就是给类打个包,避免重名的情况;struts2中作用类似,避免action重名。

18.    extends属性先写默认的“struts-default”,后面再解释

19.    namespace属性值和name属性值一般在开发的时候都用模块来命名。

20.    resutl标签中name属性如果是“success”,则可以不写,即默认就是success。

21.    namespace可以不写,等于namespace=“”,即上面的可以可以接收所有路径的action(前提是没有找到精确对应的action的时候,全都交个namespace为空的这个action去处理)。

具体来说就是在浏览器中输入/index.action,/xxx/index.action,或者/xxx/yyy/index.action都可以访问到index.action对应的页面(.action可以不写)

22.    复制粘贴改名下一个web项目,如果要正确部署到tomcat,就要右键-属性-MyEclipse-web-Context Root-Web Context-root-将其中的值改成对应的项目的名字-确定即可

23.    具体视图的返回可以由用户定义的Action来决定

具体的手段是根据返回的字符串找到对应的配置项,来决定视图的内容

具体Action的实现可以是一个普通的java类,里面有public String execut方法即可

或者实现Action接口[f6] 

不过最常用的的是从ActionSupport[f7] 继承,好处在于可以直接使用Struts2封装好的方法,重写不重写里面的excute方法都不重要,一般重写也是一样的实际开发一般都用这一种

24.    action标签后面可以有class属性,写的时候要写全类名(包名+类名)

25.    struts1离不开servlet环境,和具体的struts1环境绑定;struts2一个普通的java类就可以。

26.    action中不配class的时候,实际上默认的是xwork-core-2.3.14.jar——com.opensymphony[f8] .xwork2——ActionSupport.class类。该类中同样有execute方法,并实现了该方法,默认返回success。该类内部定义了静态常量SUCCESS,初始化为success。

public static final String SUCCESS = “success”;

27.    路径问题说明:如果没有对应的namespace,则交给tomcat处理。tomcat会根据web.xml文件中的如下配置去处理:

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

即转换到index.jsp页面去处理

28.    struts2中的路径问题是根据action的路径而不是jsp路径来确定,所以尽量不要使用相对路径。eg:namespace=“/path”首先访问/path/xxx.jsp,然后在xxx.jsp页面使用链接跳转到相对路径yyy.jsp(实际存储中xxx.jsp和yyy.jsp在同一目录下),按理说可以正确跳转,实际则不能正确跳转。点了上面所说的yyy.jsp链接,则浏览器地址栏会显示/path/yyy.jsp,故找不到正确的页面。

虽然可以用redirect方式解决,但redirect方式并非必要。

解决办法非常简单,统一使用绝对路径。(在jsp中用request.getContextRoot方式来拿到webapp的路径)

或者使用myeclipse经常用的,指定basePath

jsp“/”代表的是整个站点的根路径,即http//localhost:8080

29.    jsp页面中的路径解析:

<%

String path = request.getContextPath()[f9] ;

String basePath = request.getScheme()[f10] +"://"+request.getServerName()[f11] +":"+request.getServerPort()[f12] +path+"/";

%>

30.    要在jsp中表示绝对路径,即可以如下表示:

href =<%=basePath%>index.jsp

31.    除了上面的绝对路径,还可以在jsp内的html标签内的head标签内添加base标签,如下:意思即当前页面所以连接前面都会默认加上basehref属性值

<base href=”<%=basePath%>”/>

32.    Action执行的时候并不一定要执行execute方法

可以在配置文件中配置Action的时候用action标签内的method=属性值来指定执行哪个方法(不推荐)

也可以在url地址中动态指定(动态方法调用DMI)(推荐)直接在链接action后面加“!方法名即可

33.    Wildcard:通配符

34.    使用通配符(actionname属性带*method属性值和result标签内的值可以用{数字}来按顺序匹配),可以将配置量降到最低。不过,一定要遵守“约定优于配置”的原则

<action name="*_*" class="com.bjsxt.struts2.action.{1}[f13] Action" method="{2}">

      <result>/{1}_{2}_success.jsp</result>

      <!-- {0}_success.jsp -->

</action>

<action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">

      <result>/Student{1}_success.jsp</result>

</action>

35.    如果访问的时候可以匹配多个actionname属性值,则选择最精确的、最完整的优先。只要包含*符合的属于同一等级,哪个写在前面,就先调哪个

36.    action接收参数:一般用前两种

1.在action中对应的类中定义对应的属性,写好get、set方法。当new这个action对应的类的对象的时候,自动的赋值给这个类的属性,url中的参数和类的属性一一对应[f14] ,不需要原来那样自己还得转换String参数成别的类型,自动转换并对应赋值[f15] 。struts.xml文件中不需要多余配置,jsp中写链接的时候加上参数即可,或者form表单提交

2.可以在action中对应的类中定义对应的对象,另外一个包可以写关于该对象的类(域或者实体)的模型java类,传参数的时候可以传对象的属性[f16] ,当然action中对应的类关于该对象的setget方法[f17] 必须得写,不用new该对象,struts2会自动new该对象

3.如果传输参数的时候与对应域模型不匹配,比如注册会有密码确认等,可以再加一层dto层,数据传输对象层,该层里面的对象可以与传入的参数完全匹配,传入之后再调用域模型层的真正实体对象赋值即可。当然对应的action类中就要用dto层的对象,不是实体层对象

4.ModelDriven方法:action对应的类实现ModelDriven[f18] 接口,重写getModel()方法,返回要传入的对象,参数传递的时候不传use.name,而是name即可,类中有user对象。此方法中user必须自己new,后台不会自己new出来。上面的两个则不需要自己new,声明即可。private User user = new User()。

备注:第二种情况下form表单里面的input标签的name属性值可以是“对象.属性”,action会自动回自动new对象并且赋值。当然关于该对象的getset还是得有

37.    DomainMode域模型:即在项目或者问题域中真正存在的实体的概念。(可以参考数据库中的实体概念)

38.    struts.xml中可以加入常量:编码模式控制。

<constant name=”struts.i18n[f19] .encoding” value=”UTF-8” />

39.    struts2中配置文件中常量属性查询方法(其他的查询也类似)。打开如下目录文件(开发文档):J:/尚学堂/S19-struts2教程/struts-2.3.14/docs/docs/index.html,找到guides条目,Core Developers Guide >Configuration Files > struts.properties。常量名字以及值全在这个文档中。也可以在项目加载的jar包struts2-core-2.3.14.jar——org.apache.struts2——/org/apache/struts2/default.properties去查看。

40.    简单的数据校验:SimpleDataValiation

41.    action对应的类中没有request、response和servletContext等对象,不能通过跟这些个对象有关的方法向前台传送数据。struts2可以通过标签来解决此问题,在action中调用方法,增加内容,在jsp页面中用标签将其取出并展现。

42.    struts2中将属性称之为field,可以通过ActionSupport接口的addFieldError方法添加属性校验信息。参数第一个一般是属性名字符串,第二个是描述信息字符串。

43.    要用struts2标签的时候,必须在jsp页面头部(一般在page指令后面)加taglib指令:

<%@taglib uri=”/struts-tags[f20] ” prefix=”s” %>

44.    <s:fielderror[f21]  fieldName=”name[f22] ” theme=”simple[f23] ”/>

此种方法在浏览器上面显示的时候会显示在<ul>标签里面,如下:

 

<ur class=”errorMessage”>

      <li><span>name is error</span></li>

</ur>

45.    <s:debug></s:debug>直接写在jsp页面里,在浏览器页面上就会出现一个Debug连接,点击进去会出现Struts ValueStack Debug的详细内容

Value StackContents:object[f24] 、 Property Name、Property Value

Stack Context(又名Action Context: Key、  Value

46.    <s:property[f25]  value=”errors”/>

47.    Property Value中的如下值是一个map(key, value)

{name=[name iserror][f26] }

上面的mapkeynamevalue是只有一个元素的数组[name is error](虽然说是数组,其实内部的实现很有可能是一个集合,有[]就当做数组理解吧,更容易理解)

48.    <s:property value=”errors.name.[0][f27] ”/>

49.    actionErrors是action出问题的时候用的,fieldErrors是校验action中的属性时出问题用的,errors是两者的结合。

50.    <s:property value=”errors.name.[0]”/>:取debug中的第一部分

ActionContext.getContext().方法名:取debug中的第二部分

51.    debug中的第二部分在jsp页面访问的时候要如下格式调用:(value值前加#)

<s:propertyvalue=” #request.r1” />

也可以<%=request.getAttribute(“r1”) %>

<s:property value=” #attr[f28] .r1” />

52.    AccessWebElements:取得map类型的request, session, application,真实类型的HttpservletRequest, HttpservletSession, servletContext的引用(response一般都交给jsp去处理)

1.基本不用

package com.bjsxt.struts2.user.action;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction1 extends ActionSupport {

         private Map request;

         private Map session;

         private Map application;

         public LoginAction1() {

                   request = (Map)ActionContext.getContext()[f29] .get("request");

                   session = ActionContext.getContext().getSession();

                   application = ActionContext.getContext().getApplication();

         }

         public String execute() {

                   request.put("r1", "r1");

                   session.put("s1", "s1");

                   application.put("a1", "a1");

                   return SUCCESS;

         }

}

 

2.最常用的方法

package com.bjsxt.struts2.user.action;

import java.util.Map;

import org.apache.struts2.interceptor.ApplicationAware;

import org.apache.struts2.interceptor.RequestAware;

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction2 extends ActionSupport implementsRequestAware[f30] ,SessionAware, ApplicationAware {

         private Map<String, Object>[f31]  request;

         private Map<String, Object> session;

         private Map<String, Object> application;

         //DI dependency injection依赖注入

         //IoC inverse of control控制反转

         public String execute() {

                   request[f32] .put("r1", "r1");

                   session[f33] .put("s1", "s1");

                   application[f34] .put("a1", "a1");

                   return SUCCESS;

         }

         @Override

         public void setRequest(Map<String, Object> request)[f35]  {

                   this.request = request;

         }

         @Override

         public void setSession(Map<String, Object> session) {

                   this.session = session;

         }

         @Override

         public void setApplication(Map<String, Object> application) {

                   this.application = application;

         }

}

 

3.基本不用

package com.bjsxt.struts2.user.action;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction3 extends ActionSupport {

         private HttpServletRequest request;

         private HttpSession session;

         private ServletContext application;

         public LoginAction3() {

                   request = ServletActionContext.getRequest();

                   session = request.getSession();

                   application = session.getServletContext();

         }

         public String execute() {

                   request.setAttribute("r1", "r1");

                   session.setAttribute("s1", "s1");

                   application.setAttribute("a1", "a1");

                   return SUCCESS;

         }

}

 

4.基本不用

package com.bjsxt.struts2.user.action;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpSession;

import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction4 extends ActionSupport implements ServletRequestAware {

         private HttpServletRequest request;

         private HttpSession session;

         private ServletContext application;

         public String execute() {

                   request.setAttribute("r1", "r1");

                   session.setAttribute("s1", "s1");

                   application.setAttribute("a1", "a1");

                   return SUCCESS;

         }

         @Override

         public void setServletRequest(HttpServletRequest request) {

                   this.request = request;

                   this.session = request.getSession();

                   this.application = session.getServletContext();

         }

}

 

53.    onclick时间中可以直接写多个javascript语句代码

<iput type=”button” value=”submit1” onclick=”javascript: document.f.action=’login[f36] /login1’;  document.f.submit();

54.    IncledeModules:模块包含

<include[f37]  file=”XXX.xml”/>

多人协作同一个项目的时候,让每个人配置自己的struts.xml文件,防止冲突以及减少改动的不方便性。

55.    DefaultAction:

<default-action-ref[f38]  name="index" />

56.    result类型:

<result type=”dispatcher”>/r1.jsp[f39] </result>

其中的type不写的情况下默认为dispatcher,意思是运用服务器跳转到结果页面,也就是jspfroword到其他一个页面去。下面的1和3是forward(服务器端),2和4是redirect(客户端)。

有如下种类:

dispatcher  redirect[f40]  chain[f41]  redirectAction[f42]   freemarker httpheader[f43]  stream[f44]  velocity[f45]  xslt[f46]     plaintext[f47]    tiles[f48] 

57.    GlobalResult:加入有许多的action,它们都有一个共同的result。如果都配在每个action中都复制一行,冗余太多。可以提出来写在一个如下的标签中(放在package标签下):

<global-result><result></result></global-result>

如果另外一个包也想调用这个result,这可以更改一下packeage标签中的extends属性值,改为上一个packagename属性值即可。简单点说就是package继承。

extends的默认值struts-default指的是在struts2-core-2.3.14.jar/struts-default.xml文件里面的namestruts-defaultpackage

58.    DynamicResult:动态结果

在对应的action的类中可以另外定义个属性,当然也要有set、get方法。在重新的excute方法里面可以根据传入参数进行动态的指定上面定义的属性值。然后可以在struts.xml文件中result标签中用“$”调用该属性值。action类中定义的属性在valuestack中,也就是说在struts配置文件中$[f49] {xxx}可以访问valuestack中的名字为xxxProperty Name对应的Property Value

59.    ResultWithParams:

action对应的类的属性通过链接传入参数初始化,并保持在值栈中,在result标签的type属性中如果是redirect(客户端跳转)并且标签里面的内容要用到该参数,则可以向上面那样用“$”取出来在result内容中调用。

一次request只有一个值栈(value stack),forward(服务器端跳转)的过程这几个action共享同一个值栈;redirect是客户端跳转,就不是同一个值栈了,如果要传第一次请求的参数就要<result type=”redirect”>/user_success.jsp[f50] ?t[f51] =${type[f52] }</result>,但是如此debug值栈中会是空的,然而stackcontext中有个parameters属性,可以通过该属性拿出传入的参数。<s:property vlue=”#parameters.t”/>

60.    OGNL: Object Graph NavigationLanguage对象图导航语言

<ol>

<li>访问值栈中的action的普通属性:username = <s:property value="username[f53] "/> </li>

<li>访问值栈中对象[f54] 的普通属性(get set方法):<s:property value="user.age"/> | <s:propertyvalue="user['age']"/> | <s:propertyvalue="user[\"age\"]"/> | wrong: <%--<s:propertyvalue="user[age]"/>--%></li>

<li>访问值栈中对象的普通属性(getset方法): <s:property value="cat.friend.name[f55] "/></li>

<li>访问值栈中对象的普通方法:<s:propertyvalue="password.length()"/></li>

<li>访问值栈中对象的普通方法:<s:propertyvalue="cat.miaomiao()" /></li>

<li>访问值栈中action的普通方法:<s:propertyvalue="m()[f56] " /></li>

                   <hr />

<li>访问静态方法:<s:propertyvalue="@com.bjsxt.struts2.ognl.S[f57] @s()"/></li>

<li>访问静态属性:<s:propertyvalue="@com.bjsxt.struts2.ognl.S@STR[f58] "/></li>

<li>访问Math类的静态方法:<s:propertyvalue="@@[f59] max(2,3)"/></li>

                   <hr />

<li>访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/>[f60] </li>

<li>访问action类的方法:<s:property value="getText(‘string’)"[f61] /></li>

                   <hr />下面是访问集合(数组和list的访问方式一模一样)

<li>访问List:<s:propertyvalue="users"/></li>

<li>访问List中某个元素:<s:propertyvalue="users[1]"/></li>

<li>访问List中元素某个属性的集合:<s:propertyvalue="users.{[f62] age}"/></li>

<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> |<s:property value="users[0].age"/></li>

<li>访问Set:<s:propertyvalue="dogs"/></li>

<li>访问Set中某个元素:<s:propertyvalue="dogs[1][f63] "/></li>

<li>访问Map:<s:propertyvalue="dogMap"/></li>

<li>访问Map中某个元素:<s:propertyvalue="dogMap.dog101"/> | <s:propertyvalue="dogMap['dog101']"/> | <s:propertyvalue="dogMap[\"dog101\"]"/></li>

<li>访问Map中所有的key:<s:propertyvalue="dogMap.keys"/></li>

<li>访问Map中所有的value:<s:propertyvalue="dogMap.values"/></li>

<li>访问容器的大小:<s:propertyvalue="dogMap.size()"/> | <s:property value="users.size[f64] "/> </li>

                   <hr />

<li>投影(过滤):<s:property value="users.{?#[f65] this[f66] .age==1}[0]"/></li>

<li>投影:<s:propertyvalue="users.{^#[f67] this.age>1}.{age}"/></li>

<li>投影:<s:propertyvalue="users.{$#[f68] this.age>1}.{age}"/></li>

<li>投影:<s:propertyvalue="users.{$#this.age>1}.{age} ==null[f69] "/></li>

                   <hr />

<li>[]:<s:propertyvalue="[0][f70] .username[f71] "/></li>               

         </ol>

61.    Struts-Tags:通用标签、控制标签、UI标签、AJAX标签、S#%的区别(全部标签可以查询文档)(标签里面涉及到value属性的时候,它对应的值一般在双引号里面都是ognl表达式【具体是不是object要查文档,文档有极少部分也会写错,自己试验】,如果双引号里面再有单引号这才是字符串

62.    通用标签:

property:

set:

         默认为actionscope,会将值放入request和ActionContext中

         page、 request、 session、 application

bean:

include:

包含文件内容中含有中文的情况下容易出现问题,尽量少用,可以用jsp的两种包含方式

param:

debug:

63.    控制标签:

if  elseif  else:

iterator:

         collectionsmap enumeration iterator array

subset:截取子串<s:subset source=”myList” count=”13”start=”3”></s:subset>从第三个元素开始截取13个作为一个子集合。

64.    UI标签:(标签比较多,不好用,实际当中很少用,和javascript结合的也不是很好)

theme:simple  xhtml(默认)   css_xhtml  ajax一般要设置主题设置成simp即可

其默认值可以在struts2-core-2.3.14.jar/org/apache/struts2/default.properties文件中找到里面有默认theme和模板地址等)。theme作用于struts标签的展示。<s:form><s:input>等。主题换了,标签最后在浏览器上的展现也会换掉,可以查看页面源代码。

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

1.      对于<s:fielderror>在浏览器页面上的显示。我们可以用css控制其展现,出现圆点就是因为前面<li>标签格式等引起的,控制一下即可

2.      也可以从value stack中取值,然后自己控制展现。

3.      Struts2控制标签在浏览器上展现是的模板在struts2-core-2.3.14.jar\org.apache.struts2\ template.simple等包中。里面的文件所采用的的语言是freemaker。可以在src目录中建立同样的目录(template.simple包等),同样的文件覆盖jar包里面的模板,因为默认先搜src目录下

4.      直接在src目录下定义template包,然后在里面定义自己的主题(可以全部复制simple然后该其中小部分),调用的时候theme的值就可以写自己的主题名。

                  

65.    AJAX标签:

补充:

66.    $#%的区别

$用于i18n和struts配置文件(调用值栈内容)

#取得ActionContext的值

%原本的文本属性解析为ognl,对于本来就是ognl的属性不起作用

         参考<s:property和<s:include

67.    tag.jsp中部分代码

<ol>

                   <li>property: <s:propertyvalue="username"[f72] /> </li>

                   <li>property 取值为字符串: <s:property value="'username'"[f73] /> </li>

                   <li>property 设定默认值: <s:property value="admin" default="管理员[f74] "/> </li>

                   <li>property 设定HTML: <s:property value="'<hr/>'"escape="false"[f75] /> </li>

                   <hr />

                   <li>set 设定adminName值(默认为request 和 ActionContext): <s:set var="adminName" value="username" /></li>

                  

                   <li>set 从request[f76] 取值: <s:property value="#request.adminName" /></li>

                   <li>set 从ActionContext取值: <s:property value="#adminName" /></li>

                  

                   <%--<li>set 设定范围: <s:set name="adminPassword" value="password" scope="page"/></li>

                   <li>set 从相应范围取值: <%=pageContext[f77] .getAttribute("adminPassword") %></li>

                   --%>

                   <li>set 设定var,范围为ActionContext: <s:set var="adminPassword" value="password" scope="session[f78] "/></li>

                   <li>set 使用#取值: <s:property value="#adminPassword"/> </li>

                   <li>set[f79]  从相应范围取值: <s:property value="#session.adminPassword"/> </li>

                  

                   <hr />

                  

                   <%--<li>push:<s:set name="myDog" value="new com.bjsxt.struts2.ognl.Dog('oudy')"></s:set></li>

                  <li>

                   push:<s:push value="#myDog">

                            <s:property value="name"/>

                   </s:push>

                   </li>

                   <li>push: <s:property value="name"/></li>

                   --%>

                  

                   <hr />

                   <li>bean[f80]  定义bean,并使用param来设定新的属性值:

                            <s:bean name="com.bjsxt.struts2.tags.Dog" >

                                     <s:paramname="name"[f81]  value="'pp'"[f82] ></s:param>

                                    <s:property value="name"/>[f83] 

                                    

                            </s:bean>

                           

                           

                   </li>

                  

                   <li>bean 查看debug情况:

                            <s:bean name="com.bjsxt.struts2.tags.Dog"var[f84] ="myDog">

                                     <s:param name="name" value="'oudy'"></s:param>

                            </s:bean>

                            拿出值:

                            <s:property value="#myDog.name"/>

                           

                   </li>

                   <hr />

                  

                   <li>include _include1.html 包含静态英文文件

                   <s:include[f85]  value="/_include1.html"></s:include>

                   </li>

                  

                   <li>include _include2.html 包含静态中文文件

                   <s:include value="/_include2.html"></s:include>

                   </li>

                  

                   <li>include _include1.html 包含静态英文文件,说明%用法

                   <s:set var="incPage"value[f86] ="%{'/_include1.html'}" />

                   <s:include value="%{[f87] #incPage}"></s:include>

                   </li>

                  

                  

                   <hr />

                  

                   <li>if elseif else:

                   age = <s:property value="#parameters.age[f88] [0]" /> <br />

                   <s:set var="age" value="#parameters.age[0]" />[f89] 

                   <s:if test="#age < 0">wrong age!</s:if>

                   <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>

                   <s:else>yeah!</s:else><br />

                  

                   <s:if test="#parameters.aaa == null">null</s:if>

                   </li>

                  

                   <hr />

                  

                   <li>遍历集合:<br />

                   <s:iterator value="{1, 2, 3}[f90] " >

                            <s:property/>[f91]  |

                   </s:iterator>

                   </li>

                   <li>自定义变量:<br />

                   <s:iterator value="{'aaa', 'bbb', 'ccc'}"var[f92] ="x">

                            <s:property value="#x.toUpperCase()"/> |

                   </s:iterator>

                   </li>

                   <li>使用status:<br />

                   <s:iterator value="{'aaa', 'bbb', 'ccc'}"status[f93] ="status">

                            <s:property/> |

                            遍历过的元素总数:<s:property value="#status.count"/> |

                            遍历过的元素索引:<s:property value="#status.index"/> |

                            当前是偶数[f94] ?:<s:property value="#status.even"/> |

                            当前是奇数?:<s:property value="#status.odd"/> |

                            是第一个元素吗?:<s:property value="#status.first"/> |

                            是最后一个元素吗?:<s:property value="#status.last"/>

                            <br />

                   </s:iterator>

                  

                   </li>

                  

                   <li>

                   <s:iterator value="#[f95] {1:'a', 2:'b', 3:'c'}" >

                            <s:propertyvalue="key"[f96] /> | <s:property value="value"/> <br />

                   </s:iterator>

                   </li>

                  

                   <li>

                   <s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x"[f97] >

                            <s:property value="#x.key"/> | <s:property value="#x.value"/> <br />

                   </s:iterator>

                   </li>

                  

                   <li>

                  

                   <s:fielderror fieldName="fielderror.test" theme="simple[f98] "></s:fielderror>

                  

                   </li>

         </ol>

        

68.    myeclipse中创建类的时候写的包名可以用“.”分开,代表包的包含。但是在new包的时候要一层一层建。具体情况可以在navigator视图中看见。

69.    开发流程:先建立简单的界面(建立并命名所以页面,至于页面内容可以简陋一些),然后配置好strut.xml(建立简单的action),部署起来,浏览器访问对应页面,测试一下跳转流程对不对;然后建立数据库;接着对应数据库表以及字段建立model层的实体;接着写service(不牵扯hibernatespring情况下)层,给出一些操作数据库的方法(可以先写全部的空方法,需要返回值的时候写null等几款,写完后再写具体实现,清晰明了);最后写具体的action方法实现(连接action层和service,实现真正的数据交互[f99] )和jsp页面调用展现

 

70.    web project中要添加自己定义的类,直接拷贝到web-inf目录下的lib目录下即可,myeclipse会自动添加到web app libraries目录下

71.    在实现层中可以给出多个方便接口,比如删除产品,可以写两个接口:delete(产品对象);deletebyId(产品id)。为了简化代码量,我们可以只在一个方法里面写实现,在另外一个方面里面调用前一个已经写好实现的方法

72.    preparedStatement一次编译,多次调用;安全性好,防止sql注入。

73.    搭框架的时候如果方法有返回值,可以先返回null(当然返回值要是对象string或者list等,int就不可以返回null),具体实现的时候再删除即可。

74.    jstl(jsp标准标签库)和struts标签[f100] (if,iterator,debug等)可以完成jsp页面从后面的java文件中的内容拿去。

75.    刚开始写的项目jsp页面中有跟数据库交互的代码,哪是因为没有分层。分层之后就可以在jsp中不在写跟数据库交互的代码[f101] 。

当然在jsp页面中数据的展示还是要用到java代码,比如说循环输出list的值等,然后现在出现的jstl和struts标签可以让我们不写这些循环等的java代码,直接用简单的标签代替。所以jstlstruts标签的作用是简化了我们在jsp中的java代码(脚本编制元素跟完善一些)的书写。另外struts标签还自带了一些html格式(即拿出内容后以一定的格式显示在浏览器上)

76.    jstlstruts标签的作用:避免在 JSP页面中使用脚本编制元素[f102] 

脚本编制元素的书写格式换成另外一种更容易理解、书写、简单等标签书写格式,但是后台的处理和者结果是一样的。最大的好处可能就是使只负责JSP编写不管其他内容编写的作者减少对编制脚本元素的学习。

77.    分层和方法调用然后返回对应值解决了:在jsp页面的直接与数据库交互。

jstlstruts标签解决了:美工可以学习更简单的标签语言,不用学习较复杂的脚本编制元素

78.    以前总是对前台页面(浏览器上面的html文件)怎么拿到数据(java文件处理的数据)百思不得其解,其实在自己学了servlet和jsp之后就应该明白,可是不幸,直到现在才明白,哪是因为自己不思考,不总结。

servlet本身就是java文件,当然可以和前面的java文件处理的数据交互,然后调用servlet中对应的方法以将数据成html的格式发送给客户端浏览器,客户端浏览器解析发过来的html格式的文件,正确显示在浏览器上。

由于servlet的里面写要发送客户端浏览器的html内容非常麻烦,此时jsp就好像天使一样出现了,在jsp中我们不必再写调用servlet的方法输出html格式的内容,直接像写html格式文件(易于掌握、书写)一样书写jsp即可(后缀为jsp,加上对应的头部文件),这样jsp编译之后就会转换成调用servlet中的java方法写成对应的输出方法,至于要在jsp像servlet中增加别的方法,变量等,可以通过jsp的标签实现。

jsp中的内置对象当然也对应于servlet中转换成对应方法里面的对象。具体可以看jsp转换成servlet的源码

79.    在目前不牵扯hibernate和spring的情况下,service层调用(import…)封装的DB层和model层并提供方法给action层调用。action层也要调用service层(具体对象到时候可以用spring注入)和model层。

80.    action的自动给属性值赋值使得必须注意不要忘了属性的set、get方法的建立(action里面的所有属性不一定都要有get、set方法)

81.    有了struts标签,在jsp中用都可以不用request对象的方法拿参,直接用标签可以取值栈和stack context中的内容(里面有传的参数)

82.    更新界面可能不需要显示和更改id,但是如果要根据传入id才能更新,就可以给一个hidden的input标签。

83.    如果要写一个可以产生异常的方法,可以在方法名的括号后面加throws XXXException,然后在方法体重throw(XXXException对象)即可。

84.    声明式的异常处理:只要有异常了,可以尽管往外抛,到最后struts会给出一个统一的接口,在特定的页面可以去处理它。

85.    在service层的方法里面声明异常并抛出异常;action也只是抛出异常,不去处理异常(ActionSupport类的excute方法也是只抛出异常);处理时在struts.xml配置文件中去处理的。在action标签中加如下代码

<exception-mapping result=”error” exception=”java.sql.SQLException[f103] ”/>

<result name=”error”>/error.jsp</result>

上面的代码是对应于每一个action来处理异常,也可以写一个对应所以action的异常处理方式,这段代码可以放在另外一个package标签中,其他的package从这个继承即可。如果出现了action中出现了异常,首先会在对应的package中去找有没有对应的异常处理,如果发现没有,则去父类的package中找,找到之后拿到result结果,然后去自己action中找,自己action中没有对应result,则继续在父类package中找对应result,然后跳转到对应页面()

<global-results[f104] >

      <result name=”error” >/admin/error.jsp</result>

</global-results>

<global-exception-mappings>

      <exception-mapping exception="java.lang.Exception" result="error"/>

</global-exception-mappings>

86.    过滤器StrutsPrepareAndExecuteFilter,调用action中特定方法,比如说excute,流程为过滤器-excute方法;可以在这个过程中间加一个拦截器,这样流程就成了过滤器-拦截器-excute方法

87.    声明式的异常处理,就相当于加了一个Exception拦截器。

88.    struts2中异常处理由拦截器实现(观察struts-default.xml)。实际上struts2的大多数功能都由拦截器实现。

89.    package默认父类struts-default.xml中定义了许多默认拦截器,action被执行之前会经过很多拦截器处理

90.    I18N:程序国际化。

要建properties格式文件,并且名字有要求。eg:app_en_US.properties

ResourceBudle[f105]  res = ResourceBundle.getBundle(“app[f106] ”,Locale.US[f107] );

res.getString(“key”)[f108] ;

91.    struts的资源文件级别(i18n国际化问题)

action:

资源文件和action文件放在同一个目录下,资源文件名前半部分和action名字相同且必须得加Action以及其他后缀一起组成文件名字。jsp页面用<s:property value="getText('login.username') "/>调用资源文件中的内容。浏览器中根据自己的语言设置选择对应的资源文件内容。action级别的国际化资源只有这一个action可以用。

package:

包级别的国际化资源也很少用,资源文件名字前缀必须是package。该资源当前包里面的所有action都可以用。

app:一般就只用这个级别,在struts配置文件中要增加一个常量配置

这个最常用,放在src目录下面。struts1只能用这种。全局级别的资源文件名字前缀随便取,后缀还是的按规范来。这种情况下要在struts.xml中配置一下,要不找不到对应文件,Srtuts.xml文件中的配置不清楚的情况下都可以去strutsjar包中struts2包下面的default.properties文件中查看<constantname=”struts.custom.i18n.resources” value=”自己给properties加的前缀”></constant>

92.    <s:property value="getText('login.username')[f109] "/>

<s:text name=”login.username”>

         <s:param value=”usename”></s:param>

</s:text>[f110] 

参数的数目对应的资源文件中的占位符从数字0开始

93.    经查看在jsp中的struts标签被转换为servlet之后全都是成员方法,不是_jspService方法里面的代码块(当然_jspService方法里面还是有调用)。

经查看jsp中的ognl(也就是struts很多标签的属性值value的值)在转换成的servlet里面还是原样,没有变化。struts的框架对其做了更加深入的处理

94.    动态语言切换,链接传参数request_locale=en_US,或者zh_CN等,并且action要从ActionSupport继承。当然要在有国际化资源文件的前提下。值栈中的的local=en_US,stack context中的session值{WW_TRANS_I18N_LOCAL=en_US}。只要传request_local,并且action从ActionSupport继承,struts会自动处理值栈和stackcontext中的对应值。原理就是往session里面放了东西,任何的页面取local的时候,就从session中取出来,取完了,就根据这个值显示页面。

95.    struts拦截器和源码解析:

A里面循环调用所有拦截器B,在执行每一个拦截器B的时候又调用A

下面这个图的invoke()调用画的有点不对,第二个intercept调用在1.2.1.1.1invoke调用里面,不是下面,这样才能在执行完action之后再调用一次intercept

官方架构图:doc文档里面的guide里面的架构guide。actionMapper访问jar包里面的静态资源。

96.    写自己的intercept,实现intercept接口,并实现里面的方法,最主要的方法是public String interceptActionInvocationinvocation{}方法。该方法里面最主要的的是String s =invocation.invoke();return s;的调用

然后在struts.xml中的配置:在package标签中添加如下代码

<interceptors>

     <interceptor name=”my” class=”com.scut.flf.MyInterceptor”></interceptor>

<interceptors>

<action name=”test” class=”com.scut.flf.TestAction”>

     <result>/test.jsp</result>

     <interceptor-ref[f111]  name=”my[f112] ”></interceptor-ref>

     <interceptor-ref name=”defaultStack[f113] ”></interceptor-ref>

<action>

97.    拦截器体现了一种编程的理念:AOP,面向切面编程。

98.    acegi现在更名为springsecurity(权限检查,方法里面,url里面)

99.    使用token(令牌)拦截器控制重复提交(很少用,可以用其他方法替代)。

表单和提交在同一个页面的情况下,使用token容易出问题。

出现情况:客户端响应慢,用户可能重复按提交按钮,使得数据库中多出好多重复数据。

解决方法:表单提交方式写成post;给jsp页面添加标签<s:token></s:token>[f114] 

这个对于的拦截器没有配置在默认的intercept中,所以在struts.xml文件中要自己配置一下,写在默认拦截器后面,默认拦截器先要处理form表单提交过来的参数

<interceptor-refname=”token[f115] ”></interceptor-ref>

         同时要设置如果重复提交要对应的result,该resultname=“invalid.token”

100.  重复提交也可以使用redirect解决,具体不是很清楚。

101.  类型转换:struts拦截器实现的,有一个专门的intercept。转换的意思是把参数转换成action里面需要的类型。一般会默认转换。

102.  http传参数的时候用于是Stirng类型。

103.  struts2里面的类型转换中的date默认参数格式2013-08-08 12:32:15[f116] ;

104.  <s:date format=”yyyy/MM/dd”/>负责date格式的页面转换显示。其中format的值可以自己改动。

105.  传参为map时,书写格式如下:

user[‘a[f117] ’]=usera[f118] &user[‘b’]=userb&……

106.  基本的对象,集合,map等从前面传参数给action,拦截器都可以很好的处理。如果传的是一些特殊的对象,没有set方法,或者别的其他原因,要默认赋值就比较麻烦了。

107. 可以自己写类型转换处理类。继承DefaultTypeConverter类,重写public Object covertValue(Objectvalue, Class toType) { }

写完还得注册(三种注册方式):

         1.局部:注册给action,注册文件和用到这个处理器的action放在一个包里。名字格式为XXXAction[f119] -conversion.properties。内容为:p[f120] =com.scut.flf.MyPointConverter

         2.全局:放在src目录下,名字固定为:xwork-conversion.properties。注意对应上面的p要改成java.awt.Point。一般都用全局注册。

         3.Annotation(注解,hibernate和spring中会着重讲注解)

         也可以继承StrutsTypeConverter[f121] ,重写其中的converValue方法和converFromString方法,当然也要注册(不在深究,用的时候再说)

         如果用到非常麻烦的映射转换(传参)request.setAttribute();或者session

         处理参数类似p=5,8这样的传入方式,对应实际p为Point对象。

108.  CRUD:增删改查  create  retrieve update delete

109.  struts拦截器模拟:两个类A和B(接口),A中循环控制次数,调用实现B接口具体拦截器的类中的方法处理拦截(过滤),然后回调A中调用B的方法,同时循环变量增加。A中利用循环变量控制循环次数。A调用B的时候传递的是this即当前A对象,这样才可以把循环控制变量当前值传递下去

110.  jsp2.0中el表达式代替了<%= %>脚本表达式,jstl可以说是jsp3.0,jsp页面数据的获取还可以通过struts标签,<s:property>等。


 [f1]也可以写成*.action,但是不建议

 [f2]Namespace的值跟浏览器访问路径有关

 [f3]包的继承,继承是的值是被继承package的name属性值。

默认值是struts-default,这个package在如下的文件里面  

struts2-core-2.3.14.jar/struts-default.xml

 [f4]处理的时候首先看struts.xml文件中的namespace,发现是个“/”,接下来就去查在这个命名空间下有没有对应的action的name属性值,如果有就去找对应class属性中的的类,然后看execute方法的返回值,根据返回值找到对应的result标签,标签中对应的值,即对应页面,处理请求,并返回结果给浏览器

 [f5]过滤所有的url地址,交给上面的filter-class处理

 [f6]该类中有常量SUCCESS,继承的子类也可以返回该常量

 [f7]该类继承了Action接口

 [f8]公司名,symphony交响乐

 [f9]得到项目名字:/XXX

 [f10]协议模式http

 [f11]ip地址,localhost

 [f12]端口:8080

 [f13]应为是类名,所以注意第一个*匹配的字符串的首字母大写

 [f14]其实本质是调用与set、get方法的后半部分对应的set、get方法来赋值,所以属性可以不与参数对应,但是方法后半部分必须和参数对应

 [f15]以前写jsp中参数要自己转换,现在不需要转换,struts2自己就转换好了,直接当类中的属性是已初始化好的拿来用即可

 [f16]地址栏参数部分可以写:对象名.属性=xxx&对象名.属性=yyy。eg:user.name=aaa&user.age=18

 [f17]eg:对象是user,则先setUser()。setUser()里面在调用对应该User对象类中的set方法,设置对象的属性

 [f18]注意用泛型,要不还得强制类型转换,里面只有一个方法getModel()

public class UserAction extends ActionSupport implements ModelDriven<User>{

private User user= new User();

public String add() { return SUCCESS}

public User getMode() {return user}

}

 [f19]internationalization

 [f20]指定标签库的位置。和struts2-core-2.3.14.jar—/META-INF/struts-tags.tld这个文件里面的uri标签里面的内容一致。

 [f21]将action(action对应的类)中用addFieldError加进去的值取出来

 [f22]和addFieldError中第一个参数值一样

 [f23]可以给任何的用来展现的标签自己定义一个主题,在这个主题里面组织一系列展现

xhtml是默认的主题,比较简单的主题

 [f24]类名,一般是action。首先将关于该类的属性加入进来,还有其他属性。

 [f25]专门取Value StackContents和Stack Context的属性;

Value Stack Contents里面的属性值的时候,直接在该标签的value属性值中加入Value Stack Contents里面的Property Name即可;(大括号里面的是map,可以直接拿出map,接着可以用map方法取出对应key的value)

 [f26]要取出这个数组字符串可以如下

<s:property [f26] value=”errors.name”/>

要取出数组中的元素name is error,可以如下

<s:property [f26] value=”errors.name.[0]”/>

 [f27]像这样的表达式就是OGNL表达式

 [f28]挨着排搜applicationrequestsession,那个对应的value中有r1属性,就显示哪个

 [f29]可以得到ActionContext(即<s:debug>标签在浏览器端打开后里面的StackContext,也是当前Action执行的上下文)

 

context对应jsp中的application

 [f30]得知,知道,了解

知道request的这样一个接口

 [f31]用了泛型之后就没那么多警告了

 [f32]一般不用,action类中的属性值一般就在valuestack(debug第一部分),而vakuestack一般又属于request。属性即request

 [f33]这个最常用

 [f34]一般也不用,要放全局的数据可以放数据库中或者自己定义一个类即可解决

 [f35]调用该方法用参数初始化该类中的request对象。谁调用谁就初始化了这个request对象。所谓的依赖注入,别人调用我这方法就注入这个对象。

成员变量属性request依赖于struts2(容器)外界环境把相关的值注入给我。

控制反转:即本来自己控制自己属性的值,现在给容器控制这个类的属性。(spring中大量使用控制反转)

 [f36]跟namespace有关

 [f37]可以将另外的一个xml文件当做struts.xml包含在struts.xml文件中

 [f38]在别人访问这个namespace的时候,如果找不到对应的action,则根据此标签去找name为“index”的ation。注意要有nameindexaction;命名空间后面不跟action或者错误的action都会访问这个默认的nameindexaction

只是简单转发,不处理和数据库的业务逻辑(不执行对应的action),才可以用default-action-ref标签

 [f39]如果里面是action的话注意“/”的加与不加

 [f40]客户端跳转

 [f41]forward到另外一个action  服务器端的跳转

 [f42]客户端   跳转到另外一个aciton  1213(服务器端跳转是1231)

 [f43]发一个http的头信息过去

 [f44]下载

 [f45]和freemarke非常类似的一个模板框架

 [f46]和xml相关的修饰的xml语言

 [f47]显示页面源码,即各种标签的源文件

 [f48]把页面分成几块,每块的内容都可以动态指定

 [f49]用来从valuestack中取值给struts配置文件中用

不是jsp-el表达式,是专门用在struts配置文件里面的ognl表达式。

任何一个action对应的类的属性都会放在value stack(值栈)中

 [f50]在此页面调用debug,值栈中会是空的,因为redirect的时候没有对应的action的类

可以这样理解,本来访问的时候action是有一个对应的类的,然后redirect之后就相当于直接请求该jsp了,不是通过action调用jsp

 [f51]重命名为t

 [f52]传的参数

 [f53]这个部分内容表示的就是ognl表达式

 [f54]传参数的时候要传对象的属性(即对象.属性);或者在action中声明属性的时候直接new出来。同时domain model中要有参数为空的构造方法。如果不这样做,在值栈中的user对象就property value值就是null

 [f55]action中有一个cat对象属性,cat类中有一个dog对象属性,名字叫friend。dog类中有name属性。当然和上面一样也要传参cat.friend.name=XXX,这样值栈中才会有对应值。

 [f56]value值可以是方法

 [f57]@后面加类名,

 [f58]@后面加属性或者方法,要访问静态方法,要在struts.xml文件中配置常量:<constant name=”struts.ognl.allowStaticMethodAccess”value=””true></constant>

 [f59]两个@@只能访问Math类的静态方法,其他类管不了

 [f60]会在浏览器页面上显示新new出来对象的toString方法的返回值

 [f61]value属性值直接写action或其父类的方法名即可

 [f62]users中的每个元素的age属性组合在一起,大括号在ognl中可以代表一个集合

 [f63]set里面没顺序,所以按下标取不到

 [f64]后面不加括号也可以访问。

 [f65]只有?#、^#、$#这三种

 [f66]当给users做过滤的时候,会把users里面的每个对象拿出来,拿到那个对象,this就指那个对象。

大括号里面是个集合,因为age=1的use对象或许不止一个。后面的方括号代表取集合中的第几个。

 [f67]符合后面条件的集合中的开头的第一个对象。

 [f68]符合后面条件的集合中的最后一个对象

 [f69]判断是否为空,也可以用size判断

 [f70]用中括号去访问里面的元素,[0]代表的是值栈中的从0位置(栈顶)开始到栈底去找

值栈中3个列:对象、属性名、属性值

在值栈中,刚刚正在访问的action对象在栈顶(即在debug中的值栈的最上面)

 [f71]如果值栈中有2个action,前面是[0]即从栈顶开始找,如果再第一个action中没有找到,还会去第二个action中去找。什么时候会有2个action在值栈中?<s:bean>标签且debug在其中时或服务器端跳转就会把用到的action挨个压入到栈中。action的属性type=chain即可,最后的action在栈顶。

 [f72]value的值是一个object(ognl表达式,可以查Struts2文档得知),所以struts2会把username解析为一个ognl表达式,这样的话就会去值栈中取username的值

 [f73]双引号中加单引号里面的内容就当做一个字符串传了进去,浏览器页面显示字符串username而已

 [f74]没有admin这个属性,可以通过default设置一个默认值。如果有就取,如果没有就取默认值

 [f75]不设置默认就是true,会将字符串原封不动的显示在浏览器页面上;如果是false则会将前面字符串解析为html标签,显示一条横线。

 [f76]有时候发现stackcontext中request中没有对应值,可以去一下看看,能去出来就代表有,只是还没放进去(或者debug的时候早于放进去的时候)而已。

 [f77]jsp的内置对象,具体参见《jsp&servlet学习》文档

 [f78]会在stack context中放入namesessionvalue中,stack context中不会出现nameadminPassword的行,如果不加scope=”session”stack context中则会出现那么为adminPassword的行

 [f79]该标签一般是名字比较长,又要多次调用,则可以用set标签给其换个名字,调用的时候可以用标签写少点

当然也可以将用户名,密码写入session等

 [f80]跟jsp:usebean类似。开始的时候将该类放在值栈顶部,该标签结束的时候从栈顶去掉

 [f81]第二个name是Dog类中的属性

 [f82]要给Dog类中name属性赋值字符串就要加双引号单引号,要不加单引号就会当做ognl表达式处理

 [f83]<s:bean>标签里面访问时,可以看到值栈中会多出一个类;在该标签外面时值栈中就不会多出该类,并且不能被访问到。可以通过增加var属性将其放在stack context中,供其后续访问

 [f84]不定义变量就在debug中stackcontext中找不到,但是可以出现在值栈中,值栈中就会多一个对象

 [f85]尽量少用,包含的文件里面包含中文字符的时候容易出问题

jsp中有两种包含方式:

<%@inclue>静态包含

<jsp:include>动态包含

 [f86]set里面的value值也应该是ognl表达式,当然也可以加%{},如果本来就是ognl表达式,加了%{},系统会将其自动忽略。参见下一条备注

 [f87]%{}意思是把大括号里面的内容不要当成字符串解析,应该当成ognl解析

 [f88]浏览器地址栏中传入age参数,在stactcontext中可以发现parameters中出现age=……,如果传入2个age参数,parameters中还是值有一个表示,不过其代表的是俩个参数连在一起的字符串。可以通过输出parameters确认。

parameters.age是一个数组

 [f89]value值简化为age,调用的时候就可以用#age即可

 [f90]ognl表达式中大括号代表一个集合,默认好像转换成list

 [f91]挨个拿出里面的元素

 [f92]相当于for循环里面定义了临时变量,取的时候每循环一次就把值放在该X中

 [f93]记录每次循环到当前的状态是什么

 [f94]指的是下标值,不是实际值

 [f95]定义map的时候要加#

 [f96]如果没有value=“key”,则<s:property/>代表的是打印出当前循环的iterator对象

 [f97]此处X代表的是map的一个条目(一个键值对)

 [f98]按理说把theme设置为simple,就会吧其他的格式什么的去掉,实际中不是如此

 [f99]意思就是浏览器页面增加、删除等可以操作到数据库的数据增加、删除

 [f100]这些标签取值一般都与valuestack和stack context有关

 [f101]http请求页面时,如果需要参数,则通过request对象取得对应参数,然后jsp页面中调用相应层的对应方法,拿到return,然后循环输出、或者判断等。

总结:在jsp页面中不用通过和数据库的交互取值,而是调用对应层的方法拿到数据。(至于对应层是怎么实现的,则跟其他层息息相关)

 [f102]脚本编制元素指的是:scriptlet、表达式和声明

 [f103]出现此异常的时候,result等于error,然后跳转到下面的result等于error对应的页面

 [f104]必须写在global-exception-mapping标签前面

 [f105]如果用myeclipse propertieseditor格式打开并且在properties界面用add按钮,则可以输入中文。source界面会自动转换为本地化的ackii码。

在打开方式不对的情况下,输入中文之后可以用命令行下面用项目路径下的src目录下调用C:\jdk1.5\bin\native2ascII要转换的在src目录下的文件名 转换成的文件名

 [f106]这个名字必须和properties文件名前半部分一样。

 [f107]静态变量,对应properties文件名后面部分

注意静态变量CHINA

 [f108]可以拿到properties文件中对应key的值

 [f109]value的属性值总体来说是一个ognl表达式

ognl表达式张调用action或者其父类的方法可以直接写方法名

property里面直接调方法,只可以调用action中的方法,其他的调用要加@符号,具体参见ognl教程

 [f110]s:text也可以取国际化内容,并且可以传参数。

此处参数可以使资源文件中的内容通过占位符{数字}动态改变。可以实现比如说:欢迎您:XXX

关于参数的内容,如果用value则就是ognl表达式,或者也可以加在开始于结束标签直接,则是一个字符串

 [f111]此标签也可以放在别的地方。对应拦截范围不同。

此处这个标签只对应nametestaction

 [f112]自己的intercept标签写在默认的前面,会覆盖默认的intercept,所以后面要加上默认的intercept。

 [f113]默认的intercept标签,

 [f114]在浏览器中查看源代码则会多出hidden的input标签,并且value的值随着刷新而改变。

访问对应页面的时候,首先在服务器端的session里面生成一个随机数,再把这个随机数写到form里,提交的时候这个随机数就会带到服务器,提交之后session中的随机数就会清楚掉,下一次要提交,发现里面随机数没了,就不允许再次提交。

 [f115]这个拦截器struts2已经定义好了,不用我们自己定义

 [f116]这一部分可以省略

 [f117]key

 [f118]值

 [f119]和对应action名字一样

 [f120]对应action的属性名,即要处理的参数对应的属性名。

这句话的意思是遇到p不能转换的时候(比如没对应set方法或者其他情况)交给后面的转换器去转换

 [f121]继承了DefaultTypeConverter

0 0