我们在学习Struts之前,先来复习一下Servlet,众所周知Servlet是JavaWeb的三大组件。我们发送一个请求,这个请求交给Servlet处理,Servlet将处理的结果返还给浏览器。每个Servlet对应一个URL-pattern。那么有没有这么一种情况呢?我们访问多个URL-pattern,这些URL-pattern具有共同的功能,那就是转发到其它页面,但是又不想写那么多Servlet,Servlet虽然是单例的,但是能少一个对象,对于JVM也是一种优化不是吗,那么有什么办法可以做到呢?如下图

  熟悉Servlet的前辈,可能一看就会知道只是不可能的,一个Servlet只能对应一个URLPattern,那么怎么实现这个功能呢?下面我们通过项目来实现一下:

  • 创建Web项目struts2_1
  • 创建test.jsp页面,在页面中建立三个URL请求链接
<body>
<h3>入门路径:</h3><br>
<a href="${pageContext.request.contextPath }/UserServlet">userWorld</a><br>
<a href="${pageContext.request.contextPath }/HelloServlet">helloWorld</a><br>
<a href="${pageContext.request.contextPath }/CustomerServlet">addWorld</a><br> </body>
  • 我们首先通过传统的Servlet来实现:

UserServlet

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
System.out.println("欢迎访问UserServlet");
//pw.println("访问一次,我就得写一个Servlet!!!");请求转发会将response携带的数据丢失
request.getRequestDispatcher("/success.jsp").forward(request, response);
pw.flush();
pw.close();
}
Web.xml
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>cn.web.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/UserServlet</url-pattern>
</servlet-mapping>
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
System.out.println("欢迎访问HelloServlet");
pw.println("访问一次,我就得写一个Servlet!!!!");
request.getRequestDispatcher("/error.jsp").forward(request, response);
pw.flush();
pw.close();
}
@WebServlet("/CustomerServlet")
public class CustomerServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
System.out.println("欢迎访问CustomerServlet");
pw.println("访问一次,我就得写一个Servlet!!!!!");
request.getRequestDispatcher("/add.jsp").forward(request, response);
pw.flush();
pw.close();
}
Success.jsp
<body>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</body>
Error.jsp
<body>
错误页面
</body>
Add.jsp
<body>
添加
</body>

  我们在浏览器访问test.jsp,然后可以访问到这些Servlet,但是我们也注意到了,每一个URLpattern对应一个Servlet,这么多请求造成了我们写了很多Servlet,并且需要很多web.xml中的配置(Servlet3.0以后支持注解)。 那么能否实现在web容器中只配置一次,就可以实现以上3个URL都可以跳转到指定的页面呢?

  结论:可以使用过滤器实现:我们在过滤器中过滤所有的请求,进行判断,如果是test.jsp那么放行,否则就全部过滤操作。实际上根据上图我们知道这样一个对应关系,那就是一个请求对应一个Servlet,然后一个Servlet对应一个页面,那么我们创建两个Map集合,一个放请求和类的对应,一个放返回值和页面的对应.

  • 创建一个Action接口,作为请求对应的类,它有三个实现类对应三个Servlet
package cn.filter;

public interface Action {
public String excute();
}
package cn.filter;

public class HelloAction implements Action{

    @Override
public String excute() {
System.out.println("访问HelloAction!");
return "error";
}
}
package cn.filter;

public class UserAction implements Action {

    @Override
public String excute() {
System.out.println("访问UserAction!");
return "success";//对应请求转发的页面名称
}
}
package cn.filter;

public class CustomerAction implements Action {

    @Override
public String excute() {
System.out.println("访问CustomerAction!");
return "add";
}
}
  • 创建Filter,然后对过滤进行操作

package cn.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebFilter(
dispatcherTypes = {DispatcherType.REQUEST }
,
urlPatterns = {
"/TestFilter",
"/*"
})
public class TestFilter implements Filter {
//使页面的访问路径对应Action类
Map<String, String> actionMap = new HashMap<>();
//使对应的action返回值对应相应的jsp页面
Map<String, String> returnMap = new HashMap<>();
//web容器启动时执行
public void init(FilterConfig fConfig) throws ServletException {
actionMap.put("/UserServlet", "cn.filter.UserAction");
actionMap.put("/HelloServlet", "cn.filter.HelloAction");
actionMap.put("/CustomerServlet", "cn.filter.CustomerAction");
returnMap.put("success", "/success.jsp");
returnMap.put("add", "/add.jsp");
returnMap.put("error", "/error.jsp");
} public void destroy() {
// TODO Auto-generated method stub
} public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request= (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//获取请求Servlet路径
String path = request.getServletPath();
if(path != null && path.equals("/test.jsp")){
chain.doFilter(request, response);
return;
}//如果是test.jsp那么放行
//如果不是test.jsp页面,那就进行过滤操作
//获取访问的action路径
String actionClass = actionMap.get(path);
try {
//通过反射获取Action类的对象
Action action = (Action) Class.forName(actionClass).newInstance();
//获取返回的页面名称
String returnValue = action.excute();
//利用Action类的返回值,获取所对应的页面
String page = returnMap.get(returnValue);
//转发到相应页面
request.getRequestDispatcher(page).forward(request, response);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}

  我们使用浏览器进行测试,发现,这次我们的请求没有经过Servlet,而是通过Action类处理了(对比前后两次控制台打印输出可以看出),通过过滤器,我们简单避免了web.xml中的反复配置.上面其实就是一个简单的Struts2实现:

Struts2 第一讲 -- Struts2开发前奏的更多相关文章

  1. Struts2 第二讲 -- Struts2的入门

    搭建struts2环境时,我们一般需要做以下几个步骤的工作: 第一步:创建javaweb工程(这个很废话有木有) 第二步:找到开发Struts2应用需要使用到的jar文件.(这个很白痴有没有) 到ht ...

  2. Struts2第一天

    Struts2第一天 整体课程安排:3天知识点+2天练习 第一天:入门(action和result结果集)--一般的请求+响应 第二天:请求数据处理相关(参数接收.类型转换.合法性校验.国际化) 第三 ...

  3. (转)Spring4.2.5+Hibernate4.3.11+Struts2.3.24整合开发

    http://blog.csdn.net/yerenyuan_pku/article/details/52902851 前面我们已经学会了Spring4.2.5+Hibernate4.3.11+Str ...

  4. SSH框架之Struts2第一篇

    1.2 Struts2的概述 : Struts2是一个基于MVC设计模式的WEB层的框架. 1.2.1 常见web层框架 Struts1,Struts2,WebWork,SpringMVC Strut ...

  5. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

  6. Struts2学习第一天——struts2基本流程与配置

    struts2框架 什么是框架,框架有什么用? 框架 是 实现部分功能的代码 (半成品),使用框架简化企业级软件开发 ,提高开发效率. 学习框架 ,清楚的知道框架能做什么? 还有哪些工作需要自己编码实 ...

  7. Struts2+Spring+Hibernate整合开发(Maven多模块搭建)

    Struts2+Spring+Hibernate整合开发(Maven多模块搭建) 0.项目结构 Struts2:web层 Spring:对象的容器 Hibernate:数据库持久化操作 1.父模块导入 ...

  8. Struts2第一个入门案例

      一.如何获取Struts2,以及Struts2资源包的目录结构的了解    Struts的官方地址为http://struts.apache.org 在他的主页当中,我们可以通过左侧的Apache ...

  9. CS193P - 2016年秋 第一讲 课程简介

    Stanford 的 CS193P 课程可能是最好的 ios 入门开发视频了.iOS 更新很快,这个课程的最新内容也通常是一年以内发布的. 最新的课程发布于2016年春季.目前可以通过 iTunes ...

随机推荐

  1. C#中DataTable与泛型集合互转(支持泛型集合中对象包含枚举)

    最近在做WCF,因为是内部接口,很多地方直接用的弱类型返回(DataSet),这其实是一种非常不好的方式,最近将项目做了修改,将所有接口返回值都修改成强类型,这样可以减少很多与客户端开发人员的沟通,结 ...

  2. 初学Hadoop之中文词频统计

    1.安装eclipse 准备 eclipse-dsl-luna-SR2-linux-gtk-x86_64.tar.gz 安装 1.解压文件. 2.创建图标. ln -s /opt/eclipse/ec ...

  3. artDialog组件应用学习(三)

    一.可以加载url的对话框 预览: 对话框编写代码 //弹出一个对话框,加载页面 function OpenBox(url, title, width, height) { seajs.use(['j ...

  4. 服务器word权限添加

    我们的程序部署到IIS上会出现上图所示的错误. 这个是由于IIS没有权限访问word所致.   解决的方法: 在运行对话框中输入: mmc -32 出来如下图的界面:   然后点击"文件&q ...

  5. OLEDB 数据变更通知

    除了之前介绍的接口,OLEDB还定义了其他一些支持回调的接口,可以异步操作OLEDB对象或者得到一些重要的事件通知,从而使应用程序有机会进行一些必要的处理.其中较有用的就是结果集对象的变更通知接口.通 ...

  6. java常用API之DateFormat

    DateFormat 类: DateFormat 类是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间.日期/时间格式化子类(如 SimpleDateFormat类)允许进行格 ...

  7. 前端之CSS——盒子模型和浮动

    一.CSS盒子模型 HTML文档中的每个元素都被描绘成矩形盒子,这些矩形盒子通过一个模型来描述其占用空间,这个模型称为盒子模型. 盒子模型通过四个边界来描述:margin(外边距),border(边框 ...

  8. POJO对象

    POJO(Plain Old Java Objects)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称. 使用POJO名称是为了避免和 EJB混淆起来, 而且简 ...

  9. 【起航计划 031】2015 起航计划 Android APIDemo的魔鬼步伐 30 App->Preferences->Advanced preferences 自定义preference OnPreferenceChangeListener

    前篇文章Android ApiDemo示例解析(31):App->Preferences->Launching preferences 中用到了Advanced preferences 中 ...

  10. matlab练习程序(弧形投影)

    这个其实也算是圆柱体投影了,不过上一篇文章是从正面看,得到的是凸形的结果,而这个是从反面看,得到的是凹形的结果. 计算公式就不写了,大致介绍一下,计算公式中关于x坐标求法和上篇一样,y坐标则正好是上篇 ...