Java基础之Servlet

本篇主要介绍Servlet,部分内容摘抄自W3Cschool,仅用作笔记。

Servlet,是Java Servlet的简称,用Java编写的服务器端程序,主要功能在于交互式地浏览和生成数据,生成动态Web内容。狭义的Servlet指Servlet接口,广义的Servlet指实现Servlet接口的实现类。

Java Servlet是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。

Servlet主要执行以下任务:

  • 读取客户端发送的显式数据,包括网页上的HTML表单或自定义的HTTP客户端程序的表单。
  • 读取客户端发送的隐式的HTTP请求数据,包括cookies、媒体类型和浏览器能理解的压缩格式等。
  • 处理数据并生成结果,此过程可能需要访问数据库,调用Web服务或直接计算得出对应的响应。
  • 发送显式的数据到客户端,该文档的格式可以是多种多样的,包括文本文件、二进制文件,Excel等。
  • 发送隐式的HTTP响应到客户端,包括告诉客户端被返回的文档类型,设置cookies和缓存参数等。

Servlet生命周期

Servlet生命周期可被定义为从创建直到毁灭的整个过程,以下是Servlet遵循的过程:

  • Servlet通过调用init()方法进行初始化;
  • Servlet调用service()方法来处理客户端请求;
  • Servlet调用destroy()方法销毁;
  • JVM垃圾收集器回收Servlet。

Servlet相关API

Servlet接口

最顶级接口就是Servlet接口了,其方法如下:

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;
    ServletConfig getServletConfig();
    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    String getServletInfo();
    void destroy();
}
  1.  init():在Servlet容器(例如tomcat)加载Servlet时会调用init()方法并会传入一个ServletConfig对象对Servlet进行初始化工作,该方法只会在加载时被调用一次;
  2. getServletConfig():获取ServletConfig对象;
  3. service():当请求到达Servlet容器时,容器会调用相应的Servlet中的service()方法,并将请求封装成一个ServletRequest对象,将响应封装成ServletResponse对象。每次请求都会调用一次该方法;
  4. getServletInfo():返回Servlet的描述信息;
  5. destroy():Servlet容器在销毁Servlet时会调用此方法。destroy()方法可以让Servlet关闭数据库连接、停止后台线程、把Cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动。在调用destroy()方法后,servlet对象被标记为垃圾回收。

ServletConfig接口

该接口提供了获取Servlet配置的一些方法,每个Servlet都有其独自的ServletConfig对象。

public interface ServletConfig {
    String getServletName();
    ServletContext getServletContext();
    String getInitParameter(String var1);
    Enumeration<String> getInitParameterNames();
}
  1. getServletName():获取当前Servlet的name,在web.xml中配置;
  2. getServletContext():获取ServletContext对象;
  3. getInitParameter(String var1):根据名称获取Servlet的初始化参数;
  4. getInitParameterNames():获取Servlet的全部初始化参数。

ServletContext接口

每个Web应用程序拥有唯一的ServletContext接口,同一个Web应用中的所有的Servlet共享一个ServletContext对象。ServletContext常用方法如下:

void setAttribute(String var1, Object var2);
Object getAttribute(String var1);
Enumeration<String> getAttributeNames();
void removeAttribute(String var1);
String getInitParameter(String var1);
Enumeration<String> getInitParameterNames();
String getRealPath(String var1);
String getContextPath();
  1. setAttribute():设置应用内的共享数据;
  2. getAttribute():根据名称获取共享数据的值;
  3. getAttributeNames():获取全部共享数据的名称;
  4. removeAttribute():根据名称移除共享数据;
  5. getInitParameter():根据名称获取全局初始化参数;
  6. getInitParameterNames():获取全部初始化参数名称;
  7. getRealPath():根据相对路径获取绝对路径;
  8. getContextPath():获取当前应用名称。

ServletRequest接口

ServletRequest类表示来自客户端的请求。当Servlet容器接收到客户端要求访问特定Servlet的请求时,容器先解析客户端的原始请求数据,把它包装成一个ServletRequest对象。当容器调用Servlet对象的service()方法时,就可以把ServletRequest对象作为参数传给service()方法。其常用方法如下:

String getParameter(String var1);
Enumeration<String> getAttributeNames();
String[] getParameterValues(String var1);
String getCharacterEncoding();
String getContentType();
ServletInputStream getInputStream() throws IOException;
String getServerName();
int getServerPort();
  1. getParameter(String var1):通过参数名称获取参数值;
  2. getAttributeNames():获取全部参数名称;
  3. getParameterValues(String var1):通过参数名称获取全部参数值;
  4. getCharacterEncoding():获取请求中正文的字符集编码;
  5. getContentType():获取请求实体的网络媒体类型;
  6. getInputStream():获取请求的二进制输入流;
  7. getServerName():获取接受请求的服务器名称;
  8. getServerPort():获取接受请求的服务器的端口号。

ServletResponse接口

String getCharacterEncoding();
String getContentType();
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
void setCharacterEncoding(String var1);
void setContentType(String var1);
void flushBuffer() throws IOException;
  1. getCharacterEncoding():获取响应中的正文的字符集编码;
  2. getContentType():获取响应实体的网络媒体类型;
  3. getOutputStream():获取响应的二进制输出流;
  4. getWriter():获取PrintWeiter对象;
  5. setCharacterEncoding(String var1):设置响应中正文的字符集编码;
  6. setContentType(String var1):设置响应实体的网络媒体类型;
  7. flushBuffer():强制将缓存中的内容发送到客户端。

GenericServlet抽象类

由于实现接口时必须要实现接口的全部方法,因此很多api中都会定义一个抽象类去实现接口并提供一些方法的默认实现,子类就可以不用实现全部方法,类似集合中的AbstractCollection、AbstractList等抽象类,GenericServlet类既是起这样的作用。

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    private static final long serialVersionUID = 1L;
    private transient ServletConfig config;

    public GenericServlet() {
    }

    public void destroy() {
    }

    public String getInitParameter(String name) {
        return this.getServletConfig().getInitParameter(name);
    }

    public Enumeration<String> getInitParameterNames() {
        return this.getServletConfig().getInitParameterNames();
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }

    public String getServletInfo() {
        return "";
    }

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }

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

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

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    public String getServletName() {
        return this.config.getServletName();
    }
}

HttpServlet抽象类

现在的很多应用程序都要依赖于HTTP协议,为了更好的使用HTTP的特性,提供了HttpServlet类。HttpServlet类继承了GenericServlet类,比GenericServlet类更强大,但依赖于HTTP协议(事实上,我们的请求都是基于HTTP协议的)。

GenericServlet类中的service()方法是抽象方法,HttpServlet中实现了该方法:

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

        this.service(request, response);
    }

在此方法中仅完成了ServletRequest到HttpServletRequest和ServletResponse到HttpServletResponse的强转,然后调用了另一个重载的service()方法

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

在重载的servlet()方法中只是解析了HttpServletRequest中的method,根据method的值调用不同的方法,这些方法也存在与HttpServlet中。常用的有doGet()和doPost()方法,分别处理get和post请求,在使用时只需重写这两个方法即可。

HttpServletRequest接口

该接口继承了ServletRequest接口,封装了HTTP请求,通过此接口可以获取请求行、请求头和请求体的数据。

//获取客户端发出请求时的完整URL
String getRequestURL();
//获取请求行中的资源名称部分
String getRequestURI();
//获取请求行中的参数部分
String getQueryString();
//获取客户端的请求方式
String getMethod();
//获取HTTP版本号
String getProtocol();
//获取webapp的名称
String getContextPath();
//根据名称获取单个请求头内容
String getHeader(String var1);
//获取全部的请求头名称
Enumeration<String> getHeaders(String var1);
//获取包含请求消息中全部参数名称和值的Map对象,此方法在ServletRequest
Map<String, String[]> getParameterMap();

HttpServletResponse接口

HttpServletResponse继承ServletResponse接口,用来封装服务器对客户端的响应。

//添加键值对到响应头信息中
void addHeader(String var1, String var2);
//编码指定的URL
String encodeURL(String var1);
//使用指定错误码发送错误到客户端
void sendError(int var1) throws IOException;
//设置指定响应头信息
void setHeader(String var1, String var2);
//设置当前响应的状态码
void setStatus(int var1);

Servlet过滤器

在Servlet中,过滤器是可用于Servlet编程的Java类,其作用如下:

  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

过滤器其实就是实现了javax.servlet.Filter接口的Java类,Filter接口定义了如下三个方法:

//初始化过滤器
default void init(FilterConfig filterConfig) throws ServletException;
//在每次一个请求/响应对因
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
//销毁此过滤器
default void destroy()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值