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标签,如下:意思即当前页面所以连接前面都会默认加上base的href属性值
<base href=”<%=basePath%>”/>
32. Action执行的时候并不一定要执行execute方法
可以在配置文件中配置Action的时候用action标签内的method=属性值来指定执行哪个方法(不推荐)
也可以在url地址中动态指定(动态方法调用DMI)(推荐)直接在链接action后面加“!方法名”即可
33. Wildcard:通配符
34. 使用通配符(action中name属性带*,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. 如果访问的时候可以匹配多个action的name属性值,则选择最精确的、最完整的优先。只要包含*符合的属于同一等级,哪个写在前面,就先调哪个
36. action接收参数:一般用前两种
1.在action中对应的类中定义对应的属性,写好get、set方法。当new这个action对应的类的对象的时候,自动的赋值给这个类的属性,url中的参数和类的属性一一对应[f14] ,不需要原来那样自己还得转换String参数成别的类型,自动转换并对应赋值[f15] 。struts.xml文件中不需要多余配置,jsp中写链接的时候加上参数即可,或者form表单提交。
2.可以在action中对应的类中定义对应的对象,另外一个包可以写关于该对象的类(域或者实体)的模型java类,传参数的时候可以传对象的属性[f16] ,当然action中对应的类关于该对象的set、get方法[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对象并且赋值。当然关于该对象的get、set还是得有。
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] }
上面的map,key是name,value是只有一个元素的数组[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,意思是运用服务器跳转到结果页面,也就是jsp:froword到其他一个页面去。下面的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属性值,改为上一个package的name属性值即可。简单点说就是package继承。
extends的默认值struts-default指的是在struts2-core-2.3.14.jar/struts-default.xml文件里面的name为struts-default的package
58. DynamicResult:动态结果
在对应的action的类中可以另外定义个属性,当然也要有set、get方法。在重新的excute方法里面可以根据传入参数进行动态的指定上面定义的属性值。然后可以在struts.xml文件中result标签中用“$”调用该属性值。action类中定义的属性在valuestack中,也就是说在struts配置文件中$[f49] {xxx}可以访问valuestack中的名字为xxx的Property 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(不牵扯hibernate和spring情况下)层,给出一些操作数据库的方法(可以先写全部的空方法,需要返回值的时候写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代码,直接用简单的标签代替。所以jstl和struts标签的作用是简化了我们在jsp中的java代码(脚本编制元素跟完善一些)的书写。另外struts标签还自带了一些html格式(即拿出内容后以一定的格式显示在浏览器上)
76. jstl和struts标签的作用:避免在 JSP页面中使用脚本编制元素[f102] 。
将脚本编制元素的书写格式换成另外一种更容易理解、书写、简单等标签书写格式,但是后台的处理和者结果是一样的。最大的好处可能就是使只负责JSP编写不管其他内容编写的作者减少对编制脚本元素的学习。
77. 分层和方法调用然后返回对应值解决了:在jsp页面的直接与数据库交互。
jstl和struts标签解决了:美工可以学习更简单的标签语言,不用学习较复杂的脚本编制元素。
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文件中的配置不清楚的情况下都可以去struts的jar包中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.1的invoke调用里面,不是下面,这样才能在执行完action之后再调用一次intercept。
官方架构图:doc文档里面的guide里面的架构guide。actionMapper访问jar包里面的静态资源。
96. 写自己的intercept,实现intercept接口,并实现里面的方法,最主要的方法是public String intercept(ActionInvocationinvocation){}方法。该方法里面最主要的的是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,该result的name=“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]挨着排搜application、request、session,那个对应的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。注意要有name为index的action;命名空间后面不跟action或者错误的action都会访问这个默认的name为index的action。
只是简单转发,不处理和数据库的业务逻辑(不执行对应的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中放入name为session的value中,stack context中不会出现name为adminPassword的行,如果不加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]此标签也可以放在别的地方。对应拦截范围不同。
此处这个标签只对应name为test的action。
[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
- struts2学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- java学习笔记(word文档备注不能正常显示,如有错误,忘不吝指正)
- hibernate学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- spring学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- oracle学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- servlet和jsp学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- ADG[如有错误请不吝斧正]
- create catalog[如有错误请不吝斧正]
- 从现在起,我将学习Delphi过程中的经验和自以为是的结论放上来,如果有错误,请朋友们不吝指正,丢鸡蛋吧!
- Word图标不能正常显示
- 浅谈一下weex,如有错误,请阿里大神指正
- c语言试题整理(如有错误还望指正)
- 自加自减运算符的错误使用和理解【个人学习笔记,如有错误欢迎指正】
- 对于指针(一级指针)的理解(本人学生一枚,文中如有理解错误,欢迎指正,大家互相学习)
- struts2执行流程(个人理解,有错误请批评指正)
- Struts2 日历控件不能正常显示
- 将本地项目放到Github上(应该可以这么说)[如有错误欢迎大家批评指正]
- 剑指Offer22题栈的压入、弹出序列 java解答(如有错误欢迎批评指正)
- 第58天
- 别人让自己女人过得多好啊,自己呢,过得和个傻逼一样
- jQuery做弹出信息框代码
- 指针的大小--sizeof问题
- 关于内核符号表
- struts2学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- web.xml启动顺序
- PHP从零单排(十三)使用PHP显示MySQL数据库的数据
- 输入日期计算出星期几
- servlet和jsp学习(word文档备注不能正常显示,如有错误,忘不吝指正)
- 与服务器交互 不得太依靠服务器
- 基于TCP UDP 协议的聊天小DEMO
- 搭建SERVER2008上的IIS需要三部
- 如何用MATLAB绘制雷达图(戴布拉图、螂蛛网图、玫瑰图)