线程安全
1.多线程环境下,访问同一对象的实例变量(属性)会造成线程不安全
servlet---不是线程安全,因为它是不同的线程通过service(request,rqsponse)
访问同一个servlet容器
而struts的action
是线程安全的,里面是有属性的,且属性的名字要和form表单中的name的值
是一样的,因为struts2会调用它的setXXX和getXX方法,这个和el表达式中
的是一样的(回顾)。
action中的每次请求都会调用它的构造方法
步骤:
1.把struts的包导入lib中
2.配置中央控制器
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其中,filter-class里面的值是从web App lib中的struts2-core.jar中的org.apache.struts2.dispatcher.ng.filter包中StrutsPrepareAndExecuteFilter
3.在etc中建立一个struts.xml
(必须叫这个名字,因为读取哪个配置文件在jar中有规定)
在这个文件里加入
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
在struts2-core中的struts2.3dtd中,这句话,这句话能,配置文件怎么写,它能给提示
4.在struts。xml中写配置文件,
<struts>
<package name="mypackage" extends="struts-default"></package>
//extends属性值是struts-default。xml中找到一个<package name="struts-default" abstract="true">
这个属性值就是从这个name里来的
</struts>
下面是示例,action中的method默认的是execute可以不写,result中若是name="success"
也可以省略不写
<struts>
<package name="mypackage" extends="struts-default">
<action name="user" class="com.kaishengit.action.UserAction">
<result name="success">WEB-INF/views/user.jsp</result>
<result name="error">WEB-INF/views/error.jsp</result>
</action>
</package>
</struts>
5.修改请求的后缀
在web-App-lib中的struts-core的org.apache.struts2中的default.properities
有一句,用来设置(但是jar包中的代码不能修改)
struts.action.extension=action,,
修改方法:
01.在struts.xml中根标签下加上
<constant name="struts.action.extension" value="action,,do"/>
02.在etc中建一个struts.properties文件(一定要以这个命名)然后加上这句话
struts.action.extension=action,,
6.调用Action中指定的方法
默认的调用的是execute方法,继承的是父类?实现了Action接口
(1.public 2.String 3.名字随便起)
01.在地址栏请求的action的名字后面加上!+方法名
http://www.gzp.com/m/user!save.action (这种基本不用,很多弊端)
02.重新配置一个
<action name="usersave"
class="com.kaishengit.action.UserAction"
method="save">
<result name="success">WEB-INF/views/user.jsp</result>
<result name="error">WEB-INF/views/error.jsp</result>
</action>
method不写的时候默认的调用就是execute方法,这个时候当请求
usersave.action的时候,就会调用save方法
03.
<action name="user*"
class="com.kaishengit.action.UserAction" method="{1}">
<result name="success">WEB-INF/views/user.jsp</result>
</action>
这个在请求的时候www.gzp.com/usersave,会把*所代表的值填写到{1}中
<action name="*_*"
class="com.kaishengit.action.{1}Action" method="{2}">
<result name="success">WEB-INF/views/user.jsp</result>
</action>
这个在请求的时候www.gzp.com/User_save,会把*所代表的值User填写到{1}中,
第二个*代表的值save填写到{2}中
这种也不常用
7.写一个登陆,然后提取表单里的值
01.建立一个HomeAction类。然后配置访问login → execute,tologin-》login方法
<package name="home" extends="struts-default">
<action name="login" class="com.kaishengit.action.HomeAction">
<result>WEB-INF/views/login.jsp</result>
</action>
<action name="gologin" class="com.kaishengit.action.HomeAction" method="login">
<result>WEB-INF/views/login.jsp</result>
</action>
</package>
02.在HomeAcition中写需要从form中获取的值对应的属性,属性的名要和form
中的name=""中的值一样
这个自动生成get/set方法,需要注意的是其实struts2是自动调用的setxxx
和getxxx,和EL表达式中的类似,它在意的是set后的xx要和form中的一样
03. 按照上面两步骤做,若是一个form提交的属性很多,这个时候就会在HomeAction中
生成很的set/get方法,会很乱
这个时候可以写个实体类,如User(username,password)
只需在HomeAction中添加一个User属性,生成getset
然后在表单提交的时候,在name="username"--->改成name="user.username"
<form action="gologin.action" method="post">
USER:<input type="text" name="user.username" /><br />
PASSWORD:<input type="password" name="user.password" /><br />
<input type="submit" value="请登录" />
</form>
8. action页面跳转,userService和type,跳转类型
01.在web-App-lib中的struts-core的org.apache.struts2中的struts-default.xml中
<package name="struts-default" abstract="true">
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
</result-types>
这个里面都是跳转类型,常用的是
dispatcher, 请求转发到jsp
chain, 请求转发到action
redirect, 重定向到jsp
redirectAction 重定向到action
对于这些怎么用可以看文档,在网址struts.apache.org中
file:///E:/jar/struts2/struts-2.3.8-all/struts-2.3.8/docs/WW/result-types.html中
file:///E:/jar/struts2/struts-2.3.8-all/struts-2.3.8/docs/WW/redirect-action-result.html
02. 参数
actionName (default) - The name of the action that will be redirected to.
namespace - Used to determine which namespace the action is in that we're redirecting to.
If namespace is null, the default will be the current namespace.
suppressEmptyParameters - Optional boolean (defaults to false) that can prevent
parameters with no values from being included in the redirect URL.
parse - Boolean, true by default. If set to false, the actionName param will
not be parsed for Ognl expressions.
anchor - Optional. Also known as "fragment" or colloquially as "hash".
You can specify an anchor for a result.
示例
<package name="public" extends="struts-default">
<action name="login" class="...">
<!-- Redirect to another namespace -->
<result type="redirectAction">
<param name="actionName">dashboard</param>
<param name="namespace">/secure</param>
</result>
</action>
</package>
03. 对于地址栏里面的参数的传递,除了上面的5个参数不能乱用,有规定之外,其他的可以随便起
<result name="login" type="redirectAction">
<param name="actionName">login</param>
<param name="code">10001</param>
</result>
04. 此时有问题,若是code有很多值,就要配很多次result,
这时候在HomeAction中写一个属性code,生成get/set,然后在配置文件struts.xml中改成如下:
但是要注意${code},这个和EL表达式没有关系,并且code(小写)必须要和setXX/getXX中的xx
(首字母大写)一致
<result name="login" type="redirectAction">
<param name="actionName">login</param>
<param name="code">${code}</param>
</result>
9.namespace(地址栏的请求)
在package中加上namespace="/user",这个必须以/开头,默认的是"/"(不写的时候)
<package name="mypackage" namespace="/user" extends="struts-default">
/user/list.do
/user.do
这时,加了namespace时候,不同的namespace中的跳转要在跳转时候加上namespace参数
<result type="redirectAction">
<param name="actionName">list</param>
<param name="namespace">/user</param>
</result>
10.配置文件的分开,和jsp文件目录的分开
<include file="struts_user.xml"></include>
目录分开,在views下新建一个文件夹
11.将值传到jsp中
UserService.findAll 从数据库中获得到数据
UserAction中设置一个属性,生成set/get
调用上面的方法,把值赋给这个属性。struts2会自动在显示jsp之前,调用它的getXX
方法,在jsp上面的key就是getXX中xx这个名字。jsp显示的时候会自动根据key值来查找
getxx方法。