1、为了保证前后端请求一致,在每一个Servlet类都需要编写之前的代码,怎样能封装一下,以后在每一个具体的Servlet类中不写这样的代码了,但是还是能够达到同样的效果 ?
中间添加一个父类就可以了,不让LoginServlet直接继承GenericServlet,去继承中间的父类,父类里封装好保证前后端请求一致的代码。
- 现在存在一个问题。我们通过这个父类可以知道请求是GET或者POST,那怎么让LoginServlet这种实际业务类根据请求方式做出相应的反应呢?
比如登录发GET,我们要报错,是POST,我们要实现正确的功能。
正确代码如下:HtttpServlet
public class HtttpServlet extends GenericServlet {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//将ServletRequest,ServletResponse向下转型成带有Http的接口类型
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
//为什么这里要service()方法?
this.service(request, response);
}
public void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
//从浏览器中获取请求方式
String method = request.getMethod();
if ("GET".equals(method)) {
this.doGet(request,response);
} else if("POST".equals(method)) {
this.doPost(request,response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//前台报出错误
out.print("405-应当发送GET请求");
//后台报出错误
throw new RuntimeException("405-应当发送GET请求");
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//前台报出错误
out.print("405-应当发送POST请求");
//后台报出错误
throw new RuntimeException("405-应当发送POST请求");
}
}
为什么那里service()方法里要有个this.servies()方法?
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
//将ServletRequest,ServletResponse向下转型成带有Http的接口类型
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
//为什么这里要service()方法?
this.service(request, response);
}
这个思想和前面所讲的this.init()方法是一样的。HtttpServlet继承GenericServlet,覆写了service()方法。ServletRequest req, ServletResponse res
为了识别请求方式就一定要向下转型,这是在service()方法中实现的,那子类LoginServlet继承HtttpServlet覆写servic()方法就得加一句super.service();
,这多麻烦。
所以在service()方法里调用一个普通方法,取名也叫service(),让子类去覆写这个普通方法。这样就父类中的代码运行到了,子类覆写的代码也运行到了。
上面那个根据请求方式做出相应动作是这样完成的
核心思想还是和上一个问题一样,子类覆写父类的方法,没有加super.xxx();
子类就会覆盖父类的方法。
在普通service()方法上做判断:
public void service(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
//从浏览器中获取请求方式
String method = request.getMethod();
if ("GET".equals(method)) {
this.doGet(request,response);
} else if("POST".equals(method)) {
this.doPost(request,response);
}
}
普通方法里同样的配方,再来调用两个普通方法doGet(),doPost()
,父类HtttpServlet这两个方法里面写前后端报错信息,子类LoginServlet,根据自己想要的方式,选择一个覆写真实的业务。
- 注意:因为我们的业务其实是在Servlet的service()方法里面执行,所以真正在实现业务的是HtttpServlet类,我们只是在HtttpServlet的service()方法开了一个口子,把业务可以写到别的地方去,但最终还是回到了HtttpServlet的service()方法。
作为登录业务,我希望用POST请求方式,那我就覆写doPOST()方法,里面写正常的业务。这样如果请求是GET,先会一路执行到HtttpServlet的doGet()方法,里面有报错信息,然后发现子类LoginServlet没有覆写doGet()方法,就执行父类HtttpServlet中的doGet()方法了,输出报错信息。
这种设计,就保证前后端请求一致了。不一致就报错,一致就正常执行业务。
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//前台报出错误
out.print("405-应当发送GET请求");
//后台报出错误
throw new RuntimeException("405-应当发送GET请求");
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//前台报出错误
out.print("405-应当发送POST请求");
//后台报出错误
throw new RuntimeException("405-应当发送POST请求");
}
LoginServlet.java :
public class LoginServlet extends HtttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//super.doGet(request, response); 这一句写上去就前功尽弃了
response.getWriter().print("login...");
}
}
其实我们手写的父类HtttpServlet,sun公司已经写好了,叫HttpServlet
总结:
-
编写一个Servlet类应当继承javax.servlet.http.HttpServlet,get请求请重写doGet方法,post请求请重写doPost方法
-
doPost/doGet方法可以等同看做main方法
-
当浏览器发送的请求方式和后台的处理方式不同的话,会出现一个错误, 代号: 405