Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
servlet是单例多线程的。也就是说,在堆内存中只有一份servlet对象。对于每一次http请求,servlet容器会自动调用servlet对象的service()方法去开辟线程,在这个线程中根据已有的url-class关系对这个request进行处理。
servlet需要跑在web服务器上。这里使用apache-tomcat-9.0.12。
servlet流程图:
一、Servlet接口类
1.Servlet接口类及其方法
public interface Servlet
Defines methods that all servlets must implement.
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.
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
.
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.
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.
Method Summary | |
---|---|
void
|
destroy() Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. |
ServletConfig
|
getServletConfig()
Returns a |
String
|
getServletInfo()
Returns information about the servlet, such |
void
|
init(ServletConfig config)
Called by the servlet container to indicate to a servlet that the |
void
|
service(ServletRequest req,
Called by the servlet container to allow the servlet to respond to |
Servlet特性:
1.Servlet是单例多线程的,一个Servlet实例就是一次请求;
2.一个Servlet实例只会执行一次无参构造方法和init方法,并且是在第一次访问时执行;
3.一个Servlet实例只会执行一次destroy方法,并且在应用停止时销毁;
4.一个Servlet实例可以执行多个service,每当有用户请求发生,就会执行一次service方法;
5.Servlet是单例(单例模式)多线程的,所以为了线程安全,不为其设置成员变量,以避免线程间篡改成员变量;
6.默认情况下,Servlet在web容器启动时是不会被实例化的;
2.Servlet生命周期测试
package com.servlets; import java.io.IOException; import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; /**
* servlet的生命周期
* @author apple
* @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5
* @see javax.servlet.Servlet
* @see javax.servlet.ServletConfig
*/
public class ServletLifeCircleDemo implements Servlet { public ServletLifeCircleDemo() {
System.out.println(" 1.执行构造方法......");
} @Override
public void init(ServletConfig init) throws ServletException {
System.out.println(" 2.初始化......");
} @Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println(" 3.接受并处理请求......"); // 两个方法
ServletConfig servletConfig = this.getServletConfig();
System.out.println(servletConfig); // 读取配置信息 String servletInfo = this.getServletInfo();
System.out.println(servletInfo);
} @Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
} @Override
public void destroy() {
System.out.println(" 销毁: destroy");
} }
Servlet接口方法测试
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<servlet>
<servlet-name>Servlet-Life-Circle</servlet-name>
<servlet-class>com.servlets.ServletLifeCircleDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet-Life-Circle</servlet-name>
<url-pattern>/servletLifeCircle</url-pattern>
</servlet-mapping>
</web-app>
web.xml
启动并访问http://localhost:8080/servletLifeCircle。后台依次打印上述信息。也就是说,整个流程是constructor实例化servlet --> 执行init函数 --> 执行service方法。在整个服务关闭或停止时,会最后执行destroy方法。这里getServletConfig()和getServletInfo()返回null是因为重写了接口设定返回值为null。
service是自动调用的,对外提供的请求和相应处理的方法。
1.执行构造方法......
2.初始化......
3.接受并处理请求......
null
null
服务器打印结果
二、ServletConfig接口类
1.ServletConfig接口类及其方法
public interface ServletConfig
A servlet configuration object used by a servlet container to pass information to a servlet during initialization.
Method Summary | |
---|---|
String
|
getInitParameter(String name) Returns a String containing the value of thenamed initialization parameter, or null ifthe parameter does not exist. |
Enumeration
|
getInitParameterNames()
Returns the names of the servlet's initialization parameters |
ServletContext
|
getServletContext()
Returns a reference to the |
String
|
getServletName()
Returns the name of this servlet instance. |
servlet容器会在实例化Servlet对象后,立刻调用init()方法,前面可以看到Servlet.init()传入的参数就是ServletConfig对象。ServletConfig负责读取web.xml内容,并交给init进行初始化配置。
this.config.getInitParameter和this.config.getInitParameterNames是获取单个url请求的配置信息。它返回的是String或者Enumeration。
this.config.getServletContext()是获取全局的配置信息。它返回的是一个ServletContext对象,该对象有一堆方法。
2.ServletConfig演示
package com.servlets; import java.io.IOException;
import java.util.Enumeration; import javax.servlet.*; /**
* @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletConfig
* ServletConfig提供了四个方法,它主要用于读取配置信息
* 一个Servlet对应一个ServletConfig
*/
public class ServletConfigDemo implements Servlet { private ServletConfig config;
@Override
public void init(ServletConfig config) throws ServletException {
// servlet容器将ServletConfig传递了进来,为了使用config,在初始化的时候把它赋给成员变量
this.config = config;
System.out.println("config = " + this.config);
} @Override
public ServletConfig getServletConfig() {
return config;
} @Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// 在service中测试config的方法,总共就四个
// 1.测试getServletName()
String servletName = config.getServletName();
System.out.println("servlet name = " + servletName); // 2.测试getServletContext()
ServletContext servletContext = config.getServletContext();
System.out.println("servlet context = " + servletContext); // 3.测试getInitParameterNames()方法
Enumeration<String> names = config.getInitParameterNames();// 获取所有的配置的name
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = config.getInitParameter(name); // 4.测试getInitParameter()方法
System.out.println("init-param: name=" + name + ", " + "value=" + value);
}
} @Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
} @Override
public void destroy() {
// TODO Auto-generated method stub } }
ServletConfig测试
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<servlet>
<servlet-name>Servlet-Config</servlet-name>
<servlet-class>com.servlets.ServletConfigDemo</servlet-class>
<init-param>
<param-name>name</param-name>
<param-value>Jan</param-value>
</init-param>
<init-param>
<param-name>age</param-name>
<param-value>20</param-value>
</init-param>
<init-param>
<param-name>gender</param-name>
<param-value>female</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Servlet-Config</servlet-name>
<url-pattern>/servletConfig</url-pattern>
</servlet-mapping>
</web-app>
web.xml
servletConfig的配置在web.xml中是由<init-param>标签实现的,<init-param>标签需要写在<servlet>标签中。因此,我们可以给每一个url视图都写上请求前的配置。但是url请求彼此之间是访问不到各自的servletConfig的。
启动服务并访问http://localhost:8080/servletConfig,可以看到如下信息。
servlet name = Servlet-Config
servlet context = org.apache.catalina.core.ApplicationContextFacade@202520aa
init-param: name=gender, value=female
init-param: name=name, value=Jan
init-param: name=age, value=20
服务器打印结果
三、ServletContext
既然有了每个url请求的servletConfig配置。就有所有servlet的全局配置,其里面放置的键值对都能够被所有url请求共享,这个接口就是ServletContext。
前面可以看到,ServletConfig对象是由servlet容器自动传递给init函数的。ServletConfig包含的三个方法:getInitParameter()和getInitParameters()、getServletContext()。前两个是单个的url请求配置,由web.xml中的<servlet>标签下的<init-param>标签设置。后一个是全局的属性配置,由web.xml中的<context-param>标签直接配置。
1.ServletContext接口类及其方法
public interface ServletContext
Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog
and possibly installed via a .war
file.)
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
The ServletContext
object is contained within the ServletConfig
object, which the Web server provides the servlet when the servlet is initialized
Method Summary | |
---|---|
Object
|
getAttribute(String name) Returns the servlet container attribute with the given name, or null if there is no attribute by that name. |
Enumeration
|
getAttributeNames()
Returns an |
ServletContext
|
getContext(String uripath)
Returns a |
String
|
getContextPath()
Returns the context path of the web application. |
String
|
getInitParameter(String name)
Returns a |
Enumeration
|
getInitParameterNames()
Returns the names of the context's initialization parameters as an |
int
|
getMajorVersion()
Returns the major version of the Java Servlet API that this |
String
|
getMimeType(String file)
Returns the MIME type of the specified file, or |
int
|
getMinorVersion()
Returns the minor version of the Servlet API that this |
RequestDispatcher
|
getNamedDispatcher(String name)
Returns a |
String
|
getRealPath(String path)
Returns a |
RequestDispatcher
|
getRequestDispatcher(String path)
Returns a |
URL
|
getResource(String path)
Returns a URL to the resource that is mapped to a specified |
InputStream
|
getResourceAsStream(String path)
Returns the resource located at the named path as |
Set
|
getResourcePaths(String path)
Returns a directory-like listing of all the paths to resources within the web application whose longest sub-path |
String
|
getServerInfo()
Returns the name and version of the servlet container on which |
Servlet
|
getServlet(String name)
Deprecated. As of Java Servlet API 2.1, with no direct replacement. This method was originally defined to retrieve a servlet In lieu of this method, servlets can share information using the |
String
|
getServletContextName()
Returns the name of this web application corresponding to this ServletContext as specified in the deployment |
Enumeration
|
getServletNames()
Deprecated. As of Java Servlet API 2.1, with no replacement. This method was originally defined to return an |
Enumeration
|
getServlets()
Deprecated. As of Java Servlet API 2.0, with no replacement. This method was originally defined to return an |
void
|
log(Exception exception,
Deprecated. As of Java Servlet API 2.1, use This method was originally defined to write an |
void
|
log(String msg)
Writes the specified message to a servlet log file, usually |
void
|
log(String message,
Writes an explanatory message and a stack trace |
void
|
removeAttribute(String name)
Removes the attribute with the given name from |
void
|
setAttribute(String name,
Binds an object to a given attribute name in this servlet context. |
一个web应用对应一个ServletContext对象,所有的servlet(这里指url)共享这个对象。
ServletContext对象既是全局的,包含了一些信息,又提供一个域属性空间,供我们用来设置一些参数和值。即setAttribute、getAttribute、removeAttribute。
2.ServletContext演示
package com.servlets; import javax.servlet.*;
import java.io.IOException; /**
* @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletContext
* 一个应用对应一个servletContext,servletContext的别名又叫做application context
* 所有的servlet共享一个servletContext
* servletContext内的属性是全局性的,称为域属性空间
*/
public class ServletContextDemo2 implements Servlet { private ServletConfig config; @Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config = servletConfig; } @Override
public ServletConfig getServletConfig() {
return null;
} @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { ServletContext context = config.getServletContext(); // 3.测试servletContext的域属性设置信息
String mobile = (String) context.getAttribute("mobile");
System.out.println("Context params: " + "mobile=" + mobile);
String email = (String) context.getAttribute("email");
System.out.println("Context params: " + "email=" + email); // 4.重置或删除域属性的值
context.setAttribute("mobile", "7654321");
context.removeAttribute("email"); // 5.测试getContextPath()方法
String contextPath = context.getContextPath();// 应用的名称,也就是servlet-app,这里不知道为什么没有显示
System.out.println("contextPath=" + contextPath);
String realPath = context.getRealPath("/images");
System.out.println("realPath=" + realPath); } @Override
public String getServletInfo() {
return null;
} @Override
public void destroy() { }
}
ServletContextDemo2
package com.servlets; import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration; /**
* @see http://tool.oschina.net/apidocs/apidoc?api=javaEE5, ServletContext
* 一个应用对应一个servletContext,servletContext的别名又叫做application context
* 所有的servlet共享一个servletContext
* servletContext内的属性是全局性的,是由web.xml中的context-param配置的
* 此外它有一个全局的域属性,称为域属性空间,在域属性里可以设置属性值
*/
public class ServletContextDemo1 implements Servlet { private ServletConfig config; @Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config = servletConfig; } @Override
public ServletConfig getServletConfig() {
return null;
} @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { // 测试context的方法
ServletContext context = config.getServletContext(); // 1.测试context-param的配置信息ServletContext
Enumeration<String> names = context.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = context.getInitParameter(name);
System.out.println(name + " = " + value);
} // 2.设置域属性,先访问servletContext,设置了这个属性;再访问servletConfig,发现已经有了这个属性
context.setAttribute("email", "xxx@qq.com");
context.setAttribute("mobile", "13041234123"); } @Override
public String getServletInfo() {
return null;
} @Override
public void destroy() { }
}
ServletContextDemo1
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <context-param>
<param-name>author</param-name>
<param-value>Zhang</param-value>
</context-param>
<context-param>
<param-name>date</param-name>
<param-value>2018-09-30</param-value>
</context-param>
<servlet>
<servlet-name>Servlet-Context-1</servlet-name>
<servlet-class>com.servlets.ServletContextDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet-Context-1</servlet-name>
<url-pattern>/servletContext1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Servlet-Context-2</servlet-name>
<servlet-class>com.servlets.ServletContextDemo2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Servlet-Context-2</servlet-name>
<url-pattern>/servletContext2</url-pattern>
</servlet-mapping> </web-app
web.xml
启动服务,访问路径即结果如下:
// 第一次访问http://localhost:8080/servletContext2
Context params: mobile=null
Context params: email=null
contextPath=
realPath=/Users/apple/eclipse-workspace/servlet-partOne/out/artifacts/servletLifeCircle_war_exploded/images // 访问http://localhost:8080/servletContext1
date = 2018-09-30
author = Zhang // 第二次访问http://localhost:8080/servletContext2
Context params: mobile=13041234123
Context params: email=xxx@qq.com
contextPath=
realPath=/Users/apple/eclipse-workspace/servlet-partOne/out/artifacts/servletLifeCircle_war_exploded/images
服务器访问及打印结果
这里Context Path=空是因为IDEA中的Deployment对话框下的Application context设置成了 "/",输入"/servlet-parthOne"会有相对路径。
四、将Servlet写成HttpServlet
1.通过抽象类将service和Servlet进行解耦
如果直接每次继承Servlet类然后在service写业务逻辑太危险了。init()、getServletConfig()都需要自己去写。
此时可以写一个抽象类继承Servlet,在该抽象类中实现其余四个方法,只将service定义为抽象方法。子类直接继承这个抽象,并且只需重写service方法就好了。
import javax.servlet.*;
import java.io.IOException; /**
* "适配器设计模式": 在子类和接口类添加一层抽象类。抽象类实现接口类定义的部分方法,从而子类不必实现所有的接口类方法。
*/
public abstract class GenericServlet implements Servlet {
// 同样把config存到成员变量里,子类通过getServletConfig方法来获取config
private ServletConfig config;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config = servletConfig;
}
@Override
public ServletConfig getServletConfig() {
return config;
} // 把service写为抽象方法,并把该实现类定义为抽象类。在此抽象类中实现其它的接口方法,而不实现service这个抽象方法。
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException; @Override
public String getServletInfo() {
return null;
} @Override
public void destroy() { }
}
GenericServlet
子类继承GenericServlet。
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException; public class SubServletDemo extends GenericServlet {
// 子类只需要实现service就行了
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("执行servletDemo"); ServletConfig config = this.getServletConfig(); // 获取config
// System.out.println(config);
System.out.println(
"name=" + config.getInitParameter("name") +
", age=" + config.getInitParameter("age")
); }
}
SubServletDemo
2.重写servletConfig方法
在上例中,config.getInitParameter()等价于this.getServletConfig().getInitParameter(),由于GenericService没有实现这个方法,所以又需要访问init中传入的config的方法。为了保持各个service的独立性,应该让GenericService中继承servletConfig并重写其中的四个方法。
import javax.servlet.*;
import java.io.IOException;
import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig {
// 同样把config存到成员变量里,子类通过getServletConfig方法来获取config
private ServletConfig config;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
this.config = servletConfig;
init();// 启动子类的init初始化设置
} // "模板方法设计模式"
// 让子类用这个init
public void init(){} @Override
public ServletConfig getServletConfig() {
return config;
} // 把service写为抽象方法,并把该实现类定义为抽象类。在此抽象类中实现其它的接口方法,而不实现service这个抽象方法。
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException; @Override
public String getServletInfo() {
return null;
} @Override
public void destroy() { } // 直接继承重写ServletConfig的四个方法
@Override
public String getServletName() {
return config.getServletName();
} @Override
public ServletContext getServletContext() {
return config.getServletContext();
} @Override
public String getInitParameter(String s) {
return config.getInitParameter(s);
} @Override
public Enumeration<String> getInitParameterNames() {
return config.getInitParameterNames();
}
}
GenericServlet
同时,为了不破坏init(ServletConfig config)函数,再重载一个init()给子类用即可。这样能保证在serlvet实例化时,同样使子类(service处理类)也能够*的初始化。
3.GET请求和POST请求解耦
前面SubServletDemo继承了自己写的抽象父类GenericServlet(继承了Servlet和ServletConfig),并且实现了父类service方法。如果需要根据GET请求和POST请求分开处理,需要改写成这样:
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; public class LoginServlet extends GenericServlet{
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("login HttpServletBase ......"); // 获取请求方式
HttpServletRequest request = (HttpServletRequest) servletRequest; // 强转
HttpServletResponse response = (HttpServletResponse) servletResponse; String method = request.getMethod();
System.out.println("method=" + method); // 定义get和post方法,用来调用不同的处理方式
if("GET".equals(request)){
doGet(request, response);
}else if("POST".equals(response)){
doPost(request, response); } } private void doPost(HttpServletRequest request, HttpServletResponse response) {
System.out.println("POST 提交......");
} private void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println("GET 提交");
} }
SubServletDemo
显然这种写法有些陋。我们进行如下改写,并将SubServletDemo重命名为HttpServlet。
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; /*
"模板设计模式":以后只用doPost或者doGet来处理get请求或者post请求
*/
public class HttpServlet extends GenericServlet {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("login HttpServletBase ......"); // 获取请求方式
HttpServletRequest request = (HttpServletRequest) servletRequest; // 强转
HttpServletResponse response = (HttpServletResponse) servletResponse; service(request, response); } public void service(HttpServletRequest request, HttpServletResponse response){
String method = request.getMethod();
System.out.println("method=" + method); if ("GET".equals(request)) {
doGet(request, response);
} else if ("POST".equals(response)) {
doPost(request, response);
}
} //
public void doPost(HttpServletRequest request, HttpServletResponse response) { }
public void doGet(HttpServletRequest request, HttpServletResponse response) {
}
}
HttpServlet
最后写一个只有GET请求和POST请求的处理类,让它继承HttpServlet:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet{ public void doPost(HttpServletRequest request, HttpServletResponse response) {
System.out.println("POST 提交......");
} public void doGet(HttpServletRequest request, HttpServletResponse response) {
System.out.println("GET 提交");
} }
SubServletDemo
五、GenericServlet和HttpServlet
上一节手动写了一遍GenericServlet.class和HttpServlet.class。实际上,在serlvet中导入javax.servlet.http.HttpServlet直接使用即可:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; /*
直接使用javax.HttpServletBase.http.HttpServletBase
*/
public class LoginServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("GET 提交......");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("POST 提交......");
}
}
SubServletDemo
1.GenericServlet类
public abstract class GenericServletextends Objectimplements Servlet, ServletConfig, Serializable
Defines a generic, protocol-independent servlet. To write an HTTP servlet for use on the Web, extend HttpServlet
instead.
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
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.
To write a generic servlet, you need only override the abstract service
method.
Method Summary | |
---|---|
void
|
destroy() Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. |
String
|
getInitParameter(String name)
Returns a |
Enumeration
|
getInitParameterNames()
Returns the names of the servlet's initialization parameters |
ServletConfig
|
getServletConfig()
Returns this servlet's |
ServletContext
|
getServletContext()
Returns a reference to the |
String
|
getServletInfo()
Returns information about the servlet, such as |
String
|
getServletName()
Returns the name of this servlet instance. |
void
|
init()
A convenience method which can be overridden so that there's no need |
void
|
init(ServletConfig config)
Called by the servlet container to indicate to a servlet that the |
void
|
log(String msg)
Writes the specified message to a servlet log file, prepended by the |
void
|
log(String message,
Writes an explanatory message and a stack trace |
abstract void
|
service(ServletRequest req,
Called by the servlet container to allow the servlet to respond to |
与第四节写的GenericServlet几乎一致。
2.HttpServlet类
public abstract class HttpServlet extends GenericServletimplements Serializable
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 requestsdoPost
, for HTTP POST requestsdoPut
, for HTTP PUT requestsdoDelete
, for HTTP DELETE requestsinit
anddestroy
, to manage resources that are held for the life of the servletgetServletInfo
, 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 do
XXX methods listed above).
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.
Method Summary | |
---|---|
protected void
|
doDelete(HttpServletRequest req, HttpServletResponse resp) Called by the server (via the service method)to allow a servlet to handle a DELETE request. |
protected void
|
doGet(HttpServletRequest req,
Called by the server (via the |
protected void
|
doHead(HttpServletRequest req,
Receives an HTTP HEAD request from the protected |
protected void
|
doOptions(HttpServletRequest req,
Called by the server (via the |
protected void
|
doPost(HttpServletRequest req,
Called by the server (via the |
protected void
|
doPut(HttpServletRequest req,
Called by the server (via the |
protected void
|
doTrace(HttpServletRequest req,
Called by the server (via the |
protected long
|
getLastModified(HttpServletRequest req)
Returns the time the |
protected void
|
service(HttpServletRequest req,
Receives standard HTTP requests from the public |
void
|
service(ServletRequest req,
Dispatches client requests to the protected |
上节只实现了doGet和doPost,但是逻辑都是相同的。