Struts2框架

1.MVC思想
Java Web应用结构经历了Model1和Model2两个时代:
Model1——JSP + JavaBean模式
整个Web应用几乎全部由JSP页面组成,用少量的JavaBean来处理数据库连接、数据库访问等操作。
Model2——MVC模式
基于MVC架构,Servlet做为前端控制器,负责接收客户端发送的请求,Servlet中只包含控制逻辑和简单的前端处理,然后调用后端JavaBean来完成实际的逻辑处理,最后转发到相应的JSP页面。

MVC是一种设计思想,该思想将应用分成三个基本部分:Model(模型)、View(视图)、Controller(控制器),这三个部分以最少的耦合(低耦合)协同工作,提高应用的可扩展性及可维护性。

提示:传统Servlet/Jsp实现的MVC架构,其运行机制是:JSP页面(View)发送消息到Servlet(控制器Controller),Servlet获取请求数据,处理业务逻辑,分发转向。这样Servlet就变得臃肿,什么活都是Servlet在干,而且业务逻辑全是硬编码,代码都写列不利于维护。
2.Struts2介绍
官网: https://struts.apache.org/

Struts2是Apache组织下一个基于MVC设计模式的Web应用框架。
Struts2是Struts的下一代产品,是Struts1 + WebWork合并的全新框架。
Struts2采用拦截器为核心机制,就一个开源的轻量级的,应用于表示层(Web层、View)的框架。
Filter .action
Servlet .do
3.Struts2 入门案例
3.1.Maven创建项目

注意:这里点击“Add…”,在弹出窗中输入:archetypeCatalog = internal
用于提高Maven创建项目时的速度。 (构筑目录类型) (内部的)

注意:在这里解决两个问题。
问题1:JSP文件报错
解决办法:在pom.xml中引入servlet-api依赖即可。

javax.servlet javax.servlet-api 4.0.0

问题2:在项目中显示src/main/java文件夹

问题3:调整项目的JavaSE版本及动态网站支持版本
鼠标右击项目,选择最下面的Properties选项:

问题4:发布Maven中的包到Tomcat的WEB-INF中,否则报ClassNotFound异常

3.2.引入jar依赖包
在项目的pom.xml中引入Struts 2的核心依赖:struts2-core。

org.apache.struts struts2-core 2.5.16

注意:struts2的版本不同,配置也有部分差异。

3.3.配置核心拦截器
在项目webapp/MEB-INF/web.xml文件中配置Struts2核心拦截器:StrutsPrePareAndExecuteFilter。
当用户请求匹配的URL时,执行核心栏截器。

扩展知识:由于Web应用是基于请求/响应架构的应用,所以不管哪个MVC Web框架,都需要在web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架介入Web应用中。

struts2 org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter struts2 /* 注意事项: Struts 2.1版本之前用的核心过滤器是FilterDispacther。

Struts 2.1~2.4版本用的是StrutsPrepareAndExecuteFilter
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

Struts 2.5版本用的也是StrutsPrepareAndExecuteFilter,但路径有所改变:
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

3.4.定义Action
Action是业务控制器,是Struts2的重要组成部分之一。
Action是MVC中的C,也就是控制器。
该类负责调用Model里的方法来处理请求。

创建Action动作类:UserAction
/**

  • 用户业务控制类
    */
    public class UserAction{
    //execute方法为默认执行方法
    public String execute() throws Exception{
    ……
    return “success”; //返回字符串(即结果码)
    }
    }
    问题1:Action并未接收到用户请求,它怎么能处理用户请求呢?
    MVC框架的底层机制是:核心Servlet或Filter接收到用户请求后,通常会对用户请求进行简单预处理,例如解析、封装参数等,然后通过反射来创建Action实例,并调用Action指定的方法(Struts1通常是execute,Struts2可以是任意方法)来处理用户请求。

问题2:当Servlet和Filter拦截用户请求后,它如何知道创建哪个Action的实例呢?
有两种解决方案:
利用配置文件
例如配置login.action对应使用LoginAction类,这就可以让MVC框架知道创建哪个Action的实例了。
利用约定
例如约定xxx.action总是对应XxxAction类。如果核心控制器收到regist.action请求后,将会调用RegistAction类来处理用户请求。须要提供Convention(约定)插件。这见鉴了Rails框架的优点,即“约定优于配置”。
3.5.配置Action
在src或src/main/resources下创建Struts2核心配置文件:struts.xml,并配置Action类的请求与响应。

<?xml version="1.0" encoding="UTF-8"?> <-- 包的配置:name为自定义包名;extends当前包继承struts-default,必须要写;namespace非必填 --> <-- Action的配置:name为URL请求地址;class为实例对象全路径名;method没写,默认执行execute方法 --> …… 问题一:如何创建struts.xml?内部代码记不住怎么办? 创建普通XML文件即可,关于struts.xml中引用的dtd约束等代码,可以找到struts核心包中的struts-default.xml文件,复制即可。

3.6.配置处理结果与视图


loginForm.jsp
error.jsp
/WEB-INF/webs/welcome.jsp
……

3.7.编写视图资源
测试连接
测试连接

自学《附一:常用的constant常量设置》,挑选出常用的进行配置。

4.Struts2框架原理
4.1.Struts2框架的MVC
M:JavaBean + ModelDriven
V:JSP + OGNL
C:Action
Struts2框架的控制器将“获取请求”和“分发转向”代码抽取出来写在配置文件中,这样一样,控制器(action类)就能专注于业务逻辑的处理了。
4.2.Struts2的两个重要组成部分
Struts2的两个重要组成部分是:核心过滤器 + 业务控制器。
4.2.1.核心过滤器:StrutsPrepareAndExecuteFilter
作用:负责拦截所有用户的请求,该Filter在过滤用户请求后,将请求都交给Struts2框架处理。
拦截器会默认拦截扩展名为.action的请求,什么后缀都不写也可以。
例如:hello.action或者hello都会被拦截;hello.jsp就不会进行拦截,直接放行。

每次实例化对象,线程安全;Servlet是单实例的,所以线程不安全。
4.2.2.业务控制器:Action
业务控制器就是用户实现的Action类,Action类中通常包含一个execute方法,该方法返回一个字符串(即结果码),字符串与struts.xml中的result的name相对应,跳转到不同页面。
4.3.Struts2的运行流程图

Struts2的执行流程大致有以下几步:
第一步:用户发起请求(默认.action结尾的请求表示请求一个Action)。
第二步:Struts2的核心过滤器(StrutsPrepareAndExecuteFilter)接收用户发起的请求,然后判断这个请求交给Action处理还是交给Web组件处理。如果请求的Action或者Web组件不存在,那么出现404错误。在整个处理过程中需要一个辅助对象:Action映射器(ActionMapper)。
第三步:将第二步判断的结果如果是交给Action处理,并且存在对应的Action,那么根据struts.xml中对此Action的配置信息,首先执行拦截此 Action的所有拦截器,然后再执行请求的Action对象。在这个处理过程中需要辅助对象:Action代理(ActionProxy)、配置管理器(ConfigurationManager)、Action调度(ActionInvocation)。
第四步:Action执行完毕后返回一个结果(此结果用字符串表示),这个结果经过拦截Action的所有拦截器之后,返回给核心过滤器(StrutsPrepareAndExecuteFilter),核心过滤器根据此结果从配置文件中找到真正的路径,然后将请求转发给对应的视图,由视图向客户端作出响应。

Struts2框架内部运行原理图

(1) 客户端(Client)向Action发用一个请求(Request)
(2) Container通过web.xml映射请求,并获得控制器(Controller)的名字
(3) 容器(Container)调用控制器(StrutsPrepareAndExecuteFilter或FilterDispatcher)。在Struts2.1以前调用FilterDispatcher,Struts2.1以后调用StrutsPrepareAndExecuteFilter
(4) 控制器(Controller)通过ActionMapper获得Action的信息
(5) 控制器(Controller)调用ActionProxy
(6) ActionProxy读取struts.xml文件获取action和interceptor stack的信息。
(7) ActionProxy把request请求传递给ActionInvocation
(8) ActionInvocation依次调用action和interceptor
(9) 根据action的配置信息,产生result
(10)Result信息返回给ActionInvocation
(11)产生一个HttpServletResponse响应
(12)产生的响应行为发送给客服端。

5.Action中获取Web对象
Action获取Web对象有三种方式:ActionContext类、ServletActionContext类、ServletXxxAware接口。
其中:前者为解耦方式,推荐;后两者为耦合方式,不推荐。
解耦方式——即struts2测试时不需要启动服务器,提高开发效率。
5.1.使用ActionContext类(解耦)
Web应用中通常需要访问的Servlet API就是HttpServletRequest、HttpSession和ServletContext,这三个接口分别代表JSP内置对象中的request、session和application。

Struts2提供了一个ActionContext类(com.opensymphony.xwork.ActionContext),它是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象。可以通过下面方法访问Servlet API:
方法 说明
Object get(key) 类似于HttpServletRequest的getAttribute(String)
Map getApplication() 返回一个Map对象
Static ActionContext getContext() 返回静态的ActionContext实例,相当于HttpServletRequest对象
HttpParameters getParameters() 获取所有的请求参数
Map getSession() 返回一个Map对象
void setApplication(Map) 向application传入一个Map对象
void setSession(Map) 向session传入一个Map对象
void put(key, value) 添加对象

如何获得地址栏参数、表单参数:(struts版本不一样使用也不一样)
ActionContext ac = ActionContext.getContext();

//1.获取application、session、request对象
Map application = ac.getApplication();
Map session = ac.getSession();
Map request = (Map)ac.get(“request”);

//2.设置application、session、request作用域的值
application.put(“userName”, “admin”);
session.put(“userName”, “admin”);
request.put(“userName”, “admin”);

//3.获取application、session、request作用域的值
application.get(“userName”);
session.get(“userName”);
request.get(“userName”);

//1.获取request请求参数
//先获得request对象
HttpServletRequest request = (HttpServletRequest) ac.get(StrutsStatics.HTTP_REQUEST);
//再通过request对象获取请求参数
String type = request.getParameter(“type”);

//2.直接获取请求参数
Map<String, Object> paramsMap = Ac.getParameters();
//参数被封装成String[]
String[] methodNameParam = (String[])paramsMap.get(“methodName”);
for(String s : methodNameParam){
System.out.println(s);
}

//3.获得HttpServletRequest对象的attribute(解耦)
Map<String, Parameter> paramsMap =context.getParameters(); //获得上下文中所有的参数值
String type = paramsMap.get(“type”).toString(); //从获得的参数值中查找某个

案例1:使用ActionContext操作作用域
ActionContext ac = ActionContext.getContext();
Integer count = (Integer) ac.getApplication().get(“count”);
// 通过ActionContext设置application范围的属性
ac.getApplication().put(“count”, 100);
// 通过ActionContext设置session范围的属性
ac.getSession().put(“max”, 1000);
// 通过ActionContext设置request范围的属性
ac.put(“min”, 10);

前端页面:
统计总人数: a p p l i c a t i o n S c o p e . c o u n t 最 大 人 数 : {applicationScope.count} 最大人数: applicationScope.count{sessionScope.max}
最小人数:${requestScope.min}

案例2:使用ActionContext获得JSP表单中的数据
(1)创建表单,提交表单到action里面

用户名: 手机号: 性 别:男 女

(2)在action使用ActionContext获取表单数据:
ActionContext context = ActionContext.getContext();
// map的key就是表单项的各name
Map<String, Object> map = comtext.getParameters();
//查看Map中的数据
Set keys = map.keyset();
for(String key : keys){
Object[] obj = (Object[])map.get(key);
System.out.println(Arrays.toString(obj));
}
5.2.使用ServletActionContext类(耦合)
在Action中通过ServletActionContext类也能获得Web对象,但不建议直接访问Servlet的API,这样做不利于项目的移植。
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute(“request”, “1”);

HttpSession session = request.getSession();
session.setAttribute(“session”, “2”);

ServletContext application = request.getSession().getServletContext();
application.setAttribute(“application”, “3”);
5.3.使用ServletXxxAware接口注入(耦合)
使用ServletContextAware、ServletRequestAware、ServletResponseAware三个接口可直接获得Servlet API。
Step1:类实现ServletResponseAware接口(或其它两个接口)。
Step2:重写相应的方法:
// 自定义类实现:ServletXXXAware接口,实现方法
public class Test implements ServletRequestAware,ServletSessionAware……{
private HttpServletRequest request;

@Override
public void setServletRequest(HttpServletRequest request){
    this.request = request;
}

public String execute() throws Exception{
    return NONE;
}

}
5.4.清空Session的值
HttpSession session = ServletActionContext.getRequest().getSession();
session.invalidate();
sessionMap.invalidate();
session.invalidate():将session设置为失效,一般在退出时使用,但要注意的是:session失效的同时,浏览器会立即创建一个新的session,你第一个session已经失效了,所以调用它的getAttribute方法时候一定会抛出NullPointerException的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EviaHp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值