够了--Servlet面试看这一篇就够了!

本文详细解释了Servlet在Web服务器中的工作原理,包括Servlet接口的定义及其关键方法如init(),service(),和destroy()。特别关注了HttpServlet的特性和doGet(),doPost()方法,以及ServletContext的作用和使用示例。
摘要由CSDN通过智能技术生成

1.什么是servlet

servlet是运行在web服务器上的程序,它能接收和处理用户的请求,向用户返回数据。

2.Servlet接口

Servlet 是一个接口,它定义了如下几种方法。

public interface Servlet{
	//servlet的初始化方法,在servlet整个生命周期中只执行一次,如果顺利执行,则将serlvet实例放入servlet容器中;
	//否则抛出异常,servlet实例创建失败。
	//同时传入一个servletConfig配置对象, 能够获取当前servlet的配置信息。
	public void init(ServletConfig config);
	//获取当前servlet所对应的servletConfig对象,这个config对象是由Tomcat创建的。
	public ServletCongig  getServletConfig();
	//处理用户请求的核心方法。
	public void service(ServletRequest req, ServletResponse res);
	//获取当前servlet的基本信息
	public String getServletInfo();
	//销毁方法,在项目在服务器上关闭时执行。
	public void destroy();
}

3.Servlet的生命周期所执行的方法

1. 初始化方法,默认为空实现。
2. init()方法,
3. service()方法
4. destory()方法

方法1,2顺利执行后,servlet对象才能被顺利创建。方法3在servlet对象被创建后才能调用。方法4在工程关闭时被调用,销毁servlet对象。

4.Servlet接口的继承关系

在这里插入图片描述
总体来说,GenericServlet抽象类实现了Servlet接口,HttpServlet抽象类继承了GenericServlet
在这里插入图片描述

4.1 GenericServlet

GenericServlet类不仅实现了Servlet接口,还实现了ServletConfig接口,在属性中声明了ServletConfig对象:

private transient ServletConfig config;//每个servlet对象对对应一个config

主要方法如下:

① init方法

public void init(ServletConfig config) throws ServletException {
	this.config = config;//接受服务器传给的config对象,给config属性赋值。
	this.init();//init()无参初始化函数,它是一个空实现。
    }

② service抽象方法

public abstract void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;//抽象方法等待继承它的子类去实现

③ getServletContext方法

public ServletContext getServletContext() {
        ServletConfig sc = getServletConfig();
        return sc.getServletContext();
    }

该方法通过服务器传入的ServletConfig对象调用getServletContext()方法获取ServletContext上下文对象。

④ getServletName方法

public String getServletName() {
        ServletConfig sc = getServletConfig();
        return sc.getServletName();//默认返回当前servlet的类名
    }

4.2 HttpServlet

HttpServletGenericServlet的子类。
在这里插入图片描述
主要方法如下:

① service()方法

protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < lastModified) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
            
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);
            
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
            
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
            
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

该方法将客户端请求分发给不同的请求类型对应的方法去处理。主要关注doGet()方法和doPost()方法。

② doGet()方法

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }

当请求类型是Get时,调用该方法,在HttpServlet中该方法并没有具体的实现,只是负责处理错误和异常,需要继承它的子类去重写该方法。

③ doPost()方法

protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_post_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }

当请求类型是Post时,调用该方法,在HttpServlet中该方法并没有具体的实现,只是负责处理错误和异常,需要继承它的子类去重写该方法。

5.ServletContext接口

ServletContext上下文对象提供了一系列方法用于不同servlet对象之间的交流,整个工程中只存在唯一一个ServletContext实例。它提供了丰富的方法来操作web工程和servlet对象。
在这里插入图片描述
ServletContext的四个作用。
1.读取web.xml中声明的context上下文参数 context-param
2. 获取当前的工程路径
3. 获取当前工程在物理磁盘上的绝对路径
4. 像Map一样存储数据

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletContext servletContext = getServletContext();
        System.out.println(servletContext);
        System.out.println(servletContext.getContextPath());//获取当前工程名
        System.out.println(servletContext.getResourcePaths("/"));//获取当前工程下面的资源目录
        System.out.println(servletContext.getRealPath("/"));//获取当前工程的物理磁盘路径
        servletContext.setAttribute("name","Xx");//参数name的值为xx, 以map的形式存入servletcontext中。
    }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        System.out.println(servletContext);
        System.out.println(servletContext.getAttribute("name"));//在另外一个servlet中可以取到name参数对应的值
    }

6.编写自己的Servlet

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = request.getParameter("user");
		String pass = request.getParameter("password");
		System.out.println(name + " " + pass);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }

创建servlet需要使用@webServlet注解标注servlet名称和要处理的请求,也可以在web.xml中配置servlet和servlet-mapping。
直接继承HttpServlet并重写doGet()doPost()方法既可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值