JavaWeb-BaseServlet的抽取

1. 一个模块对应一个Servlet

在实际的项目开发中,一个模块一般只使用一个 Servlet 程序。

而我们以前往往根据一个功能写一个 Servlet,比如给用户注册功能写一个 RegistServlet,再给用户登录功能写一个 LoginServlet,事实上,我们完全可以将 用户注册功能 和 用户登录功能 封装为一个用户模块,然后给这个模块写一个单独的 UserServlet,我们接下来看看如何操作。

在这里插入图片描述
这里我们需要在前端使用 hidden 属性的 <input> 标签:

login.html 页面中:

<form action="userServlet" method="post">
	
	<!-- 核心:添加 input:hidden标签 -->
	<input type="hidden" name="action" value="login">
	
	<label>用户名称:</label>
	<input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" />
	<label>用户密码:</label>
	<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" />
	<input type="submit" value="登录" id="sub_btn" />
</form>

regist.html 页面中:

<form action="userServlet" method="post">

	<!-- 核心:添加 input:hidden标签 -->
	<input type="hidden" name="action" value="regist">

	<label>用户名称:</label>
	<input class="itxt" type="text" placeholder="请输入用户名"
		   autocomplete="off" tabindex="1" name="username" id="username" />

	<label>用户密码:</label>
	<input class="itxt" type="password" placeholder="请输入密码"
		   autocomplete="off" tabindex="1" name="password" id="password" />
	
	<label>确认密码:</label>
	<input class="itxt" type="password" placeholder="确认密码"
		   autocomplete="off" tabindex="1" name="repwd" id="repwd" />

	<label>电子邮件:</label>
	<input class="itxt" type="text" placeholder="请输入邮箱地址"
		   autocomplete="off" tabindex="1" name="email" id="email" />

	<label>验证码:</label>
	<input class="itxt" type="text" name="code" style="width: 150px;" id="code"/>
	<img alt="" src="static/img/code.bmp" style="float: right; margin-right: 40px">

	<input type="submit" value="注册" id="sub_btn" />
</form>

将这两个功能统一封装用户模块中,对应到 UserServlet

public class UserServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();
	
	/**
	* 处理注册的功能
	* @param req
	* @param resp
	*/
	protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 1. 获取参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String code = req.getParameter("code");

        // 2. 检查 验证码是否正确
        if ("abcde".equalsIgnoreCase(code)) {
            if (userService.existsUserName(username)) {
                System.out.println("用户名[ " + username + " ]已存在!");
                req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);
            } else {
                userService.registerUser(new User(null, username, password, email));
                req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req, resp);
            }
        } else {
            System.out.println("验证码[ " + code + " ]错误");
            req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);
        }
	}

	/**
	* 处理登录的功能
	* @param req
	* @param resp
	*/
	protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String username = req.getParameter("username");
        String password = req.getParameter("password");

        User user = userService.login(new User(null, username, password, null));

        if (user == null) {
            System.out.println("用户名或密码错误,登录失败!");
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req, resp);
        } else {
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req, resp);
        }
	}
	
	// 一个函数进行不同任务派遣
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String action = req.getParameter("action");
       
       if ("login".equals(action)) {
       		login(req, resp);
       } else if ("regist".equals(action)) {
       		regist(req, resp);
       }
    }
}

2. 使用反射优化大量 else if 代码

但是,目前用户模块只有登录和注册两个功能,随着项目的跟进,以后用户模块可能还会有:添加用户、修改用户信息、修改密码、绑定手机号、绑定邮箱、注销用户…等等的方法,那么以后每新加一个方法,我们都要在 doPost 中增加一个 else if 的判断,那么我们是否可以想一种方法,doPost 中的代码我们就一次性写好,以后我们不管新加了什么功能,doPost 都可以自动调用相应的方法呢?

其实有一个规律,如果 action 的值为 login,那么 doPost 调用的方法就是 login(req, resp) 方法,如果 action 的值为 regist,那么 doPost 调用的方法就是 regist(req, resp) 方法。那么,我们可以直接利用反射机制,调用 action 对应的方法名的方法即可。

利用反射机制实现 doPost 自动派发任务:

public class UserServlet extends HttpServlet {

   	private UserService userService = new UserServiceImpl();

	// 处理注册的功能
	protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 处理注册的逻辑
	}

	// 处理登录的功能
	protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 处理登录的逻辑...
	}
	
	// 一个函数进行不同任务派遣
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String action = req.getParameter("action");
       
       try {
       		// 获取aciton业务鉴别字符串,获取响应的业务方法反射对象
       		Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
       		// 调用目标业务方法
       		method.invoke(this, req, resp);
       } catch (Exception e) {
       		e.printStackTrace();
       }
   
    }
}

3. 抽取 BaseServlet 程序

事实上,我们目前仅仅写了一个包含自动派发任务的 doPost方法的 UserServlet 程序,而在一个项目中。除了用户模块,我们可能还会有 图书模块、订单模块 等不同的模块,我们也需要在这些模块中定义不同的功能方法。

那么,我们可以将 UserServlet 中的 doPost 方法逻辑复用,抽取成为一个公共的 BaseServlet 类,以后如果想要开发一个新的模块,只需要先继承这个类,然后直接写对应的方法即可。

在这里插入图片描述

提取出来的 BaseServlet 类:

// 这里作为一个抽象类,是为了防止被实例化
public abstract class BaseServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String action = req.getParameter("action");
		
		try {
			// 获取aciton业务鉴别字符串,获取响应的业务方法反射对象
       		Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
       		// 调用目标业务方法
       		method.invoke(this, req, resp);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

修改 UserServlet 程序继承 BaseServlet 类,以后只用专注于写业务代码即可:

public class UserServlet extends BaseServlet {

   	private UserService userService = new UserServiceImpl();

	// 处理注册的功能
	protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 处理注册的逻辑
	}

	// 处理登录的功能
	protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 处理登录的逻辑...
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

铁头娃撞碎南墙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值