/**
* 一个实现Servlet接口的抽象类,继承该类实现业务逻辑比直接实现Servlet接口要方便许多。
* 建议看完上篇Servlet的源码分析再看这篇文章。
*/
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
{
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE);
private transient ServletConfig config;
/**
* 空的构造方法而已
*/
public GenericServlet() { }
/**
* 该类直接覆写了destroy方法,如果自定义Servlet继承该类则可以不用覆写该方法。
* 该方法已经在Servlet源码分析中说过,这里不再赘述。
*/
public void destroy() {
}
/**
* 获取参数值
* 如果是tomcat,就是获取web.xml中Servlet-initParam的参数
* Servlet接口没有的方法,但是实现方式是通过init保存ServletConfig,getServletConfig()获取配置,然后再获取参数的键值对,很好理解,
* 如果你直接实现Servlet接口,完全可以自己写一个一模一样的方法,而该类已经帮我们实现好了,这也是继承该类方便的好处之一
* @param name
* @return
*/
public String getInitParameter(String name) {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getInitParameter(name);
}
/**
* 获取参数名称列表
* @return
*/
public Enumeration<String> getInitParameterNames() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getInitParameterNames();
}
/**
* 在分析Servlet接口时,我们自己也这么写的,实际上就是模仿该类的写法,init时传进来一个,在这里可以获取
* 该类自动帮我们实现了,这也是继承该类比实现Servlet方便的好处之一。
* @return
*/
public ServletConfig getServletConfig() {
return config;
}
/**
* 获取上下文信息,都是基于ServletConfig的init和get得到的,自己也可以实现,这里方便的提供了
* @return
*/
public ServletContext getServletContext() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getServletContext();
}
/**
* 我说这个无用吧,看官方在该类中也是这么实现的
* @return
*/
public String getServletInfo() {
return "";
}
/**
* 看这个方法的实现是不是和我们在分析Servlet接口时实现的方式一样,多调用了一个init()的空方法。
* 为什么这么写?
* 如果我们继承该类也想init一些逻辑,正常来说是覆写该方法,但是我们自己覆写该方法忘了“this.config = config;”该类实现的其他很多基于config
* 的方法就会出错。
* 为了安全,该类自定义了一个方法init()在这里回调,如果我们自定义的Servlet需要init一些逻辑,就覆写init(),最好不要覆写该方法。
* 实际上覆写但是如果覆写错误
* @param config
* @throws ServletException
*/
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
/**
* 一个空方法,在“init(ServletConfig config) ”调用,自定义Servlet服务时可以覆写该方法来完成需要init的部分
* @throws ServletException
*/
public void init() throws ServletException {
}
/**
* 继承该类写Servlet服务唯一必须实现的方法,是不是方便很多
* @param req
* @param res
* @throws ServletException
* @throws IOException
*/
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
/**
* 不在赘述的一个感觉没啥用的方法,该类也帮我们实习了,不需要自己必须实现的方法。
* @return
*/
public String getServletName() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getServletName();
}
}
示例:
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class MyServlet02 extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// TODO 业务逻辑...
}
}