文章目录
Servlet
- Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
- 狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
实现过程
- 客户端发送请求至服务器
- 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
- 服务器将响应返回客户端
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();
}
与服务器不同生,但同死
- Servlet 通过调用 init () 方法进行初始化。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 通过调用 destroy() 方法终止(结束)。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
init()方法
- 当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,就像人只能“出生”一次一样。
- Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是也可以指定 Servlet 在服务器第一次启动时被加载,这样就实现了同生同死
- 当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
service( )方法
- 每当请求Servlet时,Servlet容器就会调用这个方法。第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。
- 每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
- service() 方法由容器调用,service 方法在适当的时候调用 doGet、doPost、doPut、doDelete 等方法。所以,不用对 service() 方法做任何动作,只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可
- doGet() 和 doPost() 方法是每次服务请求中最常用的方法
- GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 或指定为get的 HTML 表单,它由 doGet() 方法处理。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Servlet 代码
}
- POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
// Servlet 代码
}
destroy() 方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
Servlet 的其它两个方法
- getServletInfo( ),这个方法会返回Servlet的一段描述,可以返回一段字符串。
- getServletConfig( ),这个方法会返回由Servlet容器传给init( )方法的ServletConfig对象。
ServletRequset接口
Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。
public interface ServletRequest {
int getContentLength();//返回请求主体的字节数
String getContentType();//返回主体的MIME类型
String getParameter(String var1);//返回请求参数的值
}
ServletResponse接口
ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法。
public interface ServletResponse {
String getCharacterEncoding();
String getContentType();
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentType(String var1);
void setBufferSize(int var1);
int getBufferSize();
void flushBuffer() throws IOException;
void resetBuffer();
boolean isCommitted();
void reset();
void setLocale(Locale var1);
Locale getLocale();
}
ServletConfig接口
封装了Servlet的配置信息,在Servlet的初始化期间被传递。init()方法将保存这个对象,以便能够用getServletConfig()方法返回。每个ServletConfig对象对应着一个唯一的Servlet。
ServletConfig对象 : 用于获取配置信息
ServletConfig servletconfig = getServletConfig(); //获取对象
方法 | 描述 |
---|---|
String getInitParameter(String name) | 根据名称获取参数值 |
Enumeration getInitParameterNames() | 返回一个 Enumeration 对象,获取当前Servlet实例中的所有参数名称 |
ServletContext getServletContext() | 返回ServletContext对象 |
String getServletName() | 返回 Servlet 的名字,即 web.xml 中 servlet-name元素的值 |
ServletContext接口
ServletContext对象表示Servlet应用程序。每个Web应用程序都只有一个ServletContext对象。在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象。
获取 ServletContext对象
- ServletContext servletContext = getServletContext();
- servletConfig.getServletContext()
1、获取对象属性的方法:
方法 | 描述 |
---|---|
Object getAttribute(String var1) | 获取Servlet环境对象中指定的属性对象 |
Enumeration getAttributeNames() | 获取当前全局已配置的属性名称的集合 |
void setAttribute(String var1, Object var2) | 设置属性和属性值 |
void removeAttribute(String var1) | 删除指定属性 |
2、获取基础信息方法
方法 | 描述 |
---|---|
String getContextPath() | 获取当前项目路径(默认是项目名称) |
String getRealPath(“/”) | 获取项目完整路径(绝对路径) |
String getVirtualServerName() | 获取项目虚拟目录 |
String getServerInfo() | 获取服务器信息 |
GenericServlet抽象类
该类定义了一个通用的、不依赖于具体协议的Servlet,他实现了Servlet接口和ServletConfig接口。
由于该类给出了除了service()方法的其他4个方法的简单实现。所以,通过继承GenericServlet来编写Servlet类,只需要实现service()方法即可。
package javax.servlet;
import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
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抽象类
HttpServlet抽象类是继承于GenericServlet抽象类而来的。
HttpServlet提供的7个处理方法:
doGet(),doPost(),doHead(),doPut(),doDelete(),doTrace(),doOptions()
(源码过长)
HttpServlet与GenericServlet比较
- HttpServlet不用覆盖service方法,而是覆盖doGet或者doPost方法。在少数情况,还会覆盖其他的5个方法。
- HttpServlet使用的是HttpServletRequest和HttpServletResponse对象。
创建Servlet
Servlet技术的核心是Servlet,它是所有Servlet类必须直接或者间接实现的一个接口。在编写实现Servlet的Servlet类时,直接实现它。在扩展实现这个这个接口的类时,间接实现它。
- 直接实现Servlet接口:实现servlet接口中所有的未实现的方法
- 继承GenericServlet:手动实现service方法
- 继承HttpServlet:重写doGet()和doPost
Servlet的转发与重定向
转发forward
- 如果请求之后希望跳转到另一个页面,转发与重定向均可以做到,如果回传时想携带信息,那么只有转发才可以
- 转发使用的是request对象,当浏览器请求到达Servlet时不会立即结束,而是等待处理完成之后继续跳转一次页面,因为request是一个作用域,故可以将信息携带参数到指定转发的页面中
- 写法:request.getResquestDispatcher(“资源路径”).forword(request,response);
- Dispatcher:派遣
- forword:转发
String msg = "你成功了";
request.setAttribute("msg", msg);
request.getRequestDispatcher("success.jsp").forward(request, response);
success.jsp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
${msg }
</body>
</html>
${msg }:通过EL表达式去接收request作用域中的值
重定向
- 当请求到达Servlet的时候,同样可以通过response对象去跳转到新的页面,但是这种跳转不能携带参数,因为response没有作用域。相当于服务端重新指定了一个新的URL,和原来的请求对象没关系
- 写法:response.sendRedirect(“资源路径”); 实质发生了新的资源定位
response.sendRedirect("success.jsp");
succes.jsp
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
你成功了
</body>
</html>
转发和重定向的区别
- 转发是客户端对象(请求对象)转发,当经过Servlet之后再转发至页面都用了一个request请求。所以相对来说服务器压力会少一些,并且能够传递参数。但是因为是一个请求,所以即使打开了新的页面但是URL也没有变化
- 重定向:当请求到达Servlet之后,如果通过重定向去跳转页面,那么之前的请求对象已经结束了。页面跳转成功后相当于服务端重新制定了一个新的URL资源位置,所以浏览器地址会变化。重定向因为发生了两次资源定位,相比转发会消耗些资源。