Struts2框架的学习路线
第一天:Struts2的概述、Struts2的入门、Struts2常见的配置、Struts2的Action的编写
第二天:Struts2的数据的封装、结果页面配置
第三天:Struts2的值栈和OGNL表达式
第四天:Struts2的标签库
主要处理你的请求和响应的
三、Struts2的入门
1、下载Struts2的开发环境
http://struts.apache.org/
2、解压Struts2开发包
apps :Struts2提供的应用,war文件:web项目打成war包(java 项目打包为 jar 包)。直接放入到tomcat可以允许。
docs :Struts2的开发文档和API
lib :Strtus2框架的开发的jar包(实际上用不到这么多)
src :Struts2的源码(开源框架)
3、创建web项目,引入jar包
引入jar包
struts-blank项目(apps 文件目录下的测试项目)下找jar包,将这个项目拖到 tomcat 里面
里面的 log4j 版本是2.x的版本,需要 XML 方式的配置文件。不管,或者引入原来版本的 log4j(1.x),把属性文件拿过来就可以了。
不需要操作,激动加入到构建路径当中。
4、创建一个JSP页面
里面提供一个连接,点击连接,访问到 Strts2。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title heretitle> head> <body> <h1>Struts2的入门h1> <h3><a href="${ pageContext.request.contextPath }/hello.action">Struts2的入门a>h3> body> html>
Struts2有一个默认的扩展名.action。
5、编写Action的类
当点击链接的时候,需要访问到Struts2里面的一个类。
这个 Action 类相当于用来处理用户请求,作响应的。
package com.itheima.struts.demo1; /** * Struts2的入门的Action类 * @author jt */ public class HelloAction { /** * 提供一个方法: * * 方法签名固定的 * 共有的 返回值是String类型 方法名execute 在这个方法中不能传递参数。 */ public String execute(){ System.out.println("HelloAction执行了..."); return null; } }
原来在编写Servlet的时候,你的类需要去继承HttpServlet。在Struts2里面,你的 Action 类,可以不用去继承任何的类或实现任何接口。一访问它,肯定执行它里面的某个方法。所以它里面需要去提供一个方法,方法签名是固定的(public),public需要返回一个String类型的,方法名execute。方法里没有任何的参数,可以先返回一个null,不至于报错。
为什么这么做,因为Struts2底层肯定要反射执行这个方法。你想要反射执行这个方法的话,里面如果有参数,它不知道你是什么参数。想要反射,必须知道你的参数是什么,所以里面是不能传递任何参数的。
6、对Action进行配置
在src下创建(提供)名称叫做struts.xml的配置文件(在提供的空的项目,在 classes 目录下有一个)
什么路径下的能弄到 classes 下,src 下的东西最后会被编译到WEB-INF下的 classes目录下。
包名称可以随便写,但是同一个配置里,不能出现报名一样的。struts-default 继承的实际上是Struts2提供的,在引入的jar包里面,有一个Struts2核心jar包,路径下有一个Struts-default.xml,在这个文件里面,它有一个包,名字叫做Struts-default,实际上继承的是这个。只有继承了它以后,才会有Struts2里 Action 的一些功能。
Action 标签的 name 属性需要跟访问的路径相对应,把后缀名去掉就可以了;class 属性的值是这个Action类的全路径。
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="demo1" extends="struts-default" namespace="/"> <action name="hello" class="com.itheima.struts.demo1.HelloAction" > action> package> struts>
7、配置前端控制器(核心过滤器)
Action 类配置好了,还不能运行,好少一个前端控制器。没有前端控制器的话,没办法去执行 Action,因为这些功能,都是由前端控制器提供的。他会根据你具体的情况,发到不同的 Action,是由一个过滤器来实现的。
在 web.xml 文件里配置核心过滤器
xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>struts2_day01display-name> <welcome-file-list> <welcome-file>index.htmlwelcome-file> <welcome-file>index.htmwelcome-file> <welcome-file>index.jspwelcome-file> <welcome-file>default.htmlwelcome-file> <welcome-file>default.htmwelcome-file> <welcome-file>default.jspwelcome-file> welcome-file-list> <filter> <filter-name>struts2filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class> 、 filter> <filter-mapping> <filter-name>struts2filter-name> <url-pattern>/*url-pattern> filter-mapping> web-app>
8、改写 Action 中的方法的返回值
通常点完一个链接以后,需要处理数据,处理完以后还要给页面作响应,这时候就跟 return 的值有关。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title heretitle> head> <body> <h1>Struts2的入门h1> <h3><a href="${ pageContext.request.contextPath }/hello.action">Struts2的入门a>h3> body> html>
9、 改写struts.xml
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="demo1" extends="struts-default" namespace="/"> <action name="hello" class="com.itheima.struts.demo1.HelloAction" > <result name="success">/demo1/success.jspresult> action> package> struts>
10、编写success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title heretitle> head> <body> <h1>跳转成功页面!!!h1> body> html>
四、Struts2的执行流程
当用户访问某一个Action的时候,先经过核心过滤器,在核心过滤器中执行一组拦截器(这组拦截器实现部分功能),执行目标Action,根据Action的返回值,进行页面跳转。
五、Struts2的常见配置
1、 配置XML的提示
2、Struts2的配置文件的加载顺序(了解)
2.1、Struts2的配置文件加载顺序
在 Struts2 好多地方都可以去配置它的常量,但是配置完那个会生效呢?这就跟加载顺序有关了
作为一个框架,他的配置文件什么时候加载呢?怎么加载呢?它的核心是过滤器,那么过滤器什么时候被创建呢?服务器只要一启动,过滤器就会被创建;过滤器一被创建,它里面的 init 方法会被执行。
init_DefaultProperties() ----加载default.properties
init_TraditionalXmlConfigurations(); ----加载struts-default.xml、struts-plugin.xml、struts.xml
init_LegacyStrutsProperties(); ----加载struts.properties
init_CustomConfigurationProviders(); ----加载配置提供类
init_FilterInitParameters() ; // [6] ----加载web.xml中过滤器初始化参数
init_AliasStandardObjects() ; // [7] ----加载Bean对象
2.2、加载顺序
default.properties
struts-default.xml
struts-plugin.xml
truts.xml
struts.properties
web.xml
注意:后配置的常量的值会覆盖先配置的常量的值。
前三个是 Struts2 框架去提供的配置文件,后面三个配置文件里面都可以配置 Struts2 的常量。如果要配置 Struts2 的常量,需要注意后配置的常量的值会覆盖先配置的常量的值。比如字符集设置...
只和常量配置有关
3、Action的配置
3.1、
package 标签称为包,这个包与Java中的包的概念不一致。包为了更好管理action的配置。
package 属于根标签下的最顶层标签
package标签的属性
① name :包的名称,只有在一个项目中不重名即可。
② extends :继承哪个包,通常值为struts-default。
③namespace :名称空间,与
名称空间有三种写法:
带名称的名称空间 :namespace=”/aaa”(/aaa/hello)
根名称空间 :namespance=”/”(/hello)
默认名称空间 :namespace=””
是有访问顺序,先访问带名称 的名称空间包里的路径,没有再访问根名称空间的包里的路径,没有的话最后访问默认名称空间的包里的路径。
④ abstract :(抽象的包)抽象的,用于其他包的继承。
这个包可以被继承,所以我们可以去继承。
3.2、
action 标签配置Action类。
action标签的属性
name :与namespace共同决定访问路径
class :Action类的全路径
method :执行Action中的哪个方法的方法名,默认值 execute
converter :用于设置类型转换器
自定义类型转换的,在 Struts2 中,类型转换的工作,底层提供的已经够用。
4、Struts2的常量配置
在Struts2的框架中,提供了非常多的常量:(在default.properties)
struts.i18n.encoding=UTF-8 ----Struts2中所有的post请求的中文乱码不用处理。
struts.action.extension=action,, ----Struts2请求的默认的扩展名。默认扩展名是.action或者什么都不写。
在Struts2中修改一些常量的值:
修改常量的值,可以有三个位置进行修正:(常量修改一般放在上面,一打开配置文件就可以看到修改了那些常量)
struts.xml中进行修改
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.action.extension" value="action"/> <include file="com/itheima/struts/demo1/struts_demo1.xml"/> <include file="com/itheima/struts/demo2/struts_demo2.xml"/> <include file="com/itheima/struts/demo3/struts_demo3.xml"/> struts>
struts.properties中进行修改(在 src 目录下新建,此文件只能修改常量 )
web.xml中进行修改(通过过滤器的初始化参数修改)
xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>struts2_day01display-name> <welcome-file-list> <welcome-file>index.htmlwelcome-file> <welcome-file>index.htmwelcome-file> <welcome-file>index.jspwelcome-file> <welcome-file>default.htmlwelcome-file> <welcome-file>default.htmwelcome-file> <welcome-file>default.jspwelcome-file> welcome-file-list> <filter> <filter-name>struts2filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class> filter> <filter-mapping> <filter-name>struts2filter-name> <url-pattern>/*url-pattern> filter-mapping> web-app>
虽然最后加载的文件里修改的常量回生效,但习惯于在 struts.xml 文件里面修改。
5、分模块开发的配置
5.1、include的配置(src\com\itheima\struts\demo1)
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="demo1" extends="struts-default" namespace="/"> <action name="hello" class="com.itheima.struts.demo1.HelloAction" > <result name="success">/demo1/success.jspresult> action> package> struts>
在主配置文件里面特别清晰,引入其他路径下的配置文件。
6、Action的访问
6.1、 Action的写法
写一个 Action 类,能被 Struts2 识别,并且能够访问执行,有三种方法。
6.1.1、 Action类是POJO的类
没有继承任何类,没有实现任何接口。
package com.itheima.struts.demo2; /** * Action的编写方式:Action类是一个POJO的类 * @author jt * */ public class ActionDemo1 { public String execute(){ System.out.println("ActionDemo1执行了..."); return null; } }
6.1.2、Action类实现一个Action的接口
package com.itheima.struts.demo2; import com.opensymphony.xwork2.Action; /** * Action的编写方式二:实现一个Action的接口 * * 实现接口的这种方式:提供了五个常量(五个逻辑视图的名称) * * SUCCESS :成功 * * ERROR :失败 * * LOGIN :登录出错页面跳转 * * INPUT :表单校验的时候出错(内部拦截器会用到,值不可以改变) * * NONE :不跳转 * @author jt * */ public class ActionDemo2 implements Action{ @Override public String execute() throws Exception { System.out.println("ActionDemo2执行了..."); return NONE; } }
6.1.3、Action类继承 ActionSupport 类(推荐使用)
重写 execute 方法,父类方法默认返回 susses。
package com.itheima.struts.demo2; import com.opensymphony.xwork2.ActionSupport; /** * Action的编写方式三:Action类继承ActionSupport类 * * 推荐使用继承ActionSupport方式 * * ActionSupport中提供了数据校验、国际化等一系列操作的方法。 * @author jt * */ public class ActionDemo3 extends ActionSupport{ @Override public String execute() throws Exception { System.out.println("ActionDemo3执行了..."); return NONE; } }
ActionSupport 里面有很多功能(数据校验、逻辑化等一些国际化的操作) ,实现了 Action 类。
数据校验在 Struts2 里面也都不用了,应为在后面会 WebServices,就是异步系统之间的调用。就是可以通过 php 的系统调用 Java 的系统,或者是通过 Java 系统调用到 .net 系统里面的一些东西。其实是没有经过 web 层的,Struts2 里面提供的校验是 Web 层的校验,但是往往会直接调用到里面 业务层的东西,那些校验就应该在业务层做,尤其是那种异步系统之间的交互。
如果说就一套页面,就用 Struts2 来实现,那你可以有 Struts2 内部的校验机制。但是,随着以后项目的越来越大,扩展起来就很麻烦了。比如说做个网站,网站上想显示一下天气预报的信息,自己建个字段,日期、天气...看气象局网站上报了多少度,自己网站上填多少度,这样肯定不行。需要那边显式多少度,这边也显示多少度,而且是程序自己去做的。哪你的网站是 Java 写的,气象局的网站一定得是 Java 的吗?不一定,它有可能是 .net,有可能是 php,所以说就涉及很多这个情况下的异步系统之间调度的问题。那么这个时候,数据是否有效就不能在 web 层进行校验了,就得在业务层。
6.2 Action的访问
之前通过 struts.xml 一配置,就可以访问了。这种访问方式太 low 了,这不又回答 selvet 那段了。有一个请求对应一个类,在实际开发中,应该让一个模块的所有请求访问一个类。比如说用户的登录、用户的注册,都应该往一个 Action 里面去执行的,但是它应该是访问不同的方法,执行 Action 里面不同的方法。这个时候就涉及到 Action 访问的问题了
demo1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title heretitle> head> <body> <h1>Action的访问h1> <h3>通过method方式h3> <a href="${ pageContext.request.contextPath }/userFind.action">查询用户a><br/> <a href="${ pageContext.request.contextPath }/userUpdate.action">修改用户a><br/> <a href="${ pageContext.request.contextPath }/userDelete.action">删除用户a><br/> <a href="${ pageContext.request.contextPath }/userSave.action">保存用户a><br/> <h3>通过通配符的方式h3> <a href="${ pageContext.request.contextPath }/product_find.action">查询商品a><br/> <a href="${ pageContext.request.contextPath }/product_update.action">修改商品a><br/> <a href="${ pageContext.request.contextPath }/product_delete.action">删除商品a><br/> <a href="${ pageContext.request.contextPath }/product_save.action">保存商品a><br/> <h3>通过动态方法访问的方式h3> <a href="${ pageContext.request.contextPath }/customer!find.action">查询客户a><br/> <a href="${ pageContext.request.contextPath }/customer!update.action">修改客户a><br/> <a href="${ pageContext.request.contextPath }/customer!delete.action">删除客户a><br/> <a href="${ pageContext.request.contextPath }/customer!save.action">保存客户a><br/> body> html>
6.2.1、通过method设置
虽然可以实现,但是还是需要配置好几个。
UserAction.java
package com.itheima.struts.demo3; import com.opensymphony.xwork2.ActionSupport; public class UserAction extends ActionSupport{ public String find(){ System.out.println("查询用户..."); return NONE; } public String update(){ System.out.println("修改用户..."); return NONE; } public String delete(){ System.out.println("删除用户..."); return NONE; } public String save(){ System.out.println("保存用户..."); return NONE; } }
struts_demo3.xml
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="demo3" extends="struts-default" namespace="/"> <action name="userFind" class="com.itheima.struts.demo3.UserAction" method="find">action> <action name="userUpdate" class="com.itheima.struts.demo3.UserAction" method="update">action> <action name="userDelete" class="com.itheima.struts.demo3.UserAction" method="delete">action> <action name="userSave" class="com.itheima.struts.demo3.UserAction" method="save">action> <action name="product_*" class="com.itheima.struts.demo3.ProductAction" method="{1}">action> <action name="customer" class="com.itheima.struts.demo3.CustomerAction">action> package> struts>
6.2.2、通过通配符的方式进行配置(开发经常会用)
访问路径中要包含需要执行的方法。
ProductAction.java
package com.itheima.struts.demo3; import com.opensymphony.xwork2.ActionSupport; public class ProductAction extends ActionSupport { public String find(){ System.out.println("查询商品..."); return NONE; } public String update(){ System.out.println("修改商品..."); return NONE; } public String delete(){ System.out.println("删除商品..."); return NONE; } public String save(){ System.out.println("保存商品..."); return NONE; } }
struts_demo3.xml
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="demo3" extends="struts-default" namespace="/"> <action name="userFind" class="com.itheima.struts.demo3.UserAction" method="find">action> <action name="userUpdate" class="com.itheima.struts.demo3.UserAction" method="update">action> <action name="userDelete" class="com.itheima.struts.demo3.UserAction" method="delete">action> <action name="userSave" class="com.itheima.struts.demo3.UserAction" method="save">action> <action name="product_*" class="com.itheima.struts.demo3.ProductAction" method="{1}">action> <action name="customer" class="com.itheima.struts.demo3.CustomerAction">action> package> struts>
6.2.3、动态方法访问
默认情况下,动态方法访问是关闭的。
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
CustomerAction.java
package com.itheima.struts.demo3; import com.opensymphony.xwork2.ActionSupport; public class CustomerAction extends ActionSupport { public String find(){ System.out.println("查询客户..."); return NONE; } public String delete(){ System.out.println("删除客户..."); return NONE; } public String update(){ System.out.println("修改客户..."); return NONE; } public String save(){ System.out.println("保存客户..."); return NONE; } }
struts_demo3.xml
xml version="1.0" encoding="UTF-8" ?> DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="demo3" extends="struts-default" namespace="/"> <action name="userFind" class="com.itheima.struts.demo3.UserAction" method="find">action> <action name="userUpdate" class="com.itheima.struts.demo3.UserAction" method="update">action> <action name="userDelete" class="com.itheima.struts.demo3.UserAction" method="delete">action> <action name="userSave" class="com.itheima.struts.demo3.UserAction" method="save">action> <action name="product_*" class="com.itheima.struts.demo3.ProductAction" method="{1}">action> <action name="customer" class="com.itheima.struts.demo3.CustomerAction">action> package> struts>