2.对 Servlet 的改进--------Struts2 引入

  通过上一篇博客:Servlet 的详解 http://www.cnblogs.com/ysocean/p/6912191.html,我们大致知道了 Servlet 的基本用法。但是稍微分析一下 Servlet 的用法,我们还是发现其存在很多缺点:

  ①、一个请求对应一个 Servlet,即每一个请求我们都需要在 web.xml 文件中配置映射。如果项目大,请求很多,那么会造成 web.xml 很大,很难维护。

  ②、即便在好几个请求对应一个 Servlet,即在 service() 方法中,通过 if--else 语句来判断执行的代码块。那这样就会造成 service() 方法很拥挤。

  ③、一个项目只存在一个 web.xml 文件,如果一个项目是多人开发,那么整合代码开发过程中会有很多问题。不适合团队开发。

  ④、Servlet中doGet方法和doPost方法中的两个参数reqeust,response拥有严重的容器依赖性。

  ⑤、如果页面上表单中的元素比较复杂,则在Servlet的方法中获取表单元素的数据比较繁琐。

  ⑥、Servlet是单线程的,只要在Servlet中的声明一个实例变量,那么该变量在多线程访问时就会有线程安全问题。

  ⑦、在Servlet中处理异常,如果Servlet中有N个方法,则这N个方法必须都要try--catch。因为子类抛的异常不能大于父类。

 

那么接下来我们用一个例子来解决上面的问题。

  1、新建一个 Web 工程,名为 ServletIncreased。并在 web.xml 中配置一个过滤器 ServletFilter,这个过滤器会过滤所有以 .do 结尾的 URL 链接

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xmlns="http://java.sun.com/xml/ns/javaee"

  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

   id="WebApp_ID" version="3.0">

    

  <filter>

    <filter-name>ServletFilter</filter-name>

    <filter-class>com.ys.filter.ServletFilter</filter-class>

  </filter>

  <filter-mapping>

    <filter-name>ServletFilter</filter-name>

    <url-pattern>*.do</url-pattern>

  </filter-mapping>

   

</web-app>

  2、创建一个 UserServlet,里面有两个方法,insert()和update()方法,调用 insert() 方法会跳转到 insert.jsp 页面,调用 update() 方法会调转到 update.jsp 页面

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

package com.ys.servlet;

 

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class UserServlet {

    //用户插入方法

    public void insert(HttpServletRequest req,HttpServletResponse resp) throws Exception, IOException{

        req.getRequestDispatcher("insert.jsp").forward(req, resp);

    }

     

    //用户更新方法

    public void update(HttpServletRequest req,HttpServletResponse resp) throws Exception, IOException{

        req.getRequestDispatcher("update.jsp").forward(req, resp);

    }

     

}

  3、创建一个配置文件类,里面存放配置文件的关系,通过一个 Map 集合,保存 Servlet 的类名和全类名

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

package com.ys.config;

 

import java.util.HashMap;

import java.util.Map;

 

public class ServletNameConfig {

    //定义一个 Servlet 配置文件,Map<key,value>

    //key:表示 Servlet 的类名

    //value:表示 Servlet 类名的全称

    public static Map<String, String> servletMap = new HashMap<>();

     

    static {

        servletMap.put("UserServlet""com.ys.servlet.UserServlet");

    }

 

}

  4、回头看我们配置的过滤器,ServletFilter

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

package com.ys.filter;

 

import java.io.IOException;

import java.lang.reflect.Method;

 

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.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.ys.config.ServletNameConfig;

 

public class ServletFilter implements Filter{

    @Override

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;

        HttpServletResponse resp = (HttpServletResponse) response;

         

        String reqURL = req.getRequestURI(); //  /ServletIncreased/UserServlet.do

        String[] strs = reqURL.split("/");

        //定义 Servlet 的全类名

        String servletAllName = null;

        if(strs[2] != null){

            //得到 请求路径的 servlet 类名

            String servletName = strs[2].substring(0, strs[2].indexOf("."));

            //根据获取的 Servlet 类名,由配置文件 ServletNameConfig 里面的map 得到 全类名

            servletAllName = ServletNameConfig.servletMap.get(servletName);

        }

        //获取请求方法名

        String methodName = req.getParameter("method");

        System.out.println(servletAllName+"---"+methodName);

        try {

            //通过反射调用执行方法

            Class obj = Class.forName(servletAllName);

            Method method = obj.getDeclaredMethod

                    (methodName, HttpServletRequest.class,HttpServletResponse.class);

            method.invoke(obj.newInstance(), req,resp);

        catch (Exception e) {

            e.printStackTrace();

        }      

    }

 

    @Override

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override

    public void destroy() {

    }

 

}

  整体的项目结构如下:

  

然后将整个项目发布到 tomcat 服务器运行,发布的方法可以如下:

  http://www.cnblogs.com/ysocean/p/6893446.html

然后我们在浏览器输入如下链接:http://localhost:8080/ServletIncreased/UserServlet.do?method=insert

  那么就会调用 UserServlet 的 insert 方法,进而跳转到 insert.jsp 页面

  

如果我们在浏览器输入如下链接:将 insert 改为 update

   http://localhost:8080/ServletIncreased/UserServlet.do?method=update

那么就会调用 UserServlet 的update 方法,进而调转到 update.jsp 页面

  

 

 

分析:这个改进主要是配置了一个过滤器,然后通过过滤器的 doFilter() 方法,我们可以通过请求路径获得请求URL,然后通过字符串的截取方法得到 Servlet 的名称。通过配置文件保存的 Servlet类名和全类名的对应关系得到全类名;然后利用反射的原理,通过 invoke() 方法来动态调用方法。这里我们并没有解决上面所有的问题,比如严重的容器依赖性我们这里还有。如果想真正解决,请看下一篇博客:Struts2 详解

 

展开阅读全文

Git 实用技巧

11-24
这几年越来越多的开发团队使用了Git,掌握Git的使用已经越来越重要,已经是一个开发者必备的一项技能;但很多人在刚开始学习Git的时候会遇到很多疑问,比如之前使用过SVN的开发者想不通Git提交代码为什么需要先commit然后再去push,而不是一条命令一次性搞定; 更多的开发者对Git已经入门,不过在遇到一些代码冲突、需要恢复Git代码时候就不知所措,这个时候哪些对 Git掌握得比较好的少数人,就像团队中的神一样,在队友遇到 Git 相关的问题的时候用各种流利的操作来帮助队友于水火。 我去年刚加入新团队,发现一些同事对Git的常规操作没太大问题,但对Git的理解还是比较生疏,比如说分支和分支之间的关联关系、合并代码时候的冲突解决、提交代码前未拉取新代码导致冲突问题的处理等,我在协助处理这些问题的时候也记录各种问题的解决办法,希望整理后通过教程帮助到更多对Git操作进阶的开发者。 本期教程学习方法分为“掌握基础——稳步进阶——熟悉协作”三个层次。从掌握基础的 Git的推送和拉取开始,以案例进行演示,分析每一个步骤的操作方式和原理,从理解Git 工具的操作到学会代码存储结构、演示不同场景下Git遇到问题的不同处理方案。循序渐进让同学们掌握Git工具在团队协作中的整体协作流程。 在教程中会通过大量案例进行分析,案例会模拟在工作中遇到的问题,从最基础的代码提交和拉取、代码冲突解决、代码仓库的数据维护、Git服务端搭建等。为了让同学们容易理解,对Git简单易懂,文章中详细记录了详细的操作步骤,提供大量演示截图和解析。在教程的最后部分,会从提升团队整体效率的角度对Git工具进行讲解,包括规范操作、Gitlab的搭建、钩子事件的应用等。 为了让同学们可以利用碎片化时间来灵活学习,在教程文章中大程度降低了上下文的依赖,让大家可以在工作之余进行学习与实战,并同时掌握里面涉及的Git不常见操作的相关知识,理解Git工具在工作遇到的问题解决思路和方法,相信一定会对大家的前端技能进阶大有帮助。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值