struts2学习笔记(不断更新)

1. 修改配置不需要重新加载
<constant name="struts.devMode" value="true" />
设置成开发模式
2. 设置myeclipse视图是Navigator 切换到pack
配置查看源码 点击jar包 选择 External Foalder 选择源码所在 例如查看 源码

查看jar   doc


3. 配置struts.xml 提示 首选项 catalog   找到xml catalog
复制struts.xml 里面那句http://struts.apache.org/dtds/struts-2.0.dtd
Key type 选择 URL
解压struts2-core-2.1.6.jar 找到struts-2.1.dtd
Location找到struts-2.1.dtd 选择
在struts.xml 输入<按alt+/代码提示



3. namespace 默认为””如果不写的话 比如访问index 每次都会访问这个  假如namespace=“aa” 则访问为http://XXXX/aa/index l类似package (包)为空可以用来囊括其他package不能处理的action操作  action访问先找有没有对应的namespace的 package 如果没有则找为空的 如果还没有就报错找不到action
4. result为空则默认是success
5. copy的项目 会带有原来项目名称需要修改项目在myeclipse  web中 如下图

6. 导入项目先去掉原来jre 在加入自己的jre —>remove form build path

7. myeclipse 修改jsp编码格式

8. Struts2的action可以是一个普通的java类 只要这个类中有public String execute();就可以。Struts1必须依靠内部action
具体视图的返回可以由用户自己定义的Action来决定
具体的手段是根据返回的字符串找到对应的配置项,来决定视图的内容
具体Action的实现可以是一个普通的java类,里面有public String execute方法即可
或者实现Action接口
不过最常用的是从ActionSupport继承,好处在于可以直接使用Struts2封装好的方法
开发最好使用从ActionSupport继承方法
9.struts2每次访问必创建一个action   struts可能还是上次那个 这也是struts2和struts1的不同处之一 struts1每次访问都是同一个可能会有线程同步问题  struts每次访问都是新的不会有线程同步的问题
10. struts.xml 如果不配置  <action name="index" class="com.bjsxt.struts2.front.action.IndexAction1"> 中的 class  struts2会执行ActionSupport类ActionSupport类在webwork中
11 struts2路径是根据action路径而非jsp路径
struts2中链接jsp最好用绝对路径 加<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<a href=”<%= basePath %> /index.jsp”>
或者加<base href="<%=basePath%>">
12.action不一定默认非得执行execute方法 可以通过<action name="userAdd" class="com.bjsxt.struts2.user.action.UserAction" method="add">
指定method属性来修改默认执行的方法不推荐使用这种方法
推荐使用动态方法调用(DMI)user/user!add
*******************************************************
使用通配符(约定优于配置)大家事先要约定好jsp页面命名规则
  <action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
            <result>/Student{1}_success.jsp</result>
</action>
路径:Student / Studentadd  name="Student*" *通配Student后面的所有方法
method="{1}" 表示匹配第一个*
<result>/Student{1}_success.jsp</result>表示返回值第一个
比如return "add"; 则调用Studentadd_success.jsp
<result>/Student_{1}_success.jsp</result>表示返回值第一个
比如return "add"; 则调用Student_add_success.jsp
********************************************************
   <action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
            <result>/{1}_{2}_success.jsp</result>
            <!-- {0}_success.jsp -->
        </action>
Student / Student_add Student actiond的add方法
method="{2}
注意匹配程度和执行顺序 所以尽量不要两个类起的名字一样
13.Struts2传递参数
1. Struts2 传递参数通过get/set方法 变量可以改 但是getXX/setXX后面必须和页面参数保持一致
2.DomainModel 接受参数(使用vo/bean)
3.使用ModelDriven
public class UserAction extends ActionSupport implements ModelDriven<User>{
private User user = new User();
public String add() {
System.out.println("name=" + user.getName());
System.out.println("age=" + user.getAge());
return SUCCESS;
}

@Override
public User getModel() {
return user;
}

}  action实现ModelDrivenM<User>(使用泛型否则要进行类型强制转换)接口使用 model要自己new (User user = new User();)
@Override
public User getModel() {
return user;
}将user转为model 获取model
14. Struts2设置传递参数的编码格式
<constant name="struts.i18n.encoding" value="GBK" /> <!-- internationalization (i和n之间18个字母)-->

或者
struts2-core-2.1.6\org\apache\struts2\default.properties
struts.i18n.encoding=UTF-8
但是2.1.6版本配置了这个中文还是乱码 这个在bug 2.1.7后就解决这个问题
<!--<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>-->
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>

假如这个修改了换成2.0的FilterDispatcher中文又没乱码了
建议假如使用2.1.6使用spring的Filter
附录default.properties的内容
#
# $Id: default.properties 722328 2008-12-02 01:56:24Z davenewton $
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
### START SNIPPET: complete_file

### Struts default properties
###(can be overridden by a struts.properties file in the root of the classpath)
###

### Specifies the Configuration used to configure Struts
### one could extend org.apache.struts2.config.Configuration
### to build one's customize way of getting the configurations parameters into Struts
# struts.configuration=org.apache.struts2.config.DefaultConfiguration

### This can be used to set your default locale and encoding scheme
# struts.locale=en_US
#设置编码格式
struts.i18n.encoding=UTF-8

### if specified, the default object factory can be overridden here
### Note: short-hand notation is supported in some cases, such as "spring"
###       Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here
# struts.objectFactory = spring

### specifies the autoWiring logic when using the SpringObjectFactory.
### valid values are: name, type, auto, and constructor (name is the default)
struts.objectFactory.spring.autoWire = name

### indicates to the struts-spring integration if Class instances should be cached
### this should, until a future Spring release makes it possible, be left as true
### unless you know exactly what you are doing!
### valid values are: true, false (true is the default)
struts.objectFactory.spring.useClassCache = true

### ensures the autowire strategy is always respected.
### valid values are: true, false (false is the default)
struts.objectFactory.spring.autoWire.alwaysRespect = false

### if specified, the default object type determiner can be overridden here
### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger"
###       Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here
### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection
###       using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's
###       functions are integrated in DefaultObjectTypeDeterminer now.
###       To disable tiger support use the "notiger" property value here.
#struts.objectTypeDeterminer = tiger
#struts.objectTypeDeterminer = notiger

### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data
# struts.multipart.parser=cos
# struts.multipart.parser=pell
struts.multipart.parser=jakarta
# uses javax.servlet.context.tempdir by default
struts.multipart.saveDir=
struts.multipart.maxSize=2097152

### Load custom property files (does not override struts.properties!)
# struts.custom.properties=application,org/apache/struts2/extension/custom

### How request URLs are mapped to and from actions
#struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper

### Used by the DefaultActionMapper
### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do
### The blank extension allows you to match directory listings as well as pure action names
### without interfering with static resources.
#struts action路径后缀可以是action或者什么都不带
struts.action.extension=action,,

### Used by FilterDispatcher
### If true then Struts serves static content from inside its jar.
### If false then the static content must be available at <context_path>/struts
struts.serve.static=true

### Used by FilterDispatcher
### This is good for development where one wants changes to the static content be
### fetch on each request.
### NOTE: This will only have effect if struts.serve.static=true
### If true -> Struts will write out header for static contents such that they will
###             be cached by web browsers (using Date, Cache-Content, Pragma, Expires)
###             headers).
### If false -> Struts will write out header for static contents such that they are
###            NOT to be cached by web browser (using Cache-Content, Pragma, Expires
###            headers)
struts.serve.static.browserCache=true

### Set this to false if you wish to disable implicit dynamic method invocation
### via the URL request. This includes URLs like foo!bar.action, as well as params
### like method:bar (but not action:foo).
### An alternative to implicit dynamic method invocation is to use wildcard
### mappings, such as <action name="*/*" method="{2}" class="actions.{1}">
struts.enable.DynamicMethodInvocation = true

### Set this to true if you wish to allow slashes in your action names.  If false,
### Actions names cannot have slashes, and will be accessible via any directory
### prefix.  This is the traditional behavior expected of WebWork applications.
### Setting to true is useful when you want to use wildcards and store values
### in the URL, to be extracted by wildcard patterns, such as
### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or
### "/foo/save".
struts.enable.SlashesInActionNames = false

### use alternative syntax that requires %{} in most places
### to evaluate expressions for String attributes for tags
struts.tag.altSyntax=true

### when set to true, Struts will act much more friendly for developers. This
### includes:
### - struts.i18n.reload = true
### - struts.configuration.xml.reload = true
### - raising various debug or ignorable problems to errors
###   For example: normally a request to foo.action?someUnknownField=true should
###                be ignored (given that any value can come from the web and it
###                should not be trusted). However, during development, it may be
###                useful to know when these errors are happening and be told of
###                them right away.
#设置开发模式
struts.devMode = false

### when set to true, resource bundles will be reloaded on _every_ request.
### this is good during development, but should never be used in production
struts.i18n.reload=false

### Standard UI theme
### Change this to reflect which path should be used for JSP control tag templates by default
struts.ui.theme=xhtml
struts.ui.templateDir=template
#sets the default template type. Either ftl, vm, or jsp
struts.ui.templateSuffix=ftl

### Configuration reloading
### This will cause the configuration to reload struts.xml when it is changed
struts.configuration.xml.reload=false

### Location of velocity.properties file.  defaults to velocity.properties
struts.velocity.configfile = velocity.properties

### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext
struts.velocity.contexts =

### Location of the velocity toolbox
struts.velocity.toolboxlocation=

### used to build URLs, such as the UrlTag
struts.url.http.port = 80
struts.url.https.port = 443
### possible values are: none, get or all
struts.url.includeParams = none

### Load custom default resource bundles
# struts.custom.i18n.resources=testmessages,testmessages2

### workaround for some app servers that don't handle HttpServletRequest.getParameterMap()
### often used for WebLogic, Orion, and OC4J
struts.dispatcher.parametersWorkaround = false

### configure the Freemarker Manager class to be used
### Allows user to plug-in customised Freemarker Manager if necessary
### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager
#struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager

### Enables caching of FreeMarker templates
### Has the same effect as copying the templates under WEB_APP/templates
struts.freemarker.templatesCache=false

### Enables caching of models on the BeanWrapper
struts.freemarker.beanwrapperCache=false

### See the StrutsBeanWrapper javadocs for more information
struts.freemarker.wrapper.altMap=true

### maxStrongSize for MruCacheStorage for freemarker
struts.freemarker.mru.max.strong.size=100

### configure the XSLTResult class to use stylesheet caching.
### Set to true for developers and false for production.
struts.xslt.nocache=false

### Whether to always select the namespace to be everything before the last slash or not
struts.mapper.alwaysSelectFullNamespace=false

### Whether to allow static method access in OGNL expressions or not
struts.ognl.allowStaticMethodAccess=false

### END SNIPPET: complete_file

Struts.xml可以配置的参数参照default.properties  当配置了struts.xml后default.properties的配置会被覆盖失效

15. 后台验证
            private String name;
            name的get/set方法省略
            this.addFieldError("name", "name is error");
”name”对应的就是属性 这句话就是name属性出错了
this.addFieldError("name", "name is too long");
  <result name="error">/user_add_error.jsp</result> s
truts.xml定义出错页面
页面上输出错误信息:<%@taglib uri="/struts-tags" prefix="s" %> 加struts2的标签
<s:fielderror fieldName="name" theme="simple"/>  输出name属性的错误 可以通过theme指定主题  simple是struts默认主题
通过查看源代码可以看到<s:fielderror标签输出的是ul和li的组成的信息
页面可以通过<s:debug></s:debug> 调试
<s:property value="errors "/> 可以取<s:debug>错误信息栈里面的value为error的错误信息<s:property value="errors.name"/> 因为error是map信息 通过对应的name key取value
取出来value是个数组 所以通过<s:property value="errors.name[0]"/>取数组第一个
这个表达式也是OGNL表达式
<s:fielderror fieldName="name" theme="simple"/>带样式 可以通过<s:property value="errors.name[0]"/>取出来加CSS样式修饰
Action中可以用同一个名字对应多个值例如this.addFieldError("name", "name is too long");
这样两个错误信息都会通过<s:fielderror fieldName="name" theme="simple"/>输出  也可以通过<s:property value="errors.name[0]"/>输出
可以通过给li加css样式美化或者修改jar中<s:fielderror标签模板文件
在\struts2-core-2.2.3\template\simple下面有fielderror.ftl模板
或者覆盖<s:fielderror标签模板文件
做法:在src下建template\simple文件夹下重写fielderror.ftl  (和struts2目录和文件名一样)
或者采用自定义主题方法
Copy一个主题修改 详细配置略
推荐修改Css方法
16.多个按钮提交同一个form
<form name="f" action="" method="post">
用户名:<input type="text" name="name"/>
密码:<input type="text" name="password"/>
<br />
<input type="button" value="submit1" onclick="javascript:document.f.action='login/login1';document.f.submit();" />
<input type="button" value="submit2" onclick="javascript:document.f.action='login/login2';document.f.submit();" />
<input type="button" value="submit3" onclick="javascript:document.f.action='login/login3';document.f.submit();" />
<input type="button" value="submit4" onclick="javascript:document.f.action='login/login4';document.f.submit();" />
</form>
17. 取得Map类型request,session,application,真实类型 HttpServletRequest, HttpSession, ServletContext的引用:
方法1 ActionContext(不常用)
Action中
public class LoginAction1 extends ActionSupport {

private Map request;//map类型
private Map session;
private Map application;

public LoginAction1() {
request = (Map)ActionContext.getContext().get("request");// ActionContext表示早action全部中的reques  这句话意思是取全部request值 放在(private Map request;)的map类型中  下面同样去取全部session和application放在上面定义的map类型的session和application
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;
}


}
页面取值(Struts2标签和原始方法对比)
<s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />
<s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />
<s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />

<s:property value="#attr.a1"/><br />
<s:property value="#attr.s1"/><br />
<s:property value="#attr.r1"/><br />   可以搜索request  session  application 中的含有的a1 s1  r1  的值 
不过不建议使用 如果request  session 或application存的有重名就会有问题
注意这里在web.xml一定要用2.1的配置
  <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
不能用2.0的配置

方法2(最常用的方法 通过IOC)

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 implements RequestAware,SessionAware, ApplicationAware {

private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;

//DI dependency injection
//IoC inverse of control
public String execute() {
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return SUCCESS;
}

@Override
public void setRequest(Map<String, Object> request) {
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;
}


}
实现implements RequestAware,SessionAware, ApplicationAware三个接口 必须重写
@Override
public void setRequest(Map<String, Object> request) {
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;
}
定义三个带泛型的
private Map<String, Object> request;
private Map<String, Object> session;
private Map<String, Object> application;
可以确定request前面值必须是String 后面是Object

这里没有new 也没有像方法1从application = ActionContext.getContext().getApplication();、
ActionContext中去 这里用到的就是IOC //DI dependency injection(依赖注入)//IoC inverse of control(控制反转)

程序判断实现了RequestAware接口然后注入request
private Map<String, Object> request;中的request依赖struts2(外界环境)注入给程序 还不是主动去取比如一种就是主动去actioncontext中去取
同理session和Application也一样
控制反转:本来自己控制request的值 现在变成容器控制
这种方式是最常用的request Application不常用 也就是取session常用这种方式

方法3 通过HttpServletRequest HttpSession ServletContext 取(基本不用)
private HttpServletRequest request;
private HttpSession session;
private ServletContext application;

public LoginAction3() {
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
}
方法4 implements ServletRequestAware(不常用)
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();
}

}
实现ServletRequestAware接口


18. 多模块包含<include file="login.xml" /> 在struts.xml引入其他xml
19.默认action
  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index"></default-action-ref>
    <action name="index">
    <result>/default.jsp</result>
    </action>
</package>
<default-action-ref name="index"></default-action-ref>
当访问当前命名空间内容找不到相应的action的时候 默认就访问index
20. Result类型

默认是dispatcher也就是forward 跳转 一个jsp ,html 单必须是一个页面但是不能是action
   <action name="r1">
    <result type="dispatcher">/r1.jsp</result>
    </action>
Redirect跳转 一个jsp ,html 单必须是一个页面但是不能是action
<action name="r2">
    <result type="redirect">/r2.jsp</result>
    </action>
chain 可以跳转到一个action  注意不要加/ 跳转到其他命名空间有问题 详细见api
<action name="r3">
<result type="chain">r1</result>
</action>
redirectAction可以跳转到客户端一个action  注意不要加/
<action name="r4">
<result type="redirectAction">r2</result>
</action>
Freemarker:跳转到Freemarker
Httpheader:发一个Http头信息
Stream:下载
Velocity:跳转到Velocity模板
Xslt:跳转到Xslt(修饰的xml语言)
Plaintext:显示源码
Tiles:
   

21 全局的结果 大家共用的返回结果集 比如大家共用mainpage
<package name="user" namespace="/user" extends="struts-default">
    <global-results>
    <result name="mainpage">/main.jsp</result>
    </global-results>
    <action name="index">
    <result>/index.jsp</result>
    </action>
    <action name="user" class="com.bjsxt.struts2.user.action.UserAction">
    <result>/user_success.jsp</result>
    <result name="error">/user_error.jsp</result>
    </action>    
</package>
假如另一个package想用这个包得result
<package name="admin" namespace="/admin" extends="user">
    <action name="admin" class="com.bjsxt.struts2.user.action.AdminAction">
    <result>/admin.jsp</result>
    </action>
    </package>可以通过继承user :extends="user" 比如404 页面可以大家共用其他都继承404 所在package

21动态返回result
Action写法
public class UserAction extends ActionSupport {
private int type;

private String r;

public String getR() {
return r;
}

public void setR(String r) {
this.r = r;
}

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

@Override
public String execute() throws Exception {
if(type == 1) r="/user_success.jsp";
else if (type == 2) r="/user_error.jsp";
return "success";
}

}
Struts.xml写法
<package name="user" namespace="/user" extends="struts-default">
   
    <action name="user" class="com.bjsxt.struts2.user.action.UserAction">
    <result>${r}</result>
    </action>    
    </package>
在action中可以通过属性来确定result值
${r} 中的r是根据action程序动态调整
${r}可以去读值栈(debug输出)里面内容还可以用%
22 取传递的值
在a页面有个请求xx?type =5  在b页面取id值
在action中
public class UserAction extends ActionSupport {
private int type;

public int getType() {
return type;
}

public void setType(int type) {
this.type = type;
}

@Override
public String execute() throws Exception {
return "success";
}

}
参数的get.set方法
Sturts.xml配置
<package name="user" namespace="/user" extends="struts-default">
   
    <action name="user" class="com.bjsxt.struts2.user.action.UserAction">
    <result type="redirect">/user_success.jsp?t=${type}</result>
    </action>    
</package>
?t=${type}加上action属性
页面取值方法from actioncontext: <s:property value="#parameters.t"/>
from valuestack: <s:property value="t"/><br/>这种方式是值栈的值 取不到参数传递的值
页面在forward时候不需要这种方式 在redirect需要
23. OGNL(Object Graph Navlgation lanuaage )对象图导航语言
1). 访问值栈中的action的普通属性: username = <s:property value="username"/>
2). 访问值栈中vo对象的普通属性(get set方法):<s:property value="user.age"/>
   注意传值的时候必须是?user.age=XXX 才回构造
想初始化domain model(VO)可以自己new也可以传参数值(例如:?user.age=XXX)
在化domain model((VO)中必须有一个参数为空的构造方法public User() {}
3). UserActin有个Cat 的domain model((VO) Cat里有个Dog domain model((VO)
访问Dog name 应该是 cat.dog.name  cat是在Useraction中有Cat get/set  dog是在Cat中友Dog的get/set 同样给dog的name传值也是?cat.dog.name=XXX
4). 访问值栈中对象的普通方法:例如调用String类型的length()方法<s:property value="password.length()"/>
5). 访问值栈中对象的普通方法: 例如Cat方法中有个miaomiao方法public String miaomiao() {return "miaomiao";} 页面中直接<s:property value="cat.miaomiao()" />就可以调用
6). 访问值栈中action的普通方法:例如action有一个public String m() {return "hello";}页面可以<s:property value="m()" />调用
7). 访问静态方法:public static String s() {return "static method";}<s:property value="@com.bjsxt.struts2.ognl.S@s()"/>
2.1需要在Struts.xml 增加<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>  允许静态方法访问设成true 因为默认值是flase(在default.properties ### Whether to allow static method access in OGNL expressions or notstruts.ognl.allowStaticMethodAccess=false)
8)访问静态属性:public static String STR = "STATIC STRING"; <s:property value="@com.bjsxt.struts2.ognl.S@STR"/>
9)访问Math类的静态方法:<s:property value="@@max(2,3)" /> 只能访问math累注意两个@@
10)访问普通类的构造方法:new  相当于new了一个user类<s:property value="new com.bjsxt.struts2.ognl.User(8)"/>
因为User重写了toString @Override   public String toString() {return "user" + age;}  所以输出user8 
11)访问集合
  在UserAction中有private Set<Dog> dogs = new HashSet<Dog>();
              private List<User> users = new ArrayList<User>();
private Map<String, Dog> dogMap = new HashMap<String, Dog>();
get/set方法略
一.访问list
   访问数组和list一样具体参照list
1.访问List:<s:property value="users"/>
2.访问List中某个元素:<s:property value="users[1]"/>
3.访问List中元素某个属性的集合:<s:property value="users.{age}"/>
4.访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/>(不要使用) | <s:property value="users[0].age"/>(使用这一种)
二.访问Set (和list一样)
1.访问Set:<s:property value="dogs"/>
2.访问Set中某个元素:<s:property value="dogs[1]"/> 这样取不到  因为set没有顺序
   三 .访问Map
1.访问Map:<s:property value="dogMap"/>
2.访问Map中某个元素(根据key值取):<s:property value="dogMap.dog101"/>(推荐使用这个 直观方便) | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/>(转义字符)
3. 访问Map中所有的key:<s:property value="dogMap.keys"/>
4.访问Map中所有的value:<s:property value="dogMap.values"/>
5.访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/>
Size不加()也可以
12)访问投影(也就是过滤 把符合条件的过滤出来)
   正则中^代表开头 $代表结束 ?代表过滤条件
  1.投影(过滤):<s:property value="users.{?#this.age==1}[0]"/> (?#)
(<s:property value="users.{?#this.age==1}.{age}"/> ?代表过滤条件    this指循环的当前对象  这句话意思是循环判断取出来age=1的)
2.投影:<s:property value="users.{^#this.age>1}.{age}"/>(^#)
   这句话意思是去age大于1的开头(第一个)元素
3.投影:<s:property value="users.{$#this.age>1}.{age}"/>($#)
这句话意思是去age大于1的结尾(最后一个)元素
4.投影:<s:property value="users.{$#this.age>1}.{age} == null"/>
  这句话意思是去age集合是不是null 或者用判断size是不是等于0也可以
13)用[]访问里面元素
[]:<s:property value="[0]"/>访问的是栈值(可以用debug输出看)第0个
假如使用服务器端跳转

    <package name="ognl" extends="struts-default">

        <action name="ognl" class="com.bjsxt.struts2.ognl.OgnlAction">
            <result>/ognl.jsp</result>
        </action>
        <action name="test" class="com.bjsxt.struts2.ognl.TestAction">
            <result type="chain">ognl</result>
        </action>

</package>
Debug输出会发现有值栈有两个action  也就是服务器端跳转(chain)值栈会一直往里压值
[]:<s:property value="[0].username"/>
24.Struts2标签
Property标签
property: <s:property value="username"/>
property 取值为字符串: <s:property value="'username'"/>
property 设定默认值: <s:property value="admin" default="管理员"/>
property 设定HTML: <s:property value="'<hr/>'" escape="false"/>
escape默认是true
Set标签 将某个值放入指定范围(session,application,request,page,action)内,如果没有指定范围则默认放在StackContext
2.1以后name和id都已经废弃 使用scope value var  set标签用于换名比较常见
set 设定adminName值(默认为request 和 ActionContext): <s:set var="adminName" value="username" />
set 从request取值: <s:property value="#request.adminName" />
set 从ActionContext取值: <s:property value="#adminName" />
set 设定范围: <s:set name="adminPassword" value="password" scope="page"/>
set 从相应范围取值: <%=pageContext.getAttribute("adminPassword") %>
set 设定var,范围为ActionContext:
<s:set var="adminPassword" value="password" scope="session"/>
set 使用#取值: <s:property value="#adminPassword"/> </li>
set 从相应范围取值: <s:property value="#session.adminPassword"/>
Bean标签
2.0这样写
<s:bean name="com.bjsxt.struts2.tags.Dog" >这句话相当于new了一个bean
<s:param name="name" value="'pp'"></s:param>
<s:property value="name"/>
</s:bean>

2.1开始id废弃 使用var
必须加var Stack Context才可以访问到
<s:bean name="com.bjsxt.struts2.tags.Dog" var=”dog” >
<s:param name="name" value="'pp'"></s:param> value=" ' ' "里面有' '
<s:property value="name"/>
</s:bean>
Include标签(少用)
包含文件中含有中文有问题
include _include1.html 包含静态英文文件
<s:include value="/_include1.html"></s:include>
include _include2.html 包含静态中文文件
<s:include value="/_include2.html"></s:include>
include _include1.html 包含静态英文文件,说明%用法
<s:set var="incPage" value="%{'/_include1.html'}" />
<s:include value="%{#incPage}"></s:include>
%{}强制把{}内的不要当成字符串 把它当成OGNL表达式
控制标签

<li>if elseif else: <s:property value="#parameters.age[0]" />
<s:set var="age" value="#parameters.age[0]" />//set这里用age替换了用"#parameters.age[0]方便下面写
<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 />
1.遍历集合:iterator可以遍历collection map enumeration iterator array
<s:iterator value="{1, 2, 3}" >
<s:property/> |
</s:iterator>

2.自定义变量:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
<s:property value="#x.toUpperCase()"/> |
</s:iterator>

3.使用status:
<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
<s:property/> |
遍历过的元素总数:<s:property value="#status.count"/> |
遍历过的元素索引:<s:property value="#status.index"/> |
当前是偶数?:<s:property value="#status.even"/> |
当前是奇数?:<s:property value="#status.odd"/> |
是第一个元素吗?:<s:property value="#status.first"/> |
是最后一个元素吗?:<s:property value="#status.last"/>

</s:iterator>
遍历map
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" >必须在定义map加#
<s:property value="key"/> | <s:property value="value"/> <br />
</s:iterator>
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
25.myeclipse快速注释ctrl+shift+/采用/**/方式注释 ctrl+shift+c采用//注释
26.$#%
$用于i18n和struts配置文件
#用户取得actioncontex的值
%将原来的文本属性解析问ognl 对于本来就是ognl的属性不起作用
27.定义自己theme方法
1.修改css(覆盖原来的css)
2.覆盖当个模板
3.自定义主题
使用过程中最好默认设置为simple 错误标签问题修改css

升级2.2遇到问题
Json问题 删除老的json包
Hibernate注解包删除
必须写namespace=”/”
国家化的时候假如是外部js 可以将js后缀改成jsp 并在页面上加上struts标签库引入和页面转码
 

猜你喜欢

转载自shizhijian870525.iteye.com/blog/1131907