- 浏览: 76683 次
- 性别:
- 来自: 杭州
文章分类
最新评论
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标签库引入和页面转码
<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标签库引入和页面转码
相关推荐
根据给定的文件信息,以下是对Struts2学习笔记中涉及的关键知识点的详细解析: ### Struts2框架概览 #### MVC模式的理解与演进 Struts2是基于MVC(Model-View-Controller)模式设计的一种Java Web开发框架。在MVC...
这份"struts2学习笔记和源码"资源是学习这个框架的理想材料,特别适合初学者。 一、Struts2框架基础 Struts2是Apache软件基金会下的一个项目,它是Struts1的升级版,弥补了Struts1的一些不足,如动作映射和拦截器等...
本学习笔记将详细阐述Struts2的核心概念、发展历程、使用步骤以及OGNL技术。 一、Struts2概述 1.1 为什么要用Struts 在传统的JSP开发中,模型与视图、控制器的耦合度较高,导致代码维护困难。Struts2引入了MVC...
【张冰Struts2学习笔记】0102_第一个Struts2实例 在Java Web开发领域,Struts2框架是十分重要的MVC(模型-视图-控制器)架构之一,它极大地简化了Web应用程序的开发流程。这篇学习笔记将带你入门Struts2,通过创建...
Struts2是一个强大的Java web应用程序框架,用于构建MVC(模型-视图-控制器)架构的应用。本笔记将深入探讨Struts2的核心组件、配置以及它的一些关键特性...不断学习和实践Struts2,将有助于提升你的Java web开发技能。
本学习笔记将深入探讨Struts2的核心概念、工作原理以及如何在实际开发中有效利用它。 **1. MVC模式与Struts2** MVC模式是一种软件设计模式,它将业务逻辑(Model)、用户界面(View)和数据控制(Controller)分离...
本篇学习笔记将深入探讨Struts2的入门与配置,继续上一讲的内容。 首先,Struts2的基础入门涉及到以下几个核心概念: 1. **Action类**:在Struts2中,业务逻辑通常封装在Action类中。Action类是处理用户请求的主体...
本笔记将重点介绍Struts2的核心概念、配置、动作(Action)以及拦截器(Interceptor)。 一、Struts2核心概念 1. **Action类**:在Struts2中,业务逻辑通常封装在Action类中,它是处理用户请求的入口点。Action类...
在本篇“Struts2学习笔记十四”中,我们将深入探讨Struts2框架如何实现文件上传和下载功能,这是web应用中常见的需求,尤其在处理用户提交的表单数据时。我们将不涉及具体代码,而是重点讲解相关概念和技术原理。 ...
这个入门教程和学习笔记是针对初学者设计的,帮助他们快速理解和掌握Struts2的核心概念和实践操作。 Struts2的学习首先需要理解MVC模式。MVC模式将应用逻辑分为三个部分:模型负责业务逻辑,视图负责展示数据,而...
Struts2是一个强大的Java web框架,它为开发者提供了构建MVC(模型-视图-控制器)应用程序的强大工具。在第六讲中,我们将深入...通过不断的实践和学习,我们可以更好地利用Struts2提供的工具来创建高质量的Web应用。
在学习Struts2的过程中,配合源码阅读能够更深入理解其内部工作机制。Struts2的工具如IDEA的插件可以帮助开发者快速创建Action、配置Action和视图之间的关联,提高开发效率。 总之,Struts2作为一个成熟的Java Web...
- Struts2最初是在2005年由WebWork和Struts1的基础上合并发展而来,随着技术的发展,Struts2不断更新迭代,增加了对Ajax的支持、改进了性能等。 #### 四、搭建Struts2的开发环境 1. **复制JAR包**:参考`struts2-...
这篇自学笔记将深入探讨Struts2的文件上传机制。 1. **文件上传原理** 文件上传是基于HTTP协议的POST请求实现的。在HTML表单中,通过`<input type="file" />`元素让用户选择本地文件。当用户提交表单时,浏览器会...
通过传智播客的struts2框架2016版day01课程,你可以系统地掌握Struts2的基础知识,为后续的深入学习和项目开发打下坚实的基础。同时,结合笔记和思路图,可以更好地理解和吸收所学内容,提升学习效率。在实际编程中...
Struts2是Java Web开发中一个非常重要的框架,它基于MVC(Model-View-Controller)设计模式,为...同时,提供的教学课件、上课笔记和考试资料将为学习过程提供丰富的参考资料,帮助你在实践中不断巩固和深化理解。
### STRUTS2学习系列:理解与应用 #### 引言 Struts作为MVC(Model-View-Controller)架构模式的代表性Web框架之一,自从其问世以来,便以其清晰的架构设计、丰富的标签库以及开源特性,赢得了广大开发者的心。...
Struts是Java Web开发中的一个开源框架,它主要用于构建基于MVC(模型-视图-控制器)模式的应用程序。...不过,这只是Struts学习的一个起点,深入掌握还需要不断实践和探索更多的高级特性和最佳实践。
本篇学习笔记主要关注的是ActionForm,它是Struts框架中用于处理用户请求的核心组件之一。 ActionForm是Struts中用于接收和验证用户输入的数据的类。当用户通过表单提交数据时,这些数据会被封装到一个ActionForm...