Struts2框架基础

时间:2022-02-21 05:24:25

Struts2框架基础

1.Java的框架

1.1.框架简介

在大型项目开发过程中,经常会使用到一些框架,这样做好的好处是能够提高工作效率,在java中最常用的的框架就是SSH,这其实是三个框架的简称。

java web的开发也是遵循着MVC模式,从jsp代表的视图层,到servlet代表的控制层,service代码的逻辑层和dao代表的数据库层,通过一些框架,使其能够提供更加快捷的开发

框架在软件中其实就是一种半成品,有些功能已经实现了,这样,当我们的项目开发建立在框架上时,就可以提高开发效率

SSH框架在MVC模式中的位置及其作用:

Struts2框架基础

这三个框架都将要学习

1.2.Struts2框架

struts框架是对应servlet控制层的框架,使用这个框架将用action取代servlet。

struts1最早是一种基于MVC模式的框架

struts2是在struts1的基础上,融合了xwork的功能,也就是说:Struts2 = struts1 + xwork

struts2框架预先实现了一些功能:

1.请求数据自动封装

2.文件上传的功能

3.对国际化功能的简化

4.数据效验功能

5.………………

2.Struts2开发流程

本处使用struts2的版本是2.3

2.1.引入jar文件

使用struts2要引入的jar文件比较多,必须引用的有八种,可以单独引用,如果是使用idea创建struts2时,可以选择下载或者执行的包含这些jar的包

必须要引入的八种jar是:

  • commons-fileupload-1.2.2.jar 【和io一起是文件上传的相关包】
  • commons-io-2.0.1.jar
  • struts2-core-2.3.4.1.jar 【struts2核心功能包】
  • xwork-core-2.3.4.1.jar 【xwork核心包】
  • ognl-3.0.5.jar 【ognl表达式功能支持包】
  • commons-lang3-3.1.jar 【struts对java.lang包的扩展】
  • freemarker-2.3.19.jar 【struts的标签模板jar文件】
  • javassist-3.11.0.GA.jar 【struts对字节码的处理相关jar 】

2.2.配置web.xml

初始化struts核心功能:

Tomcat启动时会加载自身的web.xml文件,然后加载项目所需的web.xml

Struts通过在项目的web.xml引入过滤器来完成Struts的核心功能的初始化。即Struts核心功能的初始化是通过过滤器来完成的。

前面有文章说过过滤器的方法(init,doFilter,destory)

注意过滤器写的是.StrutsPrepareAndExecuteFilte这个类,struts1.8之前也使用过其他的类,但现在一般都是.StrutsPrepareAndExecuteFilte

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 引入struts核心过滤器 -->
<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>
</web-app>

2.3.开发Action

action类,也叫作动作类,一般继承ActionSupport类,即处理请求的类,Struts中的action类取代了之前的servlet

在写action类中的业务方法来处理具体请求时,要注意以下两个方面:

1.业务方法必须返回String

2.方法不能有参数

代码示例:

package action;

import com.opensymphony.xwork2.ActionSupport;

/**
* 开发action,处理请求
* Created by cenyu on 16-12-22.
*/
public class HelloAction extends ActionSupport {
//处理请求
@Override
public String execute() throws Exception {
System.out.println("访问到了action,正在处理请求");
System.out.println("调用service");
return "success";
}
}

2.4.配置struts.xml

如果是用IDEA自动创建的Struts项目,则会自动创建struts.xml文件,如果不是就要在项目的src目录下创建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="hello" namespace="/" extends="struts-default">
<action name="hello" class="action.HelloAction" method="execute">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>

2.5.Struts2执行流程

首先是服务器启动:

1.加载项目web.xml

2.web.xml的StrutsPrepareAndExecuteFilter过滤器被初始化,初始化过程中执行该类的init()方法,该方法中又会初始化以下几个配置文件:

struts-default.xml, 核心功能的初始化

struts-plugin.xml, struts相关插件

struts.xml, 用户编写的配置文件

如果要在该文件中创建另外的拦截器,则放在Struts的核心过滤器上面

服务器启动之后开始访问资源,继续执行以下步骤:

3.用户访问Action,服务器根据访问路径名称,找对应的action配置,创建action对象

4.执行默认拦截器栈中定义的18个拦截器

5.执行action的业务处理方法

注意:上面过滤器和action的执行顺序是:创建action-->拦截器-->业务处理方法

struts-default.xml配置文件

该配置文件目录在struts的核心包里面:struts2-core.jar/struts-default.xml

分析该文件内容:

1.bean节点指定struts在运行的时候创建的对象类型

    <bean type="com.opensymphony.xwork2.security.ExcludedPatternsChecker" name="struts" class="com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker" scope="default" />

2.指定struts-default包(用户写的package(struts.xml)一样要继承此包)

package struts-default包定义了:

a.跳转的结果类型

  • dispatcher 转发,不指定默认为转发
  • redirect 重定向
  • redirectAction 重定向到action资源
  • stream (文件下载的时候用)
<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-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
</result-types>

b.定义所有的拦截器

  • 定义了32个拦截器

    为了拦截器引用方便,可以通过定义栈的方式引用拦截器,此时如果引用了栈,栈中的连接器都会被引用
  • defaultStack,默认的栈,其中定义默认要执行的18个拦截器
 <interceptors>
<interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
<interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
</interceptors>
<default-interceptor-ref name="defaultStack"/>

c.默认执行的拦截器栈,默认执行的action

	<default-interceptor-ref name="defaultStack"/>
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
<interceptor
name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor
name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

拦截器与过滤器的区别:

拦截器和过滤器的功能是类似的

共同点:

都拦截资源!

区别:

过滤器,拦截器所有资源都可以; (/index.jsp/servlet/img/css/js)

拦截器,只拦截action请求。

过滤器是servlet的概念,可以在struts项目、servlet项目用。

拦截器是struts的概念,只能在struts中用。

3.Struts配置详解

3.1.Struts.xml文档结构

package 定义一个包,作用是管理action,通常,一个业务模块用一个包;例如用户user包,订单包等等

  • name是包的名字,包名不能重复,否则启动就出报错;
  • extends 当钱包继承自那个包,在struts中,包一定要继承struts-default,struts-default在struts核心jar中的struts-default.xml中定义的包
  • abstract表示当前包为抽象包,抽象包不能有action的定义,否则运行时期报错, 只有当前的包被其他包继承时才能用abstract=true;
  • namespace 名称空间,默认为“/”,作为路径的一部分

最终的访问路径:http://localhost:8080/项目/名称空间/action的name值

action 配置请求路径与Action类的映射关系

  • name 请求路径名称
  • class 请求处理的action类的全名
  • method 请求处理方法

result

  • name action处理方法返回值
  • type 跳转的结果类型
  • 标签体中指定跳转的页面

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="hello" namespace="/" extends="struts-default">
<action name="hello" class="action.HelloAction" method="execute">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>

最佳实践方式是可以将配置文件放在不同的包下,如登录的配置文件就放在登录的包下,地址的配置文件就放在地址的包下,每个包下的配置文件的写法只需要写自己的那部分,其他部分的不用写,具体配置的写法跟上面是一样的。

然后在src/struts.xml的总配置文件中使用include将各个配置文件引入进来,总的配置文件的写法如下:

<?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>
<!--struts在运行时候会加载这个总配置文件:src/struts.xml--> <!--总配置文件中引入其他所有的配置文件-->
<include file="action/login.xml"></include>
<include file="add/address.xml"></include>
</struts>

3.2.Struts2的action开发的几种方式

方式一继承ActionSupport

package a_config;

import com.opensymphony.xwork2.ActionSupport;

/**
* 对action开发方式一:
* 使用继承ActionSupport类开发action
*/
public class UserAction extends ActionSupport{ //Action中的业务处理方法
public String login(){
System.out.println("UserAction.login");
return "success";
}
}

注意:如果要用Struts的数据效验功能,必须继承此类

方式二:实现Action接口(com.opensymphony.xwork2.Action)

Action接口的源码如下:

public interface Action {
String SUCCESS = "success";
String NONE = "none";
String ERROR = "error";
String INPUT = "input";
String LOGIN = "login"; String execute() throws Exception;
}

使用Action接口实现action类的方式是:

package a_config;

import com.opensymphony.xwork2.Action;

/**
* 对action开发方式二:
* 使用实现Action接口开发action类
*/
public class UserAction2 implements Action{
public String login(){
System.out.println("UserAction2.login");
return SUCCESS;
}
public String execute() throws Exception {
return null;
}
}

方式三:不继承任何类,不实现任何接口

此方式就是直接写类,不继承不实现,配置文件没有变化,使用这种方式时,拦截器对请求数据的自动封装仍然有效

package a_config;

/**
* 对action开发方式三:
* 不继承任何类,不实现任何接口
*/
public class UserAction3 {
public String login(){
System.out.println("UserAction2.login");
return "success";
}
}

注意,三种方法中,经常使用的是第一种继承的方式

3.3.通配符

在Struts的配置信息中,可以用*与{1}来优化配置!

<?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="config" namespace="/user" extends="struts-default" abstract="false">
<!--当一个action类中有不同的业务处理方法时-->
<!--<action name="login" class="a_config.UserAction" method="login">-->
<!--<result name="success">/index.jsp</result>-->
<!--</action>--> <!--<action name="register" class="a_config.UserAction" method="register">-->
<!--<result name="success">/index.jsp</result>-->
<!--</action>--> <!--使用通配符优化上面的步骤操作-->
<action name="user_*" class="a_config.UserAction" method="{1}">
<result name="{1}">/{1}.jsp</result>
</action>
</package>
</struts>

3.4.Struts中路径匹配原则

在上面修改的struts.xml配置文件中,名称空间(namespace)设置的为:/user。action的访问名称(action下的name)为“user_*"。则

访问路径:http://localhost:8080/Struts02/user/user_login 成功

访问路径:http://localhost:8080/Struts02/user/a/b/user_login 成功

访问路径:http://localhost:8080/Struts02/a/b/user_login 失败

Tomcat路径分析:

localhost:找到访问那一台机器

8080:找到tomcat

Struts02: 找到项目名称

/user/a/b: 先看有没有这个名称空间,没找到,继续向下,找到就返回

/user/a : 再看有没有这个名称空间,没找到,继续向下,找到就返回

/user : 再看有没有这个名称空间,没找到,继续向下,找到就返回

/ : 默认名称空间,还没找到,报错! 找到就返回

所以struts中的路径中,名称空间和action名称之间可以多出几个路径,也可以访问到资源,开发的时候要注意这个问题

3.5.Struts常量

Struts中默认访问后缀

struts1中默认访问后缀 *.do

struts2中默认访问后缀 *.action

这个后缀平常可以省略,在xml配置文件中不可以写,在jsp脚本中的链接可以写

如何修改默认访问后缀:

1.Struts2的.action访问后缀在哪里定义呢?

定义后缀的配置文档在:struts2-core-2.3.4.1.jar!/org/apache/struts2/default.propertiesstruts.action.extension=action,,指定

2.修改方式

修改的话不用在default.propertiesh中修改,直接在项目struts.xml配置文件中修改对应的全局变量就可以了

此处修改为指定访问后缀为action/do/没有访问后缀都可以。

要注意后面的逗号是不能少的

<?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> <!--1.全局配置-->
<!--修改Struts默认的访问后缀-->
<constant name="struts.action.extension" value="action,do,"></constant> <!--2.总配置文件,引入其他所有配置文件--> <include file="a_config/struts.xml"></include>
</struts>

对于上面修改后缀名称的时候:

value="action,do," : 后缀可以使用action或do或不带后缀

value="action,do" : 后缀只能使用action或do后缀

其他一些常用的全局变量,可以现在一个constant.xml常量配置文件中定义好,然后在总是的src/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> <!--一.全局配置常量-->
<!--1.指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出-->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!--2.自定义后缀修改常量-->
<constant name="struts.action.extension" value="action,do,"/>
<!--3.设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭-->
<constant name="struts.serve.static.browserCache" value="false"/>
<!--4.当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开-->
<constant name="struts.configuration.xml.reload" value="true"/>
<!--4.开发模式下使用,这样可以打印出更详细的错误信息-->
<constant name="struts.devMode" value="true" />
<!--5.默认的视图主题-->
<constant name="struts.ui.theme" value="simple" />
<!--6.与spring集成时,指定由spring负责action对象的创建-->
<constant name="struts.objectFactory" value="spring" />
<!--7.该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性默认为 false-->
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
<!--8.上传文件的大小限制-->
<constant name="struts.multipart.maxSize" value="10701096"/> </struts>

动态方法调用语法:

actionName+!+业务处理方法名。即为动态方法调用

3.6.全局配置,配置的各项默认值

1.配置全局跳转视图:

例如当返回值都是success全部要返回到一个指定的页面index.jsp时,可以使用全局配置。

<?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="config" namespace="" extends="struts-default" abstract="false">
<!--配置全局跳转视图-->
<global-results>
<result name="success">/index.jsp</result>
</global-results> <action name="login" class="a_config.UserAction" method="login">
<result name="success">/index.jsp</result>
</action> <action name="register" class="a_config.UserActio2n" method="register">
<!--返回结果标记success对应的页面在当前action中没有配置,
所有会去找全局配置是否有success标记对应的页面-->
</action> </package>
</struts>

2.配置各项默认值

<?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="config" namespace="" extends="struts-default" abstract="false">
<!--配置全局跳转视图-->
<global-results>
<result name="success">/index.jsp</result>
</global-results> <!--配置各项默认值-->
<!--
name: 配置了访问路径名称
class: 默认执行的action在struts-default有配置
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
method: 默认为excute
默认的excute返回值是success,对应的页面去全局视图中查询,此处我们定义了全局视图为index.jsp
-->
<action name="login" class="a_config.UserAction" method="login">
<result name="success">/index.jsp</result>
</action> <!--什么情况不配置class?即处理的action-->
<!--答案:当只是需要跳转到WEB-INF下资源的时候-->
<action name="test">
<result name="success">/WEB-INF/index.jsp</result>
</action>
</package>
</struts>