我们在学习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请求链接
  1. <body>
  2. <h3>入门路径:</h3><br>
  3. <a href="${pageContext.request.contextPath }/UserServlet">userWorld</a><br>
  4. <a href="${pageContext.request.contextPath }/HelloServlet">helloWorld</a><br>
  5. <a href="${pageContext.request.contextPath }/CustomerServlet">addWorld</a><br>
  6.  
  7. </body>
  • 我们首先通过传统的Servlet来实现:

UserServlet

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

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

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

  • 创建一个Action接口,作为请求对应的类,它有三个实现类对应三个Servlet
  1. package cn.filter;
  2.  
  3. public interface Action {
  4. public String excute();
  5. }
  1. package cn.filter;
  2.  
  3. public class HelloAction implements Action{
  4.  
  5. @Override
  6. public String excute() {
  7. System.out.println("访问HelloAction!");
  8. return "error";
  9. }
  10. }
  1. package cn.filter;
  2.  
  3. public class UserAction implements Action {
  4.  
  5. @Override
  6. public String excute() {
  7. System.out.println("访问UserAction!");
  8. return "success";//对应请求转发的页面名称
  9. }
  10. }
  1. package cn.filter;
  2.  
  3. public class CustomerAction implements Action {
  4.  
  5. @Override
  6. public String excute() {
  7. System.out.println("访问CustomerAction!");
  8. return "add";
  9. }
  10. }
  • 创建Filter,然后对过滤进行操作

  1. package cn.filter;
  2.  
  3. import java.io.IOException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6.  
  7. import javax.servlet.DispatcherType;
  8. import javax.servlet.Filter;
  9. import javax.servlet.FilterChain;
  10. import javax.servlet.FilterConfig;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.ServletRequest;
  13. import javax.servlet.ServletResponse;
  14. import javax.servlet.annotation.WebFilter;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17.  
  18. @WebFilter(
  19. dispatcherTypes = {DispatcherType.REQUEST }
  20. ,
  21. urlPatterns = {
  22. "/TestFilter",
  23. "/*"
  24. })
  25. public class TestFilter implements Filter {
  26. //使页面的访问路径对应Action类
  27. Map<String, String> actionMap = new HashMap<>();
  28. //使对应的action返回值对应相应的jsp页面
  29. Map<String, String> returnMap = new HashMap<>();
  30. //web容器启动时执行
  31. public void init(FilterConfig fConfig) throws ServletException {
  32. actionMap.put("/UserServlet", "cn.filter.UserAction");
  33. actionMap.put("/HelloServlet", "cn.filter.HelloAction");
  34. actionMap.put("/CustomerServlet", "cn.filter.CustomerAction");
  35. returnMap.put("success", "/success.jsp");
  36. returnMap.put("add", "/add.jsp");
  37. returnMap.put("error", "/error.jsp");
  38. }
  39.  
  40. public void destroy() {
  41. // TODO Auto-generated method stub
  42. }
  43.  
  44. public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
  45. HttpServletRequest request= (HttpServletRequest) req;
  46. HttpServletResponse response = (HttpServletResponse) resp;
  47. //获取请求Servlet路径
  48. String path = request.getServletPath();
  49. if(path != null && path.equals("/test.jsp")){
  50. chain.doFilter(request, response);
  51. return;
  52. }//如果是test.jsp那么放行
  53. //如果不是test.jsp页面,那就进行过滤操作
  54. //获取访问的action路径
  55. String actionClass = actionMap.get(path);
  56. try {
  57. //通过反射获取Action类的对象
  58. Action action = (Action) Class.forName(actionClass).newInstance();
  59. //获取返回的页面名称
  60. String returnValue = action.excute();
  61. //利用Action类的返回值,获取所对应的页面
  62. String page = returnMap.get(returnValue);
  63. //转发到相应页面
  64. request.getRequestDispatcher(page).forward(request, response);
  65. } catch (InstantiationException e) {
  66. // TODO Auto-generated catch block
  67. e.printStackTrace();
  68. } catch (IllegalAccessException e) {
  69. // TODO Auto-generated catch block
  70. e.printStackTrace();
  71. } catch (ClassNotFoundException e) {
  72. // TODO Auto-generated catch block
  73. e.printStackTrace();
  74. }
  75.  
  76. }
  77. }

  我们使用浏览器进行测试,发现,这次我们的请求没有经过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. Python高级用法------字典无需提前定义key

    from collections import defaultdict import json def tree(): return defaultdict(tree) categories = tr ...

  2. 常用shell脚本(持续更新中)

    1. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录. 答案 : 输出用户名,当前日期和时间,以及当前工作目录的命令就是logname,date,who i am和pwd. #!/b ...

  3. 【Elasticsearch】深入Elasticsearch集群

    7.1 节点发现启动Elasticsearch的时候,该节点会寻找有相同集群名字且课件的主节点,如果有加入,没有自己成为主节点,负责发现的模块两个目的 选出主节点以及发现集群的新节点7.1.1发现的类 ...

  4. ControlTemplate 中 Bingding 附加属性时需要加入 Path

    <Style TargetType="{x:Type GroupBox}" BasedOn="{StaticResource MaterialDesignGroup ...

  5. org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported或其他Content type不支持处理

    很久没从头到尾搭框架,今天搭的过程中,springmvc controller方法入参用@RequestBody自动绑定参数时一直提示各种 not supported 排查问题有两个解决路径: 1)使 ...

  6. oracle学习篇二:常用SQL

    ------------------------1.简单的SQL查询--------------------------select * from emp;select empno,ename,job ...

  7. rest-framework框架——APIView和序列化组件

    一.快速实例 Quickstart http://www.cnblogs.com/yuanchenqi/articles/8719520.html restful协议 ---- 一切皆是资源,操作只是 ...

  8. Linux服务器性能评估与优化(二)

    网络内容总结(感谢原创) 1.Linux内核参数优化 内核参数是用户和系统内核之间交互的一个接口,通过这个接口,用户可以在系统运行的同时动态更新内核配置,而这些内核参数是通过Linux Proc文件系 ...

  9. 《ArcGIS Runtime SDK for Android开发笔记》——(13)、图层扩展方式加载Google地图

    1.前言 http://mt2.google.cn/vt/lyrs=m@225000000&hl=zh-CN&gl=cn&x=420&y=193&z=9& ...

  10. IT人的格言警句

    程序员困境:我们通过编码谋生,但环境却正在摧毁我们这种谋生的能力. 在技术日新月异的IT行业,“专家”这个词其实是个危险信号,意味着你的知识距离老化不远了.IT工程师应该经常更换工作领域,了解多个领域 ...