1、package继承 struts-default 就继承了其内定义的一系列拦截器。
2、<action name="test"></action> 默认动作访问地址是 test或者test.action 。修改扩展名原始的方法是到struts-core.jar包内的 org.apache.struts2/sta/default.properties 中找到
struts.action.extension=action,, 然后修改打包。
通常的做法是:在struts.xml中用constant常量标签进行配置,如下:
<constant name="struts.devMode" value="true" /> // 配置开发模式
<constant name="struts.action.extension" value="action,,do," // 添加了扩展名为do
这里面所有的值都可以在上面的default.properties里面找到。
3、动态方法。在一个action的java源文件中,定义多个函数,如何分别调用?有四种方法。
struts.xml中就不要配置具体的执行方法了,只配置action中定义的不同返回结果对应的返回路径,如:
<action name="multi" class="com.ma.MultiAction"> // 设MultiAction中定义了两个方法fun1和fun2 ,返回值分别是res1 和res2
<result name="res1">a.jsp</result>
<result name="res2">b.jsp</result>
</action>
访问路径:
1)multi!fun1 multi!fun2
2)multi?method:fun1 multi?method:fun2
3)第三种方法,在提交表单中,添加域 <input name="method:fun1"> 也可以达到效果。(一般可加在submit域里)
4)第四种方法,通配符方法<action name="multi_*" class="com.ma.MultiAction" method="{1}"> 这样 multi_fun1.action就是访问的fun1方法 multi_fun2同理
4、结果集类型。不写默认就是dispatcher 服务器端转发<result name="success" type="dispatcher">success.jsp</result> 即 type="dispatcher"是可省略的
dispatcher 服务器端转发 redirect 客户端转发,网址要变了
chain 服务器端action转发 redirectAction 客户端action 转发
还有freemarker stream(上传下载时候使用) plainText(直接显示转发文件的源码)等类型
5、前台form表单,填写之后通过action的bean类写法取值的注意点,一些数值类型要定义成包装类,比如Integer,Long 。如果定义成int long 那么前台表单该属性对应的项目如果是空值的话,提交之后会报错。
6、注意,struts 的action类是多例多线程的,通过在类内添加System.out.println(this) 可以看出每次打印出的类名的后面的哈希码是不一样的。在SSH整合后,要将这个多例变成单例。servlet是单例多线程的。
7、ActionContext.getContext()用来取得Action的上下文环境,这里面包含了servlet request等等各种信息,并且也可以直接存值。ActionContext.getContext().put("name","zhangtao"); 在前台jsp页面中用struts标签取值时候,一定要在变量名前加# :<s:property value="#name">
不加的话,出于容错考虑,不会出现错误。但是若ActionContext中定义的变量与Action类中的属性相同时,则会出现问题。
8、ServletActionContext 取得传统的Servlet那一套东西
赋值:
ServletActionContext.getRequest().setAttribute("req", "request值");
ServletActionContext.getRequest().getSession().setAttribute("ses", "session值");
ServletActionContext.getServletContext().setAttribute("con", "application值");
前台jsp取值:
request:<s:property value="#request.req" /><br>
session:<s:property value="#session.ses" /><br>
context:<s:property value="#application.con" /><br>
9、ActionContext去设置Servlet那一套东西的值 以及取值
ActionContext.getContext().put(key, value) 这个其实类同request赋值
ActionContext.getContext().getSession().put(key, value) session赋值
ActionContext.getContext().getApplication().put(key, value) application赋值
取值的等同写法:(针对 request session application)
<s:property value="#request.req" /> <s:property value="#request['req']" />
<s:property value="#attr.req" /> <s:property value="#attr['req']" />
${requestScope.req} EL表达式写法
${req} -- 注意,不写范围,默认的取值范围顺序是:pageContext request session application
10、给复杂对象传值。
前端jsp 提交
<input type="text" name="user.username">
<input type="text" name="user.address.homeaddress">
----------------
后台取值
Action.java中
private User user; ... getter and setter
User.java中
private String username;
private Address address; ... getter and setter
Address.java中
private String homeaddress ... getter and setter
-------------------
前台jsp显示值
<s:property value="user.username" />
<s:property value="user.address.homeaddress" />
11、集合传值
在Action中,定义一个List
List<User> list = new List<User>();
// User 中有 username 和 password属性,给list添加若干个构造好的User对象,然后将list加入到ActionContext中
ActionContext.getContext().put("list",list);
前台jsp 循环显示集合值
<s:iterator value="#list">
<s:property value="username">
<s:property value="password">
</s:iterator>
还可以这样:
<s:iterator value="#list" var="obj">
<s:property value="#obj.username">
<s:property value="#obj.password">
</s:iterator>
12、OGNL对各种方法的调用。
假设com.zhang.src包内的文件Test.java中的一个方法 fun()
前台jsp页面中静态方法调用:
<s:property value="@com.zhang.src.Test@fun()" />
动态方法调用
<s:property value="new com.zhang.src.Test().fun()" />
调用Action类中定义的方法,可以直接调用
<s:property value="funInAction()" />
13、OGNL就是一种对象导航关系,可以用在jsp、传递的参数以及struts配置文件中
类中定义了user对象,假设User类中包含address对象,address对象中包含phone对象,phone对象中有number属性,则有:
Ognl.getValue("address.phone.number",user); 或 Ognl.getValue("#root.address.phone.number",user);
Ognl.setValue("address.phone.number",user,"123456"); 或Ognl.setValue("#root.address.phone.number",user,"123456");
14、拦截器总结
拦截器会对所拦截的Action内的所有方法实施拦截。定义方式如下:
<package name="form" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="ses" class="com.mavict.struts.MyInterceptor" />
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="ses" />
</interceptor-stack>
</interceptors>
//----位置1
<action name="getvalue" class="com.mavict.struts.Form">
//----位置 2
<interceptor-ref name="myStack" />
<result name="success">form_value.jsp</result>
<result name="china">form_value.jsp</result>
<result name="japan">form_value.jsp</result>
</action>
</package>
包内,action外定义好。action内使用。
定义拦截器需继承AbstractInterceptor类,实现intercept方法,其中的该方法内的ActionInvocation变量invocation可以取得ActionContext,从而取得一系列servlet
ActionContext actionContext = invocation.getInvocationContext();
15、配置技巧和全局结果集
在包内action外,如上位置1处,定义<default-interceptor-ref name = "myDefaultStack" />,则包内的每个action都不用再配置<interceptor-ref />了,都会默认执行这个myDefaultStack。如果此时某个action不需要执行这个myDefaultStack,处理方法是在该action内再配置一个拦截器就可以使这个myDefaultStack对其失效。一般是在其action内配置那个默认<intercetpor-ref name="defaultStack" />即可。
全局结果集的问题。如果一包内很多action,都有一个结果需返回同一个地址,则这时不需要在每个action内都配置这个返回结果。可以直接抽取出来,做成全局结果集,放到所有action外面、前面,所有interceptor后面的位置,定义格式如下:
<global-results>
<result name="commonResult">common.jsp</result>
</global-results>
16、在struts.xml配置文件中使用OGNL表达式
在action中的属性,以及Action中定义在ActionContext中的变量,都可以直接用在struts.xml中。在struts.xml中的使用方式是 ${#valueInActionContext} ${valueInAction}
17、ModelDriven 简化赋值
Action 继承 ModelDriven接口,然后类内可以去除实体类的getter 和 Setter方法 ,并实现接口默认的方法 getModel
private User user = null;
@Override
public Object getModel() {
if( user == null){ user = new User(); }
return user;
}
则前台可以直接用user的属性值,如username,而不必再使用user.username;
ModelDriven有陷阱,解决方法有三。待深究
18、局部类型转换器和全局类型转换器。待深究
19、文件上传
private File myfile;
private String myfileFileName; -- 文件名固定 ~~ + FileName
private String myfileContentType; -- 文件类型固定 ~~ + ContentType
FileUtils.copyFile(myfile, new File("c:/upload/"+myfileFileName));
前台form表单enctype="mulitpart/form-data" 必须设置
20、资源文件读取
abc.properties放在src下
ResourceBundle bundle = ResouceBundle.getBundle("abc");
String s = bundle.getString("item");
21、convention 免配置
首先,struts.xml中需要的配置
<!-- 结果资源的路径 -->
<constant name="struts.convention.result.path" value="/test/" />
<!-- URL资源分隔符 action和result地址都是-->
<constant name="struts.convention.action.name.separator" value="_" />
<!-- action扫描包,如果不配置这项,那么会默认扫描action/actions/ struts/struts2 等结尾的包 -->
<constant name="struts.convention.action.packages" value="com.mm.test" />
形如com.mm.action.zhang.ChinaBeijingAction 会映射到 zhang/china_beijing 的URL地址,对应的文件是 /test/china_beijing_返回结果字符串.后缀 ,若找不到,会返回/test/china_beijing.后缀
action链的配置,满足三个条件:
1、第一个Action返回的逻辑视图字符串没有对应的视图资源
2、第二个Action与第一个Action处于同一个包内
3、第二个Action的名字是第一个Action名字加其返回结果。例 :第一个Action名字是 FirstAction 返回结果是 second ,则第二个Action名字应该为 FirstSecondAction