Struts2所有的jar有80多个,项目中很少全部都用到的。只要将主要的导入即可。
将一下jar复制到WEB-INF/lib目录下:
struts2-core-2.1.8.1.jar:Struts 2框架的核心类库。
xwork-core-2.1.6.jar :XWork类库,Struts 2在其上构建。
ognl-2.7.3.jar :对象图导航语言(Object Graph Navigation Language), struts2框架通过其读写对象的属性。
freemarker-2.3.15.jar :Struts 2的UI标签的模板使用FreeMarker编写
commons-logging-1.1.x.jar :ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。
commons-fileupload-1.2.1.jar 文件上传组件,2.1.6版本后需要加入此文件
commons-io-1.3.2.jar,上传文件依赖的jar包
在web.xml文件中配置struts2的核心过滤器,以启动Struts2。
定义一个类如HelloWorldActiion继承ActionSupport类,重写execute方法。
如:
publicclass HelloWorldAction extends ActionSupport {
public String execute()throws Exception {
System.out.println("执行了execute方法");
return"toHelloWorldJsp"; //返回一个字符串
}
}
Struts2默认的配置文件为struts.xml(名字固定) ,该文件需要存放在WEB-INF/classes下,可以放在是当前工程的src目录下,放其他存放源代码的文件夹下(因为都会编译输出到WEB-INF/classes目录下)。
配置如下:
xml version="1.0"encoding="UTF-8" ?>
DOCTYPE strutsPUBLIC
"-//Apache Software Foundation//DTD StrutsConfiguration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="maple"namespace="/" extends="struts-default">
<action name="helloworld"class="com.maple.action.HelloWorldAction" method="execute">
<result name="toHelloWorldJsp"type="dispatcher">/helloworld.jspresult>
action>
package>
struts>
访问的url组成:
http://localhost:8080/虚拟目录/namespace配置的值/
查看Console是否有输出。
用户请求--StrutsPrepareAndExecuteFilter--Interceptor(默认栈18个)Struts2内置的一些拦截器或用户自定义拦截器--Action---Result----html/jsp-----响应
通过解析和反射struts2的核心Filter,实例化后,并加载struts2的相关配置文件,例如:struts.xml文件,将struts.xml文件解析后,在内存中形成一个JavaBean对象,以后只需要访问内存中的JavaBean对象即可。
(在StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作,struts2读取到struts.xml的内容后,是将内容封装进javabean对象然后存放在内存中,以后用户的每次请求处理将使用内存中的数据,而不是每次请求都读取struts.xml文件)
当Web应用[重新]部署时,会加载新的struts.xml文件,去更新该内存中的JavaBean对象。
通知Web服务器,只要是/*的请求路径,都交由该Filter来处理.
将每个请求,处理类,和对应的业务方法灵活的以配置的方式出现如果请求有变化,只需更新配置文件,无需在Java类的编码。
访问action的url地址为:
http://localhost:8080/虚拟目录/namespace配置的值/name配置的值
注意:没有配置虚拟目录则不需要写。namespace默认值为/
测试1:
说明:当前项目的虚拟目录为test,namespace的值为/(即默认值)
http://127.0.0.1:8080/test/xx/yy/zz/HelloWorldAction 回车[OK]
http://127.0.0.1:8080/test/xx/yy/HelloWorldAction回车[OK]
http://127.0.0.1:8080/test/xx/HelloWorldAction回车[OK]
http://127.0.0.1:8080/test/HelloWorldAction回车[OK]
结论:框架会[自动依次]查询以下几个namespace的情况:/xx/yy/zz->/xx/yy->/xx->/
找到了就显示指定的页面,找不到,返回404。
测试2:
说明:当前项目的虚拟目录为test,namespace的值为/xx(即默认值)
http://127.0.0.1:8080/test/xx/yy/zz/HelloWorldAction回车[OK]
http://127.0.0.1:8080/test/xx/yy/HelloWorldAction回车[OK]
http://127.0.0.1:8080/test/xx/HelloWorldAction回车[OK]
http://127.0.0.1:8080/test/HelloWorldAction回车[ERROR]
name="maple"(包名,要唯一,建意将[相关的Action类]配置在同一个包下面,类似于Java中的包和类的关系)
namespace="/"(访问空间,参与请求url的组成,如果不配置,默认为/,也可以自定义eg:/maple/test)
extends="struts-default"(继承Struts2默认的包,该包定义了很多拦截器和一些其他功能,要想使用其功能,必须继承默认包,以达到扩展struts2内部的相关功能)>
name="helloworld"(访问该action的路径,和namespace一起组成访问的url,如:http://localhost:8080/虚拟目录/namespace配置的值/name配置的值)
class="com.maple.action.HelloWorldAction"(指定由哪个类来处理这个请求,即去执行哪个类指定的方法,要用全类名,因为要通过反射去创建其实例。
如果没有配置,默认的class是"com.opensymphony.xwork2.ActionSupport"并且在
method="execute"(指定执行哪个方法,如果没有配置该属性,则默认是"execute")>
name="toHelloWorldJsp"(指定方法返回的值,这里的值要和执行方法的返回值一致,否则会提示找不到,如果没有配置,默认是“success”)
type="dispatcher"(指定使用什么方式(转发,重定向)显示指定的jsp页面,如果没有配置,默认是“dispatcher”,即转发)
>/helloworld.jsp(要现实的jsp页面)
struts.properties文件和struts.xml文件一样,也要放在WEB-INF/classes目录下。
在struts2-core-2.3.1.1.jar的org.apache.struts2包下有个default.properties配置文件,大概在地84行指定了action访问时默认的扩展名(.action或不写)
struts.action.extension=action,,(两个逗号之间或空白的,说明可以不写扩展名)
要想覆盖默认的扩展名,只要在struts.properties文件中配置如下:
struts.action.extension=qq,do,haha,,
key:必须为struts.action.extension
value:定义自己想要的扩展名
在struts.xml文件中配置一个节点:
name:必须为struts.action.extension
value:定义自己想要的扩展名
注意:当struts.xml文件和struts.properties文件的扩展名都不同的情况下,struts.properties的配置起决定作用。
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法
该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开
当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开
开发模式下使用,这样可以打印出更详细的错误信息
默认的视图主题
与spring集成时,指定由spring负责action对象的创建
上传文件的大小限制
在src/目录下,只能存在一个名为struts.xml的文件,不能存放多个,此时可以将其它struts.xml文件改名,可置在任意路径下,然后在src/目录下的struts.xml文件中,能过
Struts2是线程安全的。因为每一次请求,对应一个Action实例,不会产生线程安全问题,即在Action代码中,不会出现synchronized()同步块。可以使用实例变量,是多实例的,与Servlet不同,Servlet是单实例的。
publicclass ServletAPIAction extends ActionSupport {
public String execute() throws Exception {
HttpServletRequestrequest = ServletActionContext.getRequest();//获取request对象
// HttpServletResponseresponse = ServletActionContext.getResponse(); //获取response对象
ActionContextcontext = ServletActionContext.getContext(); //这里封装了,不是直接获取HttpSession对象了
Map
ServletContextservletContext = ServletActionContext.getServletContext(); //在jsp页面中成为application
PageContextpageContext = ServletActionContext.getPageContext(); //获取PageContext对象,从这个对象上可以获取其他域对象
request.setAttribute("request_key", "request_value");
map.put("session_key", "session_value");
servletContext.setAttribute("servletcontext_key", "serlvetcontext_value");
returnSUCCESS;
}
}
>>struts2有很多内置拦截器,位defaultStack默认拦截器中有18个拦截器
>>因为在默认的18个拦截器中,有一个拦截器能将Map中的数据取得,再自动绑定HttpSession中,这样在Action中,可以少出现或完全不出现ServletAPI,达到了解耦的作用 。
>>框架自动将POST请求的中文问题解决了,在default.properties有以下代码:
struts.i18n.encoding=UTF-8,项目中,不推荐覆盖。Get请求乱码还是要自己手动处理的。
防止非法数据插入到数据库中
提倡前台(JS)和后台(Java)同时验证
>>为服务端减压
>>安全性,后台验证[相对]较前台安全
struts2是属于后台验证
setXxxxxxx()
validate()可选,需要验证时,就覆写该方法,不需要验证时,就不用写该方法
注意:如果重写了该方法(或者有validateXxx()方法),则在sttruts.xml文件的action节点下应该配置一个reuslt节点,name的值必须为input,用与指定当验证没通过时要转到的页面。
<action name="register" class="com.maple.action.UserAction"method="register">
<result name="toRegisterSuccessJsp"type="dispatcher">/register_success.jspresult>
<result name="input"type="dispatcher">/register.jspresult>
action>
validate()方式会验证所有的方法。要验证指定的方法,可以指定验证的方法名,格式:
validateXxx(),说明该方法是验证Xxx()方法的。其他方法执行执行之前不会进行验证。
XxxxActiong类中各个方法的执行顺序为:
setXxxxx() ---validateXxx() ---validate() -----Xxx()
>>如果在UserAction中,重写validate()方法的话,会验证在UserAction中的所有业务方法,即用户注册和登录都要验证。
>>如果在UserAction中,添加validateRegisterMethod()方法的话,只会验证在UserAction中的注册业务方法,即用户登录时不会验证。
>>当UserAction中,有validate(),又有validateRegisterMethod()的话,会先执行
(1)validateRegisterMethod()
(2)validate()
>>二者验证是[叠加]的效果
使用该标签取值,只能在转发的情况下,才能取到值。
也可以取得错误消息
除了具有错误消息显示,还具有回显示原信息(推荐)
<s:form action="register"method="post">
用户名:<s:textfield name="username"/><br/>
密码:<s:password name="password"/><br/>
<s:submit value="注册"/>
s:form>