在Javaee开发中,我们一般将整个项目分成表现层,业务层,和持久层,在持久层就是和数据库打交道,之前的Hibernate就是属于这个层的,在表现层我们在没有框架之前是使用jsp+servlet+javabean的MVC设计模式来实现的,Struts2框架就是用来代替之前表现层的开发模式的,或者说Struts2将之前的MVC设计模式给封装了起来,注意Struts1与Struts2几乎只有名字继承了,底层的思想实现几乎不同,但是Struts2和webwork的底层思想很类似,可以说Struts2是webwork的下一代。
Struts2的必要jar包在使用Struts2之前,我们首先需要有Struts2的环境,因此需要导入必要的jar包,这些jar包在Struts2的解压缩包底下都可以找到。
Struts2的使用首先我们需要创建一个动态web工程,然后在web.xml文件中配置一下过滤标签filter
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</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 过滤标签,用来拦截所有请求,让所有请求先去执行StrutsPrepareAndExecuteFilter内的方法 注意不同版本的StrutsPrepareAndExecuteFilter所在的包可能不同 --> <filter> <filter-name>Struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- 这个可以用来一些初始参数值 <init-param> <param-name></param-name> <param-value></param-value> </init-param> --> </filter> <filter-mapping> <filter-name>Struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>在配置完web.xml之后,就要在src下创建struts.xml,这个配置文件用来将请求解析然后对应去执行不同Action类或方法
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标签用来对不同请求执行不同的action类的方法 --> <struts> <!-- 标签<constant name="" value=""></constant> constant用来改变一些参数的值 在Struts2中,当struts2一启动,会按照顺序依次加载以下文件 default.properties 存储一些键值对的常量,是不可以修改里边的值的 struts-default.xml 定义了许多拦截器,不可以修改里边的值 struts.plugin.xml 是struts2整合spring的时候用的 struts.xml 这是我们自定义的配置文件,里边的值可以修改 struts.properties 这也是可以修改的 web.xml 这里边我们也可以修改值 注意:如果有多个文件的参数相同,越后边加载的文件里的值会覆盖前面的加载的 --> <!-- package可以定义多个,在企业开发中,可以用来对应一个模块 属性:name为该包的名称,其他包继承的时候使用到 extends为该包继承的父包,一般要继承struts-default,这里边定义了许多默认拦截器 namespace为命名空间,一般与用户访问地址有关 --> <package name="test1" extends="struts-default" namespace="/"> <!-- 该标签定义全局的results,即该包中所有action都到这里定义的逻辑页面 如果action中有单独定义result标签,则以action中的为准 <global-results></global-results> --> <!-- action定义要去往那个action类 属性:name为该action的名称,与namespace一起决定用户该访问的地址, 比如这里的namespace为/,用户就得访问“工程名/hellostruts2” 如果namespace为/aaa,那么用户就得使用 “工程名/aaa/hellostruts2”来访问 class为action类的全限定名 method为该执行action类中的哪个方法,如果不写,默认执行execute()方法 --> <action name="hellostruts2" class="com.wzm.action.ActionDemo" method="execute"> <!-- result为决定转发或重定向到哪个逻辑页面,可以转发或者重定向到另一个action name为执行action中的方法后的返回值,根据返回值的不同,转发到不同的页面,不写就默认值为success 页面都得自己编写 --> <result name="success">/result.jsp</result> </action> </package> </struts>接下来就是创建一些页面以及一些Action类,Action类就类似于servlet类,是用来控制业务的,不同方法执行不同业务。
Action类和jsp页面示例 <!-- jip页面 --> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <a href="${pageContext.request.contextPath }/hellostruts2">Hello Struts2</a><br> </body> </html> /** * action类 */ public class ActionDemo { //struts.xml中定义的action默认执行execute方法 //也可以执行其他方法,不过method要改变成想要的方法名 public String execute() { return "success"; } } */#Action类的三种编写方式
/*//有三种编写action类的方法: //第一种就是编写一个普通的类,里边写自定义的方法,一般不使用 //第二种就是实现一个xwrok2包下的Action接口,接口定义了五大返回值常量,还有一个execute()方法,平时也不怎么使用 //第三种就是继承ActionSupport类,这个类实现了Action接口,还定义了许多方法,我们可以用它里边的方法,这种方式比较常用 public class ActionDemo1{ public String execute() { return null; } } public class ActionDemo2 implements Action { public String execute() throws Exception { return null; } } public class ActionDemo3 extends ActionSupport{ private static final long serialVersionUID = 1L; public String execute() { return null; } }#struts.xml中三种调用Action类方法的方式
<package name="test2" extends="struts-default" namespace="/"> <!-- 当action类中有许多方法时,我们有三种方法可以让action可以根据用户访问的不同URL执行不同的方法 第一种就是普通的方法,使用method来决定执行的方法,只是要执行多少方法就要写多少action标签来执行不同方法,比较麻烦 <action name="hello_save" class="com.wzm.action.ActionDemo" method="save"> <result name="success">/save.jsp</result> </action> <action name="hello_delete" class="com.wzm.action.ActionDemo" method="delete"> <result name="success">/delete.jsp</result> </action> 第二种就是使用通配符*来决定要执行哪个方法,具体实现如下,当*为save就执行save()方法,当*为delete时就执行delete()方法, 这样我们只需要写一个action标签就可以执行不同的方法,通配符可以写多个,{1}代表代表匹配第一个*,{2}代表匹配第二个*,我们还可以通过通配符来决定转发的页面 这里有一点需要注意的是,在2.5版本之后,struts2多了一个安全机制,如果要使用通配符必须要定义能被匹配的方法 ,要在action中使用标签<allowed-methods>save,delete</allowed-methods> <action name="hello_*" class="com.wzm.action.ActionDemo" method="{1}"> <result name="success">/{1}.jsp</result> </action> 前两种的页面访问URL为${pageContext.request.contextPath }/hello_save"或${pageContext.request.contextPath }/hello_delete" 第三种访问方式我们不需要使用method,只不过要改变访问的URL格式 ${pageContext.request.contextPath }/hello!save"或${pageContext.request.contextPath }/hello!delete" 这种方式为动态调用,当用户一访问,action标签就会让去执行和感叹号后边相同名称的方法, 注意:动态调用要在struts.xml添加一个constant标签 <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> --> </package>Servlet是单实例的,即所有访问都使用同一个Servlet对象,因此不是线程安全的,最好不要定义成员属性 Action是多实例的,一次访问生成一个Action对象,因此是线程安全的,可以定义成员属性。
