Struts2学习笔记(1)
1. Strut2 开发步骤1.1建立JavaEE项目1.2导入相关jar包
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包
1.3配置核心过滤器在web.xml文件中配置struts2的核心过滤器,以启动Struts2。
<!-- 配置Struts2的主要Filter,该过滤器可以过滤所有请求 ,可以参照Struts2提供的例子-->
<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>
1.4定义一个类继承ActionSupport类定义一个类如HelloWorldActiion继承ActionSupport类,重写execute方法。
如:
publicclass HelloWorldActionextends ActionSupport {
public Stringexecute()throws Exception {
System.out.println("执行了execute方法");
return"toHelloWorldJsp"; //返回一个字符串
}
}
1.5编写Struts2的配置文件struts.xmlStruts2默认的配置文件为struts.xml(名字固定) ,该文件需要存放在WEB-INF/classes下,可以放在是当前工程的src目录下,放其他存放源代码的文件夹下(因为都会编译输出到WEB-INF/classes目录下)。
配置如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEstrutsPUBLIC
"-//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">
<actionname="helloworld"class="com.maple.action.HelloWorldAction"method="execute">
<resultname="toHelloWorldJsp"type="dispatcher">/helloworld.jsp</result>
</action>
</package>
</struts>
1.6部署到服务器并访问访问的url组成:
http://localhost:8080/虚拟目录/namespace配置的值/<action>节点name属性配置的值
查看Console是否有输出。
2.Struts2的工作流程
用户请求--StrutsPrepareAndExecuteFilter--Interceptor(默认栈18个)Struts2内置的一些拦截器或用户自定义拦截器--Action---Result----html/jsp-----响应
2.1 web.xml文件的作用
通过解析和反射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来处理.
2.2 struts.xml文件的作用
将每个请求,处理类,和对应的业务方法灵活的以配置的方式出现如果请求有变化,只需更新配置文件,无需在Java类的编码。
3.struts.xml文件配置详解3.1访问规则
访问action的url地址为:
http://localhost:8080/虚拟目录/namespace配置的值/name配置的值
注意:没有配置虚拟目录则不需要写。namespace默认值为/
3.2测试Action的访问路径规则
测试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]
3.3 <package>节点配置详解<package
name="maple"(包名,要唯一,建意将[相关的Action类]配置在同一个包下面,类似于Java中的包和类的关系)
namespace="/"(访问空间,参与请求url的组成,如果不配置,默认为/,也可以自定义eg:/maple/test)
extends="struts-default"(继承Struts2默认的包,该包定义了很多拦截器和一些其他功能,要想使用其功能,必须继承默认包,以达到扩展struts2内部的相关功能)>
<action
name="helloworld"(访问该action的路径,和namespace一起组成访问的url,如:http://localhost:8080/虚拟目录/namespace配置的值/name配置的值)
class="com.maple.action.HelloWorldAction"(指定由哪个类来处理这个请求,即去执行哪个类指定的方法,要用全类名,因为要通过反射去创建其实例。
如果没有配置,默认的class是"com.opensymphony.xwork2.ActionSupport"并且在<action>标签中必须添加<result>子标签,name属性必须为"success"才可以正常访问)
method="execute"(指定执行哪个方法,如果没有配置该属性,则默认是"execute")>
<result(当执行方法的返回值为null时,可以不配置该节点)
name="toHelloWorldJsp"(指定方法返回的值,这里的值要和执行方法的返回值一致,否则会提示找不到,如果没有配置,默认是“success”)
type="dispatcher"(指定使用什么方式(转发,重定向)显示指定的jsp页面,如果没有配置,默认是“dispatcher”,即转发)
>/helloworld.jsp(要现实的jsp页面)</result>
</action>
</package>
4.自定义Action访问时的扩展名4.1通过配置文件(struts.properties)定义
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:定义自己想要的扩展名
4.2通过struts.xml文件配置在struts.xml文件中配置一个节点:
<constantname="struts.action.extension" value="action,qq,,"/>(是<struts>的子节点)
name:必须为struts.action.extension
value:定义自己想要的扩展名
注意:当struts.xml文件和struts.properties文件的扩展名都不同的情况下,struts.properties的配置起决定作用。
4.3常量节点介绍:<constant>
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法
<constant name="struts.i18n.encoding"value="UTF-8"/>
该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开
<constant name="struts.action.extension"value="do"/>
当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开
<constant name="struts.configuration.xml.reload"value="true"/>
开发模式下使用,这样可以打印出更详细的错误信息
<constant name="struts.devMode" value="true"/>
默认的视图主题
<constant name="struts.ui.theme" value="simple"/>
与spring集成时,指定由spring负责action对象的创建
<constant name="struts.objectFactory"value="spring" />
上传文件的大小限制
<constant name="struts.multipart.maxSize" value=“10701096"/>
5.指定多个struts配置文件在src/目录下,只能存在一个名为struts.xml的文件,不能存放多个,此时可以将其它struts.xml文件改名,可置在任意路径下,然后在src/目录下的struts.xml文件中,能过<include>标签,加载其它struts.xml文件,这些文件都会在部署时,一次性加载到内存,形成JavaBean对象。
6.Struts2的安全问题Struts2是线程安全的。因为每一次请求,对应一个Action实例,不会产生线程安全问题,即在Action代码中,不会出现synchronized()同步块。可以使用实例变量,是多实例的,与Servlet不同,Servlet是单实例的。
7.Struts2中和Serlvet相关的API
publicclass ServletAPIActionextends ActionSupport {
public String execute()throws Exception {
HttpServletRequestrequest = ServletActionContext.getRequest();//获取request对象
// HttpServletResponseresponse = ServletActionContext.getResponse(); //获取response对象
ActionContextcontext = ServletActionContext.getContext(); //这里封装了,不是直接获取HttpSession对象了
Map<String,Object> map= context.getSession();
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;
}
}
7.1 getSession()为什么返回Map>>struts2有很多内置拦截器,位defaultStack默认拦截器中有18个拦截器
>>因为在默认的18个拦截器中,有一个拦截器能将Map中的数据取得,再自动绑定HttpSession中,这样在Action中,可以少出现或完全不出现ServletAPI,达到了解耦的作用 。
>>框架自动将POST请求的中文问题解决了,在default.properties有以下代码:
struts.i18n.encoding=UTF-8,项目中,不推荐覆盖。Get请求乱码还是要自己手动处理的。
8.Struts2数据格式验证8.1为什么要验证防止非法数据插入到数据库中
提倡前台(JS)和后台(Java)同时验证
>>为服务端减压
>>安全性,后台验证[相对]较前台安全
8.2验证的过程struts2是属于后台验证
setXxxxxxx()
validate()可选,需要验证时,就覆写该方法,不需要验证时,就不用写该方法
注意:如果重写了该方法(或者有validateXxx()方法),则在sttruts.xml文件的action节点下应该配置一个reuslt节点,name的值必须为input,用与指定当验证没通过时要转到的页面。
<actionname="register"class="com.maple.action.UserAction"method="register">
<resultname="toRegisterSuccessJsp"type="dispatcher">/register_success.jsp</result>
<resultname="input"type="dispatcher">/register.jsp</result><!--如果该方法是要被验证的,则必须配置一个result节点,且name=“input” -->
</action>
validate()方式会验证所有的方法。要验证指定的方法,可以指定验证的方法名,格式:
validateXxx(),说明该方法是验证Xxx()方法的。其他方法执行执行之前不会进行验证。
XxxxActiong类中各个方法的执行顺序为:
setXxxxx() ---validateXxx() ---validate() -----Xxx()
8.3如何验证>>如果在UserAction中,重写validate()方法的话,会验证在UserAction中的所有业务方法,即用户注册和登录都要验证。
>>如果在UserAction中,添加validateRegisterMethod()方法的话,只会验证在UserAction中的注册业务方法,即用户登录时不会验证。
>>当UserAction中,有validate(),又有validateRegisterMethod()的话,会先执行
(1)validateRegisterMethod()
(2)validate()
>>二者验证是[叠加]的效果
9. struts2常用标签总结<s:property value="username"/>取得Action类中username的属性值,必须提供getUsername()方法。
使用该标签取值,只能在转发的情况下,才能取到值。
<s:fielderror/>自动取得所有出错消息,fieldName属性只取出某个错误消息
也可以取得错误消息
<s:form>
<s:textfield/>
除了具有错误消息显示,还具有回显示原信息(推荐)
<s:submit/>
<!-- action直接写要访问的路径的名称就可以,不用再写/ -->
<s:formaction="register"method="post">
用户名:<s:textfieldname="username"/><br/>
密码:<s:passwordname="password"/><br/>
<s:submit value="注册"/>
</s:form>