问题出现
- 为什么会提出Struts2的概念,大家都知道在我们写JavaWeb应用的时候,我们会写Servlet处理类,如果我们的项目足够大,那么Servlet处理类就会很多,导致的结果就是我们想修改某个处理类的话,要找到它会花费非常多的时间,不方便管理。
- 虽然有人想到了用BaseServlet 解决Servlet过多的管理问题,实现方式是通过底层反射实现
- 但是上面的解决办法还不是最好,每写一个类就会去继承BaseServlet来实现管理。
那么为了解决这个问题,现在比较方便的处理方法就是Struts2了。
Struts2的概述:
- Struts2是用在web层中的框架。因为Struts2管理Servlet的最根本依赖就是通过Filter来拦截用户的各种请求。所以Struts2是跟平台有关的框架。
- Struts2是建立在struts1和webwork基础之上的全新框架
- Struts2的实现原理就是:通过过滤器来拦截用户的各种操作,比如crud操作,然后Struts2通过调用各种action里面的方法来实现处理用户请求。
- 在我们往常处理请求时用的是Servlet类,现在是Struts2里面的各种action类。
冷知识:增删改查被很多人称作crud操作
web层中常见的框架:
- Struts2
- SpringMVC
注意:这里使用的Struts版本是Struts2.5
Struts2入门案例:
- 对于入门我们第一步当然是要想到怎么使用Struts2了。
- 要想使用Struts2当然是先要导入Struts2的相关jar包。因为Struts2毕竟是别人写的一个框架。(jar包下载地址),导入jar包导入到WEB-INF下的lib目录下,当然具体细节我就不会惰诉了。
- 我们每次访问Servlet的时候都是通过调用service方法来处理用户的请求。然而在我们的Struts2中却是通过调用ation类里面的execute方法来处理用户请求。execute是默认的调用方法。
- 这里写action类的时候类名可以任意写,也不用去继承任何的类,只需要在类里面写上一个返回值为String的execute方法。
下面具体代码你可以不用看明白意思,你只需要看效果,具体解释我会在文章结尾处讲到的。
public class pr01_he_action {
public String execute(){
return "pr1";
}
}
- 但是要想访问我们的ation相关类我们还必须进行配置。
配置的方法就是:首先创建struts2核心配置文件。
- 核心配置文件名称和位置都是固定的
- 位置必须在src下面,名称为struts.xml注意,这里不是struts2.xml
- 创建核心配置文件struts.xml后就是写内容了。
- 注意我们写的是xml文件,所以这里会导入相关的约束。
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
- 这里的约束有一个专业名词叫做dtd约束。
- 最后就是要配置我们的action这个处理类了。
整体配置代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="px" extends="struts-default" namespace="/">
<action name="lang" class="cn.domarvel.pr.pr01_he_action">
<result name="pr1">/pr1x.jsp</result>
</action>
</package>
</struts>
- 剩下的就是让我们的项目跑起来了,对于访问浏览器的url地址方面,这里来个示例:http://localhost/项目名称/lang
- 这样写在我们的标准浏览器能够完美访问,但是在其它的杂牌浏览器里面这样访问会出错的。
- 所以我们这样改写我们的浏览器url访问地址:http://localhost/项目名称/lang.action
- 但是哦,你会发现你在进行访问上面的路径的时候会出现404的错误,那就是你出现了最核心的错误。你想啊,Struts2是根据Filter来拦截用户请求实现的。你都没用进行拦截用户请求就直接让用户访问了,这样肯定会出现404啊。
- 这个时候虽然Struts2已经帮我们写好了Filter,但是呢我们还没有进行配置Filter。
- 配置Filter是固定的。
<filter>
<!-- 这里的filter-name不是固定的可以随便写,当然会写xml的人都知道 -->
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我的pr1x.jsp页面是这样写的:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'pr1x.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<h4>It's Nice!! link successed!!</h4>
</body>
</html>
这里就能够正常进行相关的访问了。非常Nice!!!
值得回忆的是Servlet的创建:
- 在别人问我们怎么创建Servlet的时候,可能很多人都会说,右键new一个Servlet,这种回答是非常不正确的。
- 我们应该说的是:写一个类继承一个类,我们一般继承的是HttpServlet,然后重写doGet()和doPost()方法。
- 但是这样还没有完,我们必须还要让web容器找到我们写的这个Servlet功能。也就是配置web.xml。或者在Servlet的当前页面进行配置。
Struts2执行步骤讲解
上面我们已经成功进行访问了,但是具体过程我们还是不了解。
下面我们来进行讲解相关的访问执行过程。
- 首先用户在浏览器中输入url路径进行访问。
- Struts2中的过滤器拦截用户的访问请求。
- 拦截用户请求后,Struts2就获取到访问路径,得到路径中的hello这个值,虽然我们这里访问的项目路径中的具体请求是hello.action,但是Struts2能够通过切割字符串来取得hello这个值。
- Struts2于是就到src目录下找到struts.xml这个文件,使用dom4j解析得到xml文件的内容。拿着hello这个值到xml文件中找到action标签,匹配name属性值是否一样。
- 于是匹配成功后就在当前action标签中找另外一个属性的值,这个属性就是class,得到关于hello的处理类全路径。
- 使用反射实现功能。
- 下面是反射让action中的方法执行过程:
Class clazz=Class.forName("action全路径");
//得到名称是execute的方法
Method m=clazz.getMethod("execute");
//让方法跑起来。因为方法有返回值,所以要有个变量来接收。
Object result=m.invoke();
- 得到方法的返回值,找到当前action标签里面有result标签,匹配result标签里面的name属性值,匹配成功后,得到result标签里面的内容,然后根据内容跳转到相关页面。
OK! 完毕!!