Struts2核心

xiaoxiao2021-02-28  20

MVC框架及Struts2介绍 Struts2核心 Struts2拦截器 Struts2值栈和OGNL表达式 Struts2标签库

1 xml文件模块化管理

  大部分应用中,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得很大。为了避免struts.xml文件过大,提高struts.xml文件的可读性,可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml主文件中引入其他配置文件。配置文件的基本格式与struts.xml文件一样,写在resources文件(Source Folder文件)中。   struts.xml中<include>引入其他配置文件:

<struts> <package name="default" namespace="/" extends="struts-default"> ... </package> <!-- 引入struts-system.xml文件 --> <include file="struts-system.xml"></include> </struts>

2 <package>标签

  在配置文件中,需要将<action>标签写在<package>中,<package>类似Java中的包,可以唯一确定一个包中的<action>,不同包中<action>可以同名,同包中不能同名。<package>的目的是为了进行模块化管理。

<package name="default" namespace="/" extends="struts-default" abstract="false"> ... </package>

  name:包名,在整个应用中不能重复;   namespace:包命名空间,访问该包中action时额外加的路径;   extends:继承,继承其他包的配置文件,通常继承struts-default.xml中的;   abstract:当前包是抽象的包(用来被继承的,struts-default.xml中为”true”)。

  访问action   http ://ip:port/<appContextPath>/<packageNamespace>/<actionName>[.action]   http ://ip:端口/<上下文路径>/<包的命名空间>/<action名称>[.后缀名]   如果上下文路径path=”“,namespace=”/”,则不需要加/<上下文路径>/<包的命名空间>。

3 Action的查找流程

  简单查找流程

<package name="default" namespace="/system" extends="struts-default"> <action name="hello"></action> </package >

  访问的uri:http ://localhost/system/hello   uri分为两部分:   packageNamespace : /system   actionName:hello   查找Action时,首先通过packageNamespace在配置文件中查找对应的<package>标签,然后通过actionName在<package>标签中查找对应<action>。

  复杂查找流程

<package name="default" namespace="/" extends="struts-default" > ... </package > <package name="path1" namespace="/path1" extends="struts-default" > ... </package> <package name="path2" namespace="/path1/path2" extends="struts-default" > ... </package>

  访问uri:http ://localhost/path1/path2/hello   先找<package>:   先会通过/path1/path2找对应的<package namespace=”/path1/path2”…>包,如果没有这个包,就退一级找/path1对应的<package namespace=”/path1”…>包,如果没有这个包,就找到<package namespace=”/”…>根包。

  再找<action>:   如果找到包,就在当前包下面找Action,如果没有找到Action,不会退级找,而是到默认包中查找Action,如果还没有就报错。namespace=”/”代表根包,namespace=”“代表默认包。

4 Struts配置文件

4.1 配置文件

Struts2框架加载配置顺序   1.default.properties:该文件在struts2-core-2.3.20.jar/ org.apache.struts2中,配置中很多常量在其中;      2.struts-default.xml:该文件在struts2-core-2.3.20.jar中,可以查看配置方式;      3.struts-plugin.xml:该文件在struts2项目的lib包中,比如struts2-spring-plugin-2.3.20.jar,保存着一些插件;   4.struts.xml:web应用默认的struts配置文件;   5.struts.properties:struts的默认配置文件(一般配置不写在其中);   6.web.xml:web应用的配置文件(一般配置不写在其中)。

  前三个文件是Struts2默认的配置文件,不能进行修改,如果多个文件配置了同一个常量,后一个配置文件会覆盖前一个配置文件的常量。

4.2 常量配置

  常量配置在default.properties文件中,可以通过struts.xml配置常用常量(也可以在web.xml和struts.properties配置,但是不推荐)。   开发者模式   修改配置不需要重启服务器

<constant name="struts.devMode" value="true"/>

  开发时使用,项目上线前需要关闭。

  设置系统编码

<constant name="struts.i18n.encoding" value="utf-8"></constant>

  设置后缀名

<constant name="struts.action.extension" value="action,do,,"></constant>

  后缀名之间用逗号分隔,一般留下一个空串,访问时使用actionName.action、actionName.do或actionName。

4.3 默认配置

  package继承了struts-default包,在struts-default.xml中配置了<action>和<result>标签的默认值。

<package name="default" namespace="/" extends="struts-default"> <action name="index"> <result>/index.jsp</result> </action> </package>

  <action>   class属性可以不写,但一般写上,默认的属性值为:   <default-class-ref class=”com.opensymphony.xwork2.ActionSupport” />   method属性可以不写,默认值为:execute

  <result>   name属性可以不写,默认为:success   type属性可以不写,默认为:dispatcher

5 Struts2获取ServletAPI

  Struts2可以在不使用ServletAPI的情况下获取参数,也可以通过结果视图进行页面跳转。但是在一些特殊情况中依然需要获取request、response对象,比如获取浏览器的信息,获取当前项目所在的实际路径等。

5.1 ActionContext/ServletActionContext

public class ApiAction { public String execute(){ // 通过ActionContext获取作用域对象 Map<String, Object> session = ActionContext.getContext().getSession(); Map<String, Object> application = ActionContext.getContext().getApplication(); // 通过ServletActionContext获取请求和响应对象 HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); return "success"; } }

  通过ActionContext获取作用域对象Session时,获取的实际上是SessionMap,底层中封装了HttpSession对象,通过Map设置或获取值时实际上是往当前请求的Session中设置或获取值。这种方式更简单,类本身脱离了ServletAPI,通常使用这种方式。

5.2 ServletRequestAware/ServletResponseAware

public class ApiAction implements ServletRequestAware,ServletResponseAware { private HttpServletRequest request; private HttpServletResponse response; public String execute(){ return "success"; } // request @Override public void setServletRequest(HttpServletRequest request) { this.request = request; } // response @Override public void setServletResponse(HttpServletResponse response) { this.response = response; } }

  通过Action类实现ServletRequestAware、ServletResponseAware接口获取请求与响应对象,只要Action实现了Aware(可感知)接口,Struts2就能感知到,框架就可以调用接口对应的方法。

6 Struts2返回类型

6.1 视图返回类型

  在struts-default.xml配置文件中,Struts2定义了很多返回结果类型,并且为每个结果类型封装了一个类:      dispatcher:请求转发,默认类型   redirect:重定向   redirectAction:重定向到Action   velocity、freemarker:在模版中使用

  结果视图的完整写法

<result name="success" type="dispatcher"> <param name="location"> index.jsp</param> </result>

  <result>标签中的属性:   name:指定配置逻辑视图名(和Action方法返回值对应),默认值为success;   type:指定结果类型,默认值为dispatcher。   标签中的内容为视图路径地址。

  struts.xml中新增结果类型名称

<package name="default" namespace="/" extends="struts-default"> <result-types> <result-type name="forward" class="org.apache.struts2.dispatcher.ServletDispatcherResult"/> </result-types> </package>

  定义在<package>标签中,class为struts2为结果类型封装的类,替代dispatcher。

  redirectAction   1.同包中跳转到Action

<package name="result" namespace="/result" extends="struts-default"> <action name="result01" class="cn.wenwen.action._01RedirectAction"> <result name="success" type="redirectAction"> result02 </result> </action> <action name="result02" class="cn.wenwen.action._02RedirectAction"> <result name="success"> /index.jsp </result> </action> </package>

  ”result01”跳转到”result02”,跳转结果为Actionname,无需加”/”

  2.异包中跳转到Action

<package name="result" namespace="/result" extends="struts-default"> <action name="result02" class="cn.wenwen.action._02RedirectAction"> <result name="success"> /index.jsp </result> </action> </package> <package name="res" namespace="/res" extends="struts-default"> <action name="result01" class="cn.wenwen.action._01RedirectAction"> <result name="success" type="redirectAction"> <param name="namespace">/result</param> <param name="actionName">result02</param> </result> </action> </package>

  ”result01”跳转到另一个包中的”result02”时,需要在<result>中设置参数,通过namespace找到另一个包,然后通过actionName找到包中的Action。

  3.使用redirect也可以跳转到其它Action

<package name="default" namespace="/" extends="struts-default"> <action name="result01" class="cn.itsource._04_result.ResultAction01"> <result name="success" type="redirect"> /result/result02 </result> </action> </package> <package name="result" namespace="/result" extends="struts-default"> <action name="result02" class="cn.itsource._04_result.ResultAction02"> <result name="success"> /success.jsp </result> </action> </package>

  结果视图内容为:/其它包namespace/其它action的name。

6.2 全局视图

  局部视图只能在当前的<action>中使用,如果一个包中多个需要使用同一个结果视图,就需要定义全局视图。

<package name="default" namespace="/" extends="struts-default"> <global-results> <result name="login"> /login.jsp </result> </global-results> ... </package>

  将全局视图<global-results>配置在<package>中,包中的所有<action>都可以使用。如果局部视图中有一个结果视图与全局中的结果视图名称相同,会使用局部视图。   如果写一个返回视图给几个包都使用,可以使用包之间的继承来实现。

7 Struts2实现Action的方式

7.1 普通Action类

  使用POJO(JavaBean)类,并提供public修饰的无参方法。

public class MethodAction { public String execute(){ return null; } }

  struts.xml配置

<package name="method" namespace="/method" extends="struts-default"> <action name="methodAction" class="cn.wenwen.MethodAction " method="execute"> </action> </package>

  访问   http ://localhost/method/methodAction

7.2 实现Action接口

  实现com.opensymphony.xwork2.Action接口,并覆写方法:

public class MethodAction implements Action { @Override public String execute() throws Exception { return NONE; } }

  在Action中,封装了SUCCESS、ERROR、INPUT、LOGIN、NONE字段以及execute()方法。

7.3 继承ActionSupport类

  继承ActionSupport类,并覆写execute()方法。

public class MethodAction extends ActionSupport { @Override public String execute() throws Exception { return NONE; } }

  ActionSupport实现了Action类,同时定义了表单域校验、错误信息设置和获得国际化信息等方法。

  最佳实践   写一个BaseAction继承ActionSupport,可以继承ActionSupport的功能,也可以扩展一些公共的常量和方法。让其它的Action来继承BaseAction,这样就可以使用自定义的常量和方法。

8 Action多方法配置

  在一个Action中会有CRUD等多个方法,这时需要通过在struts.xml中配置,调用Action中不同的方法。

8.1 动态调用

  采用”/Actionname!方法名”调用,需要开启动态调用的配置。

<package name="dynamic" namespace="/dynamic" extends="struts-default"> <!-- 开启动态调用 --> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <action name="method" class="cn.wenwen.MethodAction " method="execute"> ... </action> </package>

  访问add()方法:http ://localhost/dynamic/method!add   动态调用的安全性不高,通常不使用。

8.2 使用通配符*

  单通配符

<package name="default" namespace="/" extends="struts-default"> <action name="method_*" class="cn.wenwen.MethodAction" method="{1}"> ... </action> </package>

  ”method_*”中星号表示一个通配符,根据传入的方法名在Action中匹配,{1}表示第一个通配符。访问add()方法:http ://localhost/method_add,如果访问的是execute()方法,可以不加_*直接用/method。

  多通配符

<package name="default" namespace="/" extends="struts-default"> <action name="*_*" class="cn.wenwen.{1}Action" method="{2}"> ... </action> </package>

  {1}表示第一个通配符,替代部分类名,{2}表示第二个通配符,代表方法名。   访问add()方法:http: //localhost/Method_add

9 接收参数方式

9.1 普通参数

  接收普通参数如name、password:

public class ParamAction extends ActionSupport { private String name; private String password; public String execute() { return NONE; } public void setName(String name) { this.name = name; } public void setPassword(String password) { this.password = password; } }

  写一个Action类继承ActionSupport覆写方法,定义需要接收的参数,只需提供set()方法,框架会匹配属性设置值。这种方式如果参数过多就会变得复杂。

  struts.xml配置

<package name="default" namespace="/" extends="struts-default"> <action name="params" class="cn.wenwen.ParamAction"></action> </package>

  前台页面

<form action="/params" method="post"> 用户名:<input type="text" name="name" /> <br /> 密码:<input type="password" name="password" /> <br /> <input type="submit" value="...提交..." /> </form>

9.2 接收对象

  如果参数过多,需要将数据封装为对象,比如User对象。

public class User { private Long id; private String name; private String password; // set、get方法 ... }

  方式一:Action中将User实例化

public class ParamAction extends ActionSupport { private User user = new User(); public String execute() { return NONE; } // 框架获取User对象,然后调用User里面setter方法设置值 public User getUser() { return user; } }

  框架会通过getUser()获取User对象,然后调用User中的setter方法把值设置到对象属性中。

  方式二:提供set方法。

public class ParamAction extends ActionSupport { private User user; public String execute() { return NONE; } // 框架获取User对象,然后调用User里面setter方法设置值 public User getUser() { return user; } public void setUser(User user) { this.user = user; } }

  如果没有实例化User,无法直接获取User对象,框架会通过反射创建一个User对象,调用setUser()方法将对象设置进去,然后获取User对象并设置属性值。

9.3 实现ModelDriven接口

  实现ModelDriven(模型驱动)接口

public class ParamAction extends ActionSupport implements ModelDriven<User> { private Long id; private User user = new User(); public String execute() { return NONE; } @Override public User getModel() { return user; } public void setId(Long id) { this.id = id; } }

  实现ModelDriven接口后,框架在设置参数时就会先调用getModel()方法来获取对象,然后调用对象中的setter方法设置属性值。这种方法可以和普通参数方法结合使用,利用普通参数方法设置id。如果一个Action中只封装了一个对象,就可以用这种方式。

转载请注明原文地址: https://www.6miu.com/read-2099991.html

最新回复(0)