首页 > 代码库 > Servlet

Servlet

大纲:

1.什么是Servlet

2.三种实现Servlet的方式

3.Servlet生命周期

4.Servlet的三个细节

5.ServletContext域

6.通过ServletConfig来获取web.xml的相关Servlet的配置

7.Servlet访问流程(注意有一步反射)

1.什么是Servlet?

  Servlet是JavaWeb的三大组件之一,属于动态资源。Servlet的作用是处理请求,服务器会把收到的请求交给Servlet处理,在使用Servlet之前,是使用Tomcat的方式接收浏览器的请求并进行处理,Servlet主要完成三项任务:接收请求数据、处理请求、完成相应。

  Servlet其实也是一个类,但是与普通的类有所不同,普通类由程序员创建new实例之后使用,Servlet类则由服务器调用。

2.三种实现Servlet的方式

2-1实现Servlet接口

Servlet接口的方法如下:

public interface Servlet {
    public void init(ServletConfig config) throws ServletException;
    public ServletConfig getServletConfig();
    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;
    public String getServletInfo();
    public void destroy();
}

编写一个类实现Servlet接口的方法:

public class HelloServlet implements Servlet {
    public void init(ServletConfig config) throws ServletException {}
    public ServletConfig getServletConfig() {return null;}
    public void destroy() {}
    public String getServletInfo() {return null;}

    public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException {
        System.out.println("hello servlet!");
    }
}
本接口中的方法大多数是逻辑方法,创建这些方法的目的是为了方便用户在遇到一些情况时进行相应的处理,比如init就是在创建Servlet出生时进行调用的一个方法,如果用户需要在Servlet
创建时进行相应的操作,就可以把代码写到Init()中。
当服务器每次接收到请求时,就会调用service方法,所以此处只在service方法中编写了相应的处理代码。

每次创建Servlet时,都需要在web.xml中添加如下代码片段。

    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>cn.itcast.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/helloworld</url-pattern> 
    </servlet-mapping>  
配置的目的:把访问路径与一个Servlet绑定在一起,通过<servlet-name>,“/helloworld”为浏览器访问路径,“<servlet-class>”为Servlet完整类名

2-2继承GenericServlet

GenericServlet.java源代码

public abstract class GenericServlet implements Servlet, ServletConfig, //在这两个接口中,Servlet有5个方法,ServletConfig有4个方法。
        java.io.Serializable {
    private static final long serialVersionUID = 1L;
    private transient ServletConfig config;
    public GenericServlet() {}
    @Override
    public void destroy() {}
    @Override
    public String getInitParameter(String name) {
        return getServletConfig().getInitParameter(name);
    }
    @Override
    public Enumeration<String> getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }
    @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }
    @Override
    public String getServletInfo() {
        return "";
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    public void init() throws ServletException {}      //有需求时重写此init(),而不重写上面那个。
    public void log(String msg) {
        getServletContext().log(getServletName() + ": " + msg);
    }
    public void log(String message, Throwable t) {
        getServletContext().log(getServletName() + ": " + message, t);
    }
    @Override
    public abstract void service(ServletRequest req, ServletResponse res)    //service()方法
            throws ServletException, IOException;
    @Override
    public String getServletName() {
        return config.getServletName();
    }
}

 

2-3继承HttpServlet(最常用)

HttpServlet.java

  HttpServlet.java中有两个service方法,使用时,先调用代码段一中的service,再调用代码段二中的service方法,代码段二中的service方法作用是根据浏览器的请求方式不同,从而调用不同的处理方法。

public abstract class HttpServlet extends GenericServlet {
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        ……
}
    @Override
    public void service(ServletRequest req, ServletResponse res)
        throws ServletException, IOException {

        HttpServletRequest  request;
        HttpServletResponse response;

        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("non-HTTP request or response");
        }
        service(request, response);      
}
}
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {

        String method = req.getMethod();    //获取浏览器用户发来的请求方式。总共有其中请求方式,常用的是post和get两种请求方式。

        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;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // 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);
        }
    }

在使用这种方式创建Servlet时,只需要重写doPost()和doGet()方法即可。

package cn.insistence;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    }

}

3.Servlet生命周期

当有人问到XXX的生命周期时,就是说XXX的出生,服务,以及死亡。Servlet的生命周期也是如此,Servlet的生命周期方法总共有三个,分别是:

1.void init()

4.Servlet的三个细节

5.ServletContext域

6.通过ServletConfig来获取web.xml的相关Servlet的配置

7.Servlet访问流程(注意有一步反射)

publicinterface Servlet {

    publicvoid init(ServletConfig config) throws ServletException;

    public ServletConfig getServletConfig();

    publicvoid service(ServletRequest req, ServletResponse res)

            throws ServletException, IOException;

    public String getServletInfo();

    publicvoid destroy();

}

Servlet