GenericServlet内部实现之我见

本文详细介绍了JavaWeb的动态资源Servlet的概念、作用及其实现方式,包括直接实现Servlet接口、继承GenericServlet类和继承HttpServlet类。通过具体代码示例展示了Servlet生命周期方法的使用,比较了不同实现方式的优劣,以及如何利用适配器设计模式简化Servlet接口的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先了解下什么是Servlet,Servlet是JavaWeb的三大组件之一,它属于动态资源。Servlet的作用是处理请求,     服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:  
接收请求数据  
处理请求    
完成响应

实现Servlet有三种方式:
    实现javax.servlet.Servlet接口;
    继承javax.servlet.GenericServlet类;
    继承javax.servlet.http.HttpServlet类;

第一种方式
实现javax.servlet.Servlet接口;
实现该接口需要重写里面所有的抽象方法
package cn.edu.witpt.servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletImpl implements Servlet {

private ServletConfig config;
/*
 * 生命周期方法
 * Servlet对象创建之后马上调用,并且只调用一次。
 */
@Override
public void init(ServletConfig config) throws ServletException {
    System.out.println("init");     

}

/*
 * 生命周期方法
 * 每次处理请求都会调用此方法
 */

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
    System.out.println("service");

}
/*
 * 生命周期方法
 * Servlet对象被销毁之前调用此方法,并且只调用一次。
 */
@Override
public void destroy() {
    System.out.println("destroy");

}

/*
 * 获取Servlet配置信息
 */
@Override
public ServletConfig getServletConfig() {
    System.out.println("getServletConfig");

    return config;
}

/*
 * 获取Servlet信息
 */
@Override
public String getServletInfo() {
    System.out.println("getServletInfo");
    return "在这里可以描述Servlet";
}

}

第二种方式
继承javax.servlet.GenericServlet类;
package cn.edu.witpt.servlet;

import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/*
* 继承GenericServlet类
*/
public class ServletExtendsGenericServlet extends GenericServlet{

/*
 * 需要实现的抽象方法
 */
@Override
public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
    System.out.println("对每次请求,给出对应的处理。");

}

}

对比方式一和方式二:
发现方式二实现Servlet会简单很多,接下来我们去查看GenericServlet源码。

package javax.servlet;
import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public abstract class GenericServlet implements Servlet, ServletConfig,
java.io.Serializable {

private static final long serialVersionUID = 1L;

private transient ServletConfig config;

public GenericServlet() {
    // NOOP
}

/*
 * 生命周期方法
 * Servlet对象创建之后马上调用,并且只调用一次。
 */
@Override
public void init(ServletConfig config) throws ServletException {
    this.config = config;
    this.init();
}

/*
 * 增加的方法,子类重写该方法实现自己的初始化操作。
 * 避免子类重写 init(ServletConfig config)方法时,覆盖掉config成员变量的初始化,导致出现空指针异常。
 */
public void init() throws ServletException {
    // NOOP by default
}

/*
 * 生命周期方法
 * 每次处理请求都会调用此方法,该方法未实现,子类需要根据自己的需要重写该方法。
 */
@Override
public abstract void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException;

/*
 * 生命周期方法
 * Servlet对象被销毁之前调用此方法,并且只调用一次。
 */
@Override
public void destroy() {
    // NOOP by default
}

/*
 * 获取ServletConfig对象
 */  
@Override
public ServletConfig getServletConfig() {
    return config;
}

/*
 * 获取Servlet信息
 */
@Override
public String getServletInfo() {
    return "";
}

//以下四个重写的方法为ServletConfig接口中的方法 

/*
 * 增加的方法,获取ServletName对象
 */
@Override
public String getServletName() {
    return config.getServletName();
}

/*
 * 增加的方法,根据指定参数的名字,获取对应的值.
 */
@Override
public String getInitParameter(String name) {
    return getServletConfig().getInitParameter(name);
}   
/*
 * 用来获取在web.xml中配置的所有初始化参数名称
 */
@Override
public Enumeration<String> getInitParameterNames() {
    return getServletConfig().getInitParameterNames();
}

/*
 * 本类自己定义的方法,获取ServletContext对象
 */
 @Override
public ServletContext getServletContext() {
    return getServletConfig().getServletContext();
}

public void log(String msg) {
    getServletContext().log(getServletName() + ": " + msg);
}


public void log(String message, Throwable t) {
    getServletContext().log(getServletName() + ": " + message, t);
}    

}

方式二继承GenericServlet该类,我们只需要实现 service(ServletRequest req, ServletResponse res)该方法,这样方便了我们实现Servlet接口。这种让本来不适合使用的接口变得适合使用,是适配器设计模式的体现。
什么是设计模式呢?简单来说设计模式是代码设计经验的总结,个人认为GenericServlet内部实现方式是程序设计的精华,能很好帮助我们理解面向对象的思想。因此写了这篇文章,不足之处还望不吝赐教。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值