其他分享
首页 > 其他分享> > Servlet详解

Servlet详解

作者:互联网

什么是Servlet

Servlet是Server Applet的缩写.

这是一项时至2020年仍在更新使用的JAVA技术.
它的出现是为了解决服务端为用户提供动态网页的问题.其实这个问题已经有一个解决方案CGI(Common Gateway Interface),但是CGI程序编写困难,响应时间长,以进程方式运行导致性能受限.所以SUN公司推出了Servlet技术来取代它.

Servlet是作为WEB浏览器或者其他HTTP客户端请求和服务器上数据库或者应用程序之间的中间层.使用Servlet,我们可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,或者动态创建页面(比如JSP就是它的一个扩展).

Servlet接口和类

这边就看JAVA EE8.0文档,然后给大家翻译一下吧.

Servlet接口

public interface Servlet
Defines methods that all servlets must implement.

Servlet接口定义了servlets必须实现的方法

A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.

一个servlet就是一个运行在Web服务器内的Java小程序.Servlets接收和响应来自Web客户端的请求(一般是通过HTTP)

To implement this interface, you can write a generic servlet that extends javax.servlet.GenericServlet or an HTTP servlet that extends javax.servlet.http.HttpServlet.

要实现这个接口,你可以继承javax.servlet.GenericServlet写一个generic servlet,或者继承javax.servlet.http.HttpServlet写一个HTTP servlet

This interface defines methods to initialize a servlet, to service requests, and to remove a servlet from the server. These are known as life-cycle methods and are called in the following sequence:
1.The servlet is constructed, then initialized with the init method.
2.Any calls from clients to the service method are handled.
3.The servlet is taken out of service, then destroyed with the destroy method, then garbage collected and finalized.

这个接口定义了一些方法,来初始化servlet,服务请求和从服务器中移除servlet.这就是著名的生命周期方法

  1. servlet被创建,然后通过init方法进行初始化
  2. 处理任何来自客户端的服务请求
  3. servlet停用,然后通过destory方法进行销毁,接着GC进行垃圾搜集清理

In addition to the life-cycle methods, this interface provides the getServletConfig method, which the servlet can use to get any startup information, and the getServletInfo method, which allows the servlet to return basic information about itself, such as author, version, and copyright.

除了生命周期方法外,这个接口还提供了getServletConfig方法,用于获取启动信息和getServeltInfo方法,获取自身的基本信息(比如作者,版本和版权)

上面这部分就是文档里,Servlet接口的说明部分,但其实还有个很重要的方法没提,这边补充一下.
void service(ServletRequest req, ServletResponse res)
Called by the servlet container to allow the servlet to respond to a request.
由servlet容器调用,使得servlet能够请求和响应.
这边得和参考资料1结合一下,servlet没有main方法,不能独立运行,必须被部署到servlet容器中,由容器来实例化和调用servlet的方法.

GenericServlet

public abstract class GenericServlet extends Object implements Servlet, ServletConfig, Serializable

可以看到这是一个抽象类

Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet instead.

定义了一个泛化,协议独立的servlet.如果要为了写一个HTTP servlet供WEB使用,可以继承HttpServlet作为替代.
换句话说仅用HTTP协议通信就直接用HttpServlet就好了,没必要浪费时间重载GenericServlet的一堆方法.

GenericServlet implements the Servlet and ServletConfig interfaces. GenericServlet may be directly extended by a servlet, although it's more common to extend a protocol-specific subclass such as HttpServlet.

GenericServlet实现了Servlet和ServletConfig接口.
GenericServlet可以被servlet直接继承,但是更常见的是继承一个明确协议的子类,像HttpServlet.

GenericServlet makes writing servlets easier. It provides simple versions of the lifecycle methods init and destroy and of the methods in the ServletConfig interface. GenericServlet also implements the log method, declared in the ServletContext interface.

GenericServlet使得写servlet更简单了.它提供了简化版的生命周期方法和ServletContig接口中的方法.同时,实现了ServletContext接口中声明的log(日志)方法.

To write a generic servlet, you need only override the abstract service method.

要写一个Generic Servlet,你只需要重载特定的抽象服务方法.

HttpServlet

public abstract class HttpServlet extends GenericServlet
继承自GenericServlet的一个抽象类

Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).

提供被子类化的一个抽象类,以创建适用于WEB网站的HTTP servlet.
一个HttpServlet的子类,必须重载至少一个方法,通常是下列之一.

2021年4月29日15:49:14 全翻太累了,直接看吧,重点记一下就好.

Likewise, there's almost no reason to override the doOptions and doTrace methods.

Servlets typically run on multithreaded servers, so be aware that a servlet must handle concurrent requests and be careful to synchronize access to shared resources. Shared resources include in-memory data such as instance or class variables and external objects such as files, database connections, and network connections. See the Java Tutorial on Multithreaded Programming for more information on handling multiple threads in a Java program.

三者关系

Servlet生命周期

Servlet接口声明的5个方法中,有3个是生命周期函数

这里的Servlet Container一般就是tomcat,可以理解为服务器.
然后,这三个生命周期函数被调用时执行的次数是不同的.

还有一点很值得注意的是,Servlet类虽然是我们写的,但却是由服务器来创建,调用的.
这点文档也反复提及,所以得划下重点.

ServletConfig

先看下文档
public interface ServletConfig
A servlet configuration object used by a servlet container to pass information to a servlet during initialization.
看了简介,可以获得两个信息

看下它的方法

然后看阿里云大学的教程

ServletRequest & ServletResponse

void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
在servlet接口的service方法中,包含两个相关接口ServletRequest和ServletResponse
看名字就知道,这是让我们在实现servlet时,传入请求,传出响应用的,看了下文档中的方法,也确实如此

由于之后我们主要继承HttpServlet进行开发,这里大致了解一下就好了
稍微看下overview吧

Defines an object to provide client request information to a servlet. The servlet container creates a ServletRequest object and passes it as an argument to the servlet's service method.
A ServletRequest object provides data including parameter name and values, attributes, and an input stream. Interfaces that extend ServletRequest can provide additional protocol-specific data (for example, HTTP data is provided by HttpServletRequest.

Defines an object to assist a servlet in sending a response to the client. The servlet container creates a ServletResponse object and passes it as an argument to the servlet's service method.
To send binary data in a MIME body response, use the ServletOutputStream returned by getOutputStream(). To send character data, use the PrintWriter object returned by getWriter(). To mix binary and text data, for example, to create a multipart response, use a ServletOutputStream and manage the character sections manually.
The charset for the MIME body response can be specified explicitly using any of the following techniques: per request, per web-app (using ServletContext.setRequestCharacterEncoding(java.lang.String), deployment descriptor), and per container (for all web applications deployed in that container, using vendor specific configuration). If multiple of the preceding techniques have been employed, the priority is the order listed. For per request, the charset for the response can be specified explicitly using the setCharacterEncoding(java.lang.String) and setContentType(java.lang.String) methods, or implicitly using the setLocale(java.util.Locale) method. Explicit specifications take precedence over implicit specifications. If no charset is explicitly specified, ISO-8859-1 will be used. The setCharacterEncoding, setContentType, or setLocale method must be called before getWriter and before committing the response for the character encoding to be used.

GenericServlet

在一开始看文档的时候,已经基本介绍了GenericServlet类的概述和方法
阿里云大学的教程又结合Tomcat源码,深入剖析了GenericServlet类是如何实现的

结合起来看,文档中说的GenericServlet实现了Servlet,ServletConfig接口,使得更易于创建Servlet,就很好理解了
可以调用方法直接获取配置信息肯定是比手动再实现一遍方法来得简单快捷的

HttpServlet

我们只需要实现HttpServlet的doPost/doGet之类的方法
Tomcat接收到请求后,会依据上图逐层进行函数调用

Servlet的细节

Servlet和反射

  1. 通过<servlet-mapping>找到url对应的servlet-name
  2. 通过<servlet>找到servlet-name对应的servlet-class
  3. 通过反射,具体说是Class.forName(),将servlet-class标签的值(字符串),找到对应的类,再通过.newInstance()创建该类实例
    1. 注意该类必须有无参构造器
    2. 之后可以通过getMethod(),获得方法,再通过invoke()对method进行调用

ServletContext

概述

获取ServletContext对象

域对象的功能

获取公共初始化参数

获取资源的方法

访问量统计

	ServletContext application = this.getServletContext();
	Integer count = (Integer)application.getAttribute("count");
	if(count == null){
		count = 1;
	} else {
		count++;
	}
	response.setContentType("text/html;charset=utf-8");
	response.getWriter().print("<h1>This website has been visited " + count + " times."</h1>);
	application.setAttribute("count",count);

获取类路径下的资源

HttpServlet优化

我们可还以对HttpServlet再进行封装,使得开发更加高效

参考资料

  1. 几个概念:Servlet、Servlet容器、Tomcat - 知乎 (zhihu.com)
  2. Java Servlet Technology Overview (oracle.com)
  3. Servlet 简介 | 菜鸟教程 (runoob.com)
  4. Java Servlet - 维基百科,自由的百科全书 (wikipedia.org)
  5. 聊聊Tomcat的架构设计 (objcoding.com)
  6. Apache Tomcat - 维基百科,自由的百科全书 (wikipedia.org)
  7. Overview (Java Platform SE 8 ) (oracle.com)
  8. Servlet入门 - 阿里云大学 - 官方网站,云生态下的创新人才工场 (aliyun.com)
  9. servlets - What is WEB-INF used for in a Java EE web application? - Stack Overflow
  10. Servlet--Context - 华为云 (huaweicloud.com)

标签:name,Servlet,GenericServlet,方法,详解,ServletContext,servlet
来源: https://www.cnblogs.com/rpish/p/14725626.html