如果Servlet的执行流程还不清楚看下我的这个文章(图解)
https://blog.csdn.net/u010452388/article/details/80395679
核心知识点:
反射
一般我们遇到一个新的技能或者新的概念时,一般要从三个方面去问下自己(哲学中的哈哈):
1.是什么?
2.为什么?
3.怎么做?
废话不多说,咱们直接奔入主题
基础
在使用BaseServlet之前,我们先从最基本的浏览器访问服务器时,我们的操作,然后一步步进阶到BaseServlet
浏览器访问路径
下面是前台的访问路径,需要进行增删改查的功能
<a href="http://localhost:8080/webtest/addServlet">增加</a>
<a href="http://localhost:8080/webtest/delServlet">删除</a>
<a href="http://localhost:8080/webtest/addServlet">修改</a>
<a href="http://localhost:8080/webtest/addServlet">查询</a>
后台Sevlet
从上面图片可以看出,servlet和web.xml文件都冗余了,为什么这么说呢?我们现在只是四个功能,就要写四个servlet,假如前台有100种功能呢,难道我们要写100个Servlet?下面我们需要对我们现有的操作进行优化
进阶
下面我们需要想想,如何把这4个Servlet整合到一个里面去(这个阶段的目标)
一般数据都是从前台访问过来,我们可以在前台自己添加一个方法参数,然后在servlet中判断请求过来的方法,去调用servlet中指定的方法,可能有点抽象哈,下面我用图的方式讲解下
浏览器访问路径
看下下面浏览器访问的代码都修改了,访问了都是同一个Servlet,既actionServlet,以及后面携带了不同的请求参数
<a href="http://localhost:8080/webtest/actionServlet?method=add">增加</a>
<a href="http://localhost:8080/webtest/actionServlet?method=del">删除</a>
<a href="http://localhost:8080/webtest/actionServlet?method=update">修改</a>
<a href="http://localhost:8080/webtest/actionServlet?method=find">查询</a>
后台Servlet
actionServlet的核心代码
public class actionServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取请求携带的method方法参数
String methodName = request.getParameter("method");
if("add".equals(methodName)){
add();
}else if("del".equals(methodName)){
del();
}else if("update".equals(methodName)){
update();
}else if("find".equals(methodName)){
find();
}
}
//查询
private void find() {
//执行service层代码
}
//更新
private void update() {
//执行service层代码
}
//删除
private void del() {
//执行service层代码
}
//添加
private void add() {
//执行service层代码
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
到这里代码似乎已经进行了一些优化,不用再创建很多servlet了,注意,我说的是“似乎“”哈哈,因为又有问题出现在我们面前了:
1.写这么多if,代码每次运行过来要挨个去判断下,假如有100个方法,要判断100次,效率低
2.每次写一个新的方法,都要加个判断,好烦是不是?
下面开始重点,我们用BaseServlet可以解决上面两个问题
图解执行流程
高级
我们可以创建一个类,其提供的功能就是,可以调用继承此类中的任意方法,至于要调用哪个方法,由请求所带的参数决定,这样我们就不必写那么多if语句,只要把重点放在如何实现业务需求了
BaseServlet代码
需要让BaserServlet继承于HttpServlet
反射的知识:(从第二步到第四步)
第一步:先获取请求携带的方法参数值
第二步:获取指定类的字节码对象
第三步:根据请求携带的方法参数值,再通过字节码对象获取指定的方法
第四步:最后执行指定的方法
public class BaseServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 获取请求标识
String methodName = request.getParameter("method");
// 获取指定类的字节码对象
Class<? extends BaseServlet> clazz = this.getClass();//这里的this指的是继承BaseServlet对象
// 通过类的字节码对象获取方法的字节码对象
Method method = clazz.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
// 让方法执行
method.invoke(this, request, response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ActionServlet代码
从下面代码可以看出来,我们只需要写具体执行的方法即可,把重点放在业务需求上面,解决了代码冗余,各种if语句的判断
注意点:所有方法修饰符要用public,不然上面的反射获取方法时,无法获取到方法,会出现异常
public class actionServlet extends BaseServlet {
public void add(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//执行service层代码
}
public void del(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//执行service层代码
}
public void update(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//执行service层代码
}
public void find(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//执行service层代码
}
}
图解执行流程
总结
现在我们可以回答之前刚开始的三个问题了
1.是什么?
BaseServlet就是一个类
2.为什么?
因为BaseServlet可以帮我们解决代码冗余,解决创建过多的Servlet,可以让我们开发的过程只需要注重业务实现,提高工作效率
3.怎么做?
通过反射的方式实现功能