指定Tomcat的目次,指定JDK搭建开辟景象(拷贝jar包,复制struts.xml文件 此文件不要放在WEB-INF下面,应当放到src下面
),在web.xml文件中:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAnduteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
此中<url-pattern>/*</url-pattern> 不要写/*.do 或者 /*.action
(1)
<!--<constant >:常量的设备 -->
<!--name="struts.devMode" value="true":当前是开辟模式,批改设备文件会主动装载 默认是false-->
<!--定名空间 ---> action -->响应的处理惩罚类或页面 -->
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="hell" class="package + class xxxx">
<result>
/Hello.jsp
</result>
</action>
</package>
(2)struts.xml不主动提示的解决办法: window--perferences-XML catalog---add---key Type="URI" key="*.dtd"
struts2的履行流程:
当用户在浏览器中敲入要接见的地址的时辰,浏览器会将这个恳求发送给tomcat然后tomcat断定应当交给那个WebApplication
来处理惩罚,然后会读取它下面的web.xml设备发明有设备:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAnduteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>因为<url-pattern> 为/* 它会过滤所有的恳求然后就交给filter类
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAnduteFilter处理惩罚履行调用doFilter()办法,然后再办法中会读
取struts.xml文件,按照用户恳求的地址找到响应的package、 action、 result、然后将响应的页面返回给浏览器
(1)namespace决意了action的接见路径,默认为"",可以接管所有路径的action
namespace可以写为/,或者/xxx,或者/xxx/yyy,对应的action接见路径为/index.action,
/xxx/index.action,或者/xxx/yyy/index.action
namespace最好也用模块来进行定名
(1)struts1 与struts2的一个首要差别:在struts1中进行多次接见的时辰用到的是同一个Action对象。而struts2则是每一次访
问都邑创建一个Action对象,所以struts2不会有线程安然题目的产生
(2)<result>标签若是没有指定name属性默认返回值为success
(3)<action>标签中的class值若是没有设备响应的类,它会调用struts默认的一个处理惩罚类的execute()办法.
(4)实现struts的处理惩罚类的时辰不要本身随便写类然后定义execute()办法,也不要实现Action类而要从ActionSupport类持续,可
以直接应用它为我们定义好的办法.
(1)struts2中的路径题目是按照action的路径而不是jsp路径来断定,所以尽量不要应用相对路径。
固然可以用redirect体式格式解决,但redirect体式格式并非须要。
解决办法很是简单,同一应用绝对路径。(在jsp顶用request.getContextRoot体式格式来拿到webapp的路径)
或者应用myeclipse经常用的,指定basePath
(2)request.getContextPath()获得项目标名字,一般用来解决路径题目 若是项目为根目次,则获得一个"",即空的字条串。
request.getscheme()返回的和谈名称.默认是http
request.getServerName()就是获取你的网站的域名,若是是在本地的话就是localhost
request.getServerPort()获取办事的端标语
Action履行的时辰并不必然要履行execute办法<br />
可以在设备文件中设备Action的时辰用method=来指定履行哪个办法
也可以在url地址中动态指定(动态办法调用DMI)(推荐)<br />
<a href="<%=context %>/user/userAdd">添加用户</a>
<br />
<a href="<%=context %>/user/user!add">添加用户</a>
<br />
前者会产生太多的action,所以不推荐应用
设备文件:
<package name="user" extends="struts-default" namespace="/user">
<action name="userAdd" class="com.bjsxt.struts2.user.action.UserAction" method="add">
<result>/user_add_success.jsp</result>
</action>
<action name="user" class="com.bjsxt.struts2.user.action.UserAction">
<result>/user_add_success.jsp</result>
</action>
</package>
首要进修通配符的应用 通配符可以将设备量降到最低,不过必然要遵守"商定优于设备"的原则
<package name="actions" extends="struts-default" namespace="/actions">
<action name="Student_add"></action>
<action name="Student_*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
<result>/Student_{1}_success.jsp</result>
</action>
<!-- 更简便的设置设备摆设法 -->
<action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
<result>/{1}_{2}_success.jsp</result>
</action>
</package>
申明:
(1){1}代表name="Student*"后面第一个""*"",同理{2}代表第二个""*""
(2).若是action之间有反复设备,struts2会匹配最正确的action。若是通配符设备之间有反复,则看前后设备次序
在持续ActionSupport的类中定义要接管的参数,参数的名称与Action所传的名称无关在struts2内部调用的是属性的set办法
,所以setxxx()的名字必然要与Action后面所传的值是一样的。
若是要接管的参数的个数很多,我们可以不消定义属性而是直接定义一个对象例如:
private User user (set get 办法)在调用Action传值的时辰应用user!add?user.name=x&user.age=x的体式格式进行值得传递
。(最常用的体式格式)
持续ActionSupport类的处理惩罚类必须同时实现ModelDriven<Object>(实现getModel())在传值的时辰应用user/user!add?
name=bbb进入处理惩罚类的时辰会调用getModel()办法返回User对象并且把传过来的值set到里面,重视:此时private User user =
new User() 不克不及只定义,要同时实现如许getModel()才干拿到user对象。
在设备文件中参加:
<constant name="struts.i18n.encoding" value="GBK"/> 遵守文档申明参加此句可解决中文乱码然则不可这是2.1.6的一个bug,
会鄙人一个版本中修复 如何解决呢:在web.xml中:
<filter-name>struts2</filter-name>
<!--<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAnduteFilter</filter-class>-->
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
把过滤器的版本改成老版本的即可解决该题目!
应用addFieldError办法和s:fieldError标签简单处理惩罚数据校验
public String add() {
if(name == null || !name.equals("admin")) {
this.addFieldError("name", "name is error");
this.addFieldError("name", "name is too long");
return ERROR;
}
return SUCCESS;
}
在页面中显示错误信息:
<!-- 以固定的css样式取失足误信息,不便利我们进行响应的处理惩罚-->
<s:fielderrorfieldName="name" theme="simple"/>
<!-- 从存储错误信息的Map中拿数据 -->
<s:property value="errors.name[1]"/>
<!-- 显示具体的栈信息-->
<s:debug></s:debug>
Value stack的应用
Request ,session,application context,httprequest
经由过程js把握一个form可以多个提交action
Context可以懂得为景象,运行时辰的所有景象的凑集
Actioncontext的高低文景象的记录,记录了action的所有的景象器材;
不合的JSP页面元素的接见;
不合JSP页面的参数的接见;
重视:web.xml中关于struts的设备必然要采取2.1的,2.0的会取不到这是一个bug
(1)经由过程ActionContext对象取得Map类型的request, session, application HttpServletRequest,
HttpSerletSessionServletContetext:
public class LoginAction1 extends ActionSupport {
private Map request;
private Map session;
private Map application;
//接见此办法,取得响应的对象然则是Map类型
public LoginAction1() {
request = (Map)ActionContext.getContext().get("request");
session = ActionContext.getContext().getSession();
application = ActionContext.getContext().getApplication();
}
//在Map类型的对象中存入响应的值
public String execute() {
request.put("r1", "r1");
session.put("s1", "s1");
application.put("a1", "a1");
return SUCCESS;
}
}
//在页面中经由过程标签取得存入的数据二种办法(经由过程标签, 经由过程原始体式格式):
<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 />
<s:debug></s:debug>
<br />
我们存入Map中的数据居然可以在request,等对象中获得,那么在struts内部他是将Map中的数据全部复制到了request,session
等对象中的 #attr ,可以取得所有的属性,然则不推荐应用,为了防止同名的景象,造成无法差别。
(2)经由过程实现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,本身不初始化对象,交给spring进行处理惩罚new的体式格式
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;
}
(3)经由过程ServletActionContext()取得真实的响应的对象
privateHttpServletRequest request;
privateHttpSession session;
privateServletContext application;
public LoginAction3() {
request = ServletActionContext.getRequest();
session = request.getSession();
application = session.getServletContext();
}
public String execute() {
request.setAttribute("r1", "r1");
session.setAttribute("s1", "s1");
application.setAttribute("a1", "a1");
return SUCCESS;
}
(4)经由过程实现ServletRequestAware接口获得响应的对象
privateHttpServletRequest request;
privateHttpSession session;
privateServletContext 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();
}
Request在value stack中应用,而application直接存放在数据库中接见,而对于session最常用
批改了action后须要从头安排,其他的jsp和struts设备文件不须要重启
<struts>
<constant name="struts.devMode" value="true" />
<include file="login.xml" />
</struts>
可以将此外写好的设备文件直接包含到struts得设备文件中,便利多人开辟避免不须要的设备文件冲突.
login.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="login" extends="struts-default" namespace="/login">
<action name="login*" class="com.bjsxt.struts2.user.action.LoginAction{1}">
<result>/user_login_success.jsp</result>
</action>
</package>
</struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 当设备文件中没有效户要接见的Aciton的时辰,会调用<default-action-ref 所定义的Action --处理惩罚错误页面 -->
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>/default.jsp</result>
</action>
</package>
ResultType的最常用的几种设备:(四种设备分别代表了四种不合的跳转体式格式)
<package name="resultTypes" namespace="/r" extends="struts-default">
<action name="r1">
<!--type不写默认的为dispatcher:用办事器跳转跳转到成果页面--只能跳转到页面,不克不及跳转到Action -->
<result type="dispatcher">/r1.jsp</result>
</action>
<action name="r2">
<!--客户端跳转的体式格式跳转到成果页面 只能跳转到页面,不克不及跳转到Action -->
<result type="redirect">/r2.jsp</result>
</action>
<action name="r3">
<!--办事器跳转的体式格式跳转到Action -->
<result type="chain">r1</result>
</action>
<action name="r4">
<!--客户端跳转的体式格式跳转到Action -->
<result type="redirectAction">r2</result>
</action>
<!--当要跳转的Action在此外包下的时辰 应当如许写-->
<action name="r5">
<result type="china">
<parma name="actionName">dashboard</param>
<parma name="namespace">/sesure</param>
</result>
</action>
<package name="user" namespace="/user" extends="struts-default">
<!-- 设备全局的成果集:当返回的result没有设备的时辰会履行全局成果集的设备-->
<global-results>
<result name="mainpage">/main.jsp</result>
</global-results>
<action name="index">
<result>/index.jsp</result>
</action>
</package>
<!--关键字extends的应用:我想鄙人面的这个设备包中应用上方那个包中的成果集,那么可以应用extends关键字持续上一个包
<package name="admin" namespace="/admin" extends="user">
<action name="admin" class="com.bjsxt.struts2.user.action.AdminAction">
<result>/admin.jsp</result>
</action>
</package>
可以在strtus.xml文件中动态的指定返回的成果集。
public class UserAction extends ActionSupport {
privateint type;
private String r;
public String getR() {
return r;
}
public void setR(String r) {
this.r = r;
}
publicintgetType() {
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">
<!--可以用¥{属性名}的体式格式取得Action中的属性,在办事器端断定好响应的跳转路径然后存到变量里 然后再struts.xml文件顶用
这种体式格式取出来,可以极大的增长设备文件的灵活性 -->
<result>¥{r}</result>
</action>
</package>
接见链接格局:<a href="user/user?type=1">传参数</a>
public class UserAction extends ActionSupport {
privateint type;
publicintgetType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public String execute() throws Exception {
return "success";
}
}
当从一个Action跳转到另一个Action的时辰,若是须要传值并且是办事器端的跳转,没有须要再struts.xml文件result的跳
转路径中进行传值操纵,因为多个办事器端的跳转,共享的是同一个值栈,可以直接取到,然则若是是客户端的跳转(redirect)的
体式格式进行跳转则须要进行如下的设备:
<package name="user" namespace="/user" extends="struts-default">
<action name="user" class="com.bjsxt.struts2.user.action.UserAction">
<!-- 用¥{}的体式格式是从值栈取值,重视:不是El表达式 -->
<result type="redirect">/user_success.jsp?t=¥{type}</result>
</action>
</package>
然则若是在jsp页面取出传输的值用<s:property value="t"/>是取不到的,因为这种体式格式是在值栈里取值而我们跳转道德是一个
jsp页面不是一个Action所以值栈为空,然则我们可以在ActionContext中进行取值:<s:property value="#parameters.t"/>
在接见Actoin向Action进行传值的时辰
http:www.xxxxx/ognl.action?username=u&password=p;
private String username(set get 办法)
private String password(set get 办法)
若是用这种体式格式进行传值,那么在jsp页面中可以用<s:property value="username"/>进行接见值栈中的内容,没有任何题目然则
若是:
http:www.xxxxx/ognl.action?username=u&password=p;
private User user;(set get)办法,应用<s:property value="user"/>依然接见不到,因为若是采取dominModel的体式格式进行传值
,必须:http:www.xxxxx/ognl.action?user.username=u&user.password=p;如许 Struts会在Action中帮助我们new一个User对象
,然后把值放进去,然则必必要有User空的机关办法。若是依然应用http:www.xxxxx/ognl.action?username=u&password=p;的方
式进行传值,那么在Action中必须手动的初始化User对象,Private User user = new User();如许同样可以接见的到。
Ognl:Object graph Navigation Language(对象图导航说话):起首看一下下面三个类之间的关系:
public class OgnlAsction extends ActionSupport {
private Cat cat;(set get 办法)
public String m() {
return "你好";
}
}
public class Cat {
private Dog friend;(set get 办法)
}
public Dog {
private String name;(set get 办法)
}
在OgnlAction中包含Cat,而在Cat中包含Dog的对象friend,那么如今我想接见OgnlAction的时辰,给friend肤质,我们应当这么写
:
http:www.xxxx/ognl.action?cat.friend.name=aaa; 用点进行导航,所以叫做"对象图导航说话"。
已知以下三个类中的属性和办法:
public class OgnlAsction extends ActionSupport {
private Cat cat;(set get 办法)
private String password;(set get 办法)
List<User> users = new ArrayList<User>();(set get 办法)
}
public class Cat {
private Dog friend;(set get 办法)
private String miaomiao() {
return "miaomiao";
}
}
public Dog {
private String name;(set get 办法)
}
public class S {
public static String STR = "STATIC STRING";
public static String s() {
return "static method";
}
}
(1)接见值栈中对象的通俗办法:<s:property value="password.length()"/>
(2)接见值栈中对象的通俗办法:<s:property value="cat.miaomiao()" />
(3)接见值栈中的Action的通俗属性<s:property value="username"/>
(4)接见值栈中对象的通俗属性<s:property value="user.age" />
(5)接见值栈中对象的通俗属性<s:property value="cat.friend.name" />
(6)接见值栈中Action的通俗办法<s:property value="m()" />
<!--要想接见静态办法,必须在struts.xml文件中参加如下设备才可以 -->
<constant name="struts.ognl.allowStaticMethodAccess"value="true"/>
(7)接见静态办法<s:property value="@com.bjsxt.struts2.ognl.S@s()"/>
(8)接见静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/>
(9)接见Math类的静态办法:<s:property value="@@max(2,3)" />(不常用)
(10)接见通俗类的机关办法:<s:property value="new com.bjsxt.struts2.ognl.User()"
(11)接见List:<s:property value="users"/>
(12)接见List中某个元素:<s:property value="users[1]"/>
<!--把users中的每一个元素User取出来,然后取他们的age属性连接成的字符串-->
(13)接见List中元素某个属性的凑集:<s:property value="users.{age}"/>
(14)接见List中元素某个属性的凑集中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users
[0].age"/>
(15)接见Set:<s:property value="dogs"/>
<!--下面如许接见set中的某个元素是接见不到的,因为set是没有次序的 -->
(16)接见Set中某个元素:<s:property value="dogs[1]"/>
(17)接见Map:<s:property value="dogMap"/>
(18)接见Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap[""dog101""]"/> |
<s:property value="dogMap[\"dog101\"]"/>
(19)接见Map中所有的key:<s:property value="dogMap.keys"/>
(20)接见Map中所有的value:<s:property value="dogMap.values"/>
<!--在ognl中他会把size办法算作属性,所以可以不加括号,直接接见 -->
(21)接见容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/>
<!-- ?#指的是过滤:取出users中的每个age==1的元素 [0]是取第一个,不加会全部取出来
(22)投影(过滤):<s:property value="users.{?#this.age==1}[0]"/>
<!-- ^#:开首取出满足前提的开首的那一个 -->
(23)投影:<s:property value="users.{^#this.age>1}.{age}"/>
<!-- ¥#:开首取出满足前提的结尾的那一个 -->
(24)投影:<s:property value="users.{¥#this.age>1}.{age}"/>
<!--断定 -->
(25)投影:<s:property value="users.{¥#this.age>1}.{age} == null"/>
(24)投影:<s:property value="users.{¥#this.age>1}.{age}"/>
<!-- value="[1]接见值栈中从上到下的第几个元素,而[0]指的是值栈中从开端到结尾的所有的对象,获得的是一个凑集"
[0].username:接见值栈中所有元素的username属性,若是没有此属性会依次往下找其他的Action(从一个action跳转到另一个
action的时辰值栈中会有两个action) -->
(25)[]:<s:property value="[0].username"/>
(1)property: <s:property value="username"/>
(2)property 取值为字符串: <s:property value="""username"""/>
<!--若是取到admin的值,就是admin的值不然就是default所定义的默认值 -->
(3)property 设定默认值: <s:property value="admin" default="经管员"/>
<!-- value可以直接写html标签,escape默认为true,会原样不变显示出来,false将把html标签转化为浏览器可以识此外标签,显
示响应的结果 -->
(4)property 设定HTML: <s:property value="""<hr/>""" escape="false"/>
<s:property>有三个属性,value ,escapeHtml,default,此中的value是ognl表达式
<s:set>设置变量,value ,var ,scope三个属性,此中的value是ognl表达式
<s:bean>两个属性,name,var; 都是字符串 ,履行开端new一个bean当为</s:bean>时,从栈顶移除,将不克不及应用;
<s:param>两个属性,name,value;此中的value是ognl表达式;
<s:include>包含文件,最好不消,一个属性value字符串;
Ognl表达式:¥用于struts2中的传参和i18n设备文件中;
#用于action context中取值;
%{}用于将本来的字符串属性改变成ognl,若是是ognl表达式属性就将该表达式改变成字符串
<s:fielderror>取得的值是不规矩的值,若是取到正确的值?
把握标签---两个(<s:if><s:elseif><s:else> 和<s:iterator>
<s:if>这个标签就是应用了上方所说的%{}此中括号中可以使ognl表达式,也可所以字符串
<s:iterator>标签,此中的value是ognl表达式,此中的status是个boolean,此中可以设置var属性是个字符串,是每次轮回的那个变量相当于;
遍历凑集:此中value直接可以接见,不消应用#
Status中count个数;
Status 中的index默示索引;
Status中的even默示是否是偶数;
Staus中的odd默示是否是奇数;
Status中的first默示是否是第一个元素;
Status中的last默示是否是最后一个元素;
定义map对象的时辰,必必要将加上#,这个是一个困惑,不必纠结;
获得map中的对象,.key ,.value获取相干的值;
<s:subset>默示获取此中的子凑集;
此中的source默示此中的list或者是map对象,此中的count默示获取的子凑集的大小,start默示开端的元素大小;
标签总结:
<s:property><s:set><s:bean><s:param><s:include>主如果三个标签;
此中只有一个<s:bean>应用到了name属性
Model层和service层的含义
Model:代表数据库接见层
接见action中的通俗
数据表定名:大小写;
文件的定名对应了action的应用,所以要重视