跳转到目录
public class AServlet implements Servlet {
private ServletConfig servletConfig;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.servletConfig = servletConfig;
}
@Override
// 把ServletConfig对象暴露给子类访问
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
String encoding = servletConfig.getInitParameter("encoding");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
public class BServlet implements Servlet {
private ServletConfig servletConfig;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.servletConfig = servletConfig;
}
@Override
// 把ServletConfig对象暴露给子类访问
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
String encoding = servletConfig.getInitParameter("encoding");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
问题:
上面的每自定义的Servlet类都得编写一些重复的代码,如此一来,我们需要重构代码,消除重复
.
解决方案:
定义MyGenericServlet,用来定义一些自定义Servlet中的重复代码.
abstract public class MyGenericServlet implements Servlet {
private ServletConfig servletConfig;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// 把tomcat传递的ServletConfig赋值给本类的成员servletConfig,就是把它保存起来,方便其他方法使用!
this.servletConfig = servletConfig;
}
@Override
public ServletConfig getServletConfig() {
return this.servletConfig;
}
@Override
abstract public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException,IOException;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
写完MyGenericServlet类后,让AServlet类和Bservlet类继承它.
public class AServlet extends MyGenericServlet {
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException,IOException{
String encoding = super.getServletConfig().getInitParameter("encoding");
}
}
问题:
此时在AServlet中的service方法获取初始化参数:
String encoding = super.getServletConfig().getInitParameter("encoding");
如果想更进一步, 想在AServlet中的service方法中,这样写:
String encoding = super.getInitParameter("encoding");
解决方案:
让MyGenericServlet实现ServletConfig接口,并实现其方法,在实现方法中让父类来完成.
@Override
public String getInitParameter(String s) {
return servletConfig.getInitParameter(s);
}
问题:
此时,如果AServlet需要做自身的初始化操作,怎么办?
应该在AServlet中覆盖init(config)方法
,并在该方法中写初始化代码
如果忘记调用父类的init方法, 就会报空指针异常
,针对于没写父类init方法,看下面的解决方案.
解决方案:
为了解决开发在做自身初始化操作的时候, 可能会忘记super.init(config)
, 需要在MyGenericServlet中,专门提供一个无参数的初始化方法: init, 专门暴露给子类用于子类做自身的初始化操作
上图的执行步骤:
obj.init(config)
, 此时Servlet1的父类(MyGenericServlet)总去找带有config参数的init方法,并调用.this.config=config
,再调用this.init();
如此一来, 就确保了子类如何完成自身的初始化操作;
跳转到目录
问题:
但是上面的Servlet1只能处理一般的请求和响应,一般B/S开发,都是基于浏览器所以要遵循HTTP协议, 所以我们应该处理HTTP类型的请求和响应,需要重新设计, 处理Http的service方法,要统一处理GET/POST请求. 提供doGet方法和doPost方法
根据上图这样处理, 每一个Servlet都得编写这么多的代码.
解决方案:
提取出一个专门用于处理HTTP协议的Servlet出来, 创建MyHttpServlet类
并继承MyGenericServlet
public class MyHttpServlet extends MyGenericServlet {
// 只能处理一般的请求
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
// 调用处理Http请求的方法
service(httpServletRequest, httpServletResponse);
}
public void service(HttpServletRequest reg, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求方式 GET/POST
String method = reg.getMethod();
if ("GET".equals(method)){
doGet(reg, resp);
} else if("POST".equals(method)){
doPost(reg, resp);
}
}
// 专门用于处理POST请求
private void doPost(HttpServletRequest reg, HttpServletResponse resp) {
System.out.println("AServlet.doPost()");
}
// 专门用于处理GET请求
private void doGet(HttpServletRequest reg, HttpServletResponse resp) {
System.out.println("AServlet.doGet()");
}
}
抽取MyHttpServlet之后,以后开发,只需要继承于MyHttpServlet即可,再提供处理请求的service/doGet/doPost方法. 这里也体现了模板方法设计模式
public class TestServlet extends HttpServlet {
@Override
public void init() throws ServletException {
// 初始化代码
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service()----");
// 不要调用父类的service
// super.service(req, resp);
}
}