Servlet概述
Servlet 是 JavaEE 规范之一,规范就是接口。
Servlet 是 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
Servlet 是运行在服务器上的一个 Java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。处理结果以响应协议格式写回客户端(浏览器)。
例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理。Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。
实现Servlet的方式
实现Servlet有三种方式:
-
实现javax.servlet.Servlet接口;
-
继承javax.servlet.GenericServlet类;
-
继承javax.servlet.http.HttpServlet类;(常用形式)
Servlet快速入门
编写Servlet代码
-
在JavaWeb工程下编写一个类去实现 Servlet 接口。
-
实现 service 方法,处理请求,并响应数据。
-
到 web.xml 中去配置 servlet 程序的访问地址。
package com.coydone.servlet;
import javax.servlet.*;
import java.io.IOException;
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* service方法是专门用来处理请求和响应的
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("HelloServlet被访问了");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--servlet标签给Tomcat配置Servlet程序-->
<servlet>
<!--servlet-name标签 给servlet程序起一个别名(一般是类名)-->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class标签 是servlet程序的全类名(src下)-->
<servlet-class>com.coydone.servlet.HelloServlet</servlet-class>
</servlet>
<!--servlet-mapping 标签给Servlet程序配置访问地址-->
<servlet-mapping>
<!--servlet-name标签 作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--url-pattern标签 配置访问地址
/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径
/hello 表示地址为:http://ip:port/工程路径/hello
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
配置IDEA访问
为防止控制台乱码,在VM options 中配置 -Dfile.encoding=UTF-8
在浏览器输入url地址 http://localhost:8080/01_javaweb/hello
就可以了访问到Servlet了。
Servlet的生命周期
所谓xxx的生命周期,就是说xxx的出生、服务,以及死亡。Servlet生命周期也是如此。与Servlet的生命周期相关的方法有:
-
void init(ServletConfig);
-
void service(ServletRequest,ServletResponse);
-
void destroy();
当客户第一次请求时,首先判断是否存在servlet对象,第一次请求时不存在,则由Tomcat创建对象,调用init()方法对其初始化,用service()方法判断是post请求还是get请求,调用对应的方法返回给客户。当客户第二次请求时,还是判断是否存在servlet对象,由于之前已经创建过对象,所以直接到service()方法判断提交方式,调用对应的方法返回给客户端,当Tomcat关闭时,调用destory()方法销毁对象。
init( )
服务器会在Servlet第一次被访问时创建Servlet,或者是在服务器启动时创建Servlet。如果服务器启动时就创建Servlet,那么还需要在web.xml文件中配置。也就是说默认情况下,Servlet是在第一次被访问时由服务器创建的。
而且一个Servlet类型,服务器只创建一个实例对象,例如在我们首次访问http://localhost:8080/01_javaweb/hello
时,服务器通过“/hello”找到了绑定的Servlet名称为com.coydone.servlet.HelloServlet,然后服务器查看这个类型的Servlet是否已经创建过,如果没有创建过,那么服务器才会通过反射来创建HelloServlet的实例。当我们再次访问http://localhost:8080/01_javaweb/hello
时,服务器就不会再次创建HelloServlet实例了,而是直接使用上次创建的实例。
在Servlet被创建后,服务器会马上调用Servlet的void init(ServletConfig)方法。Servlet的生命周期中,这个方法只会被调用一次。我们可以把一些对Servlet的初始化工作放到init()方法中。
service( )
当服务器每次接收到请求时,都会去调用Servlet的service()方法来处理请求。服务器接收到一次请求,就会调用service() 方法一次,所以service()方法是会被调用多次的。正因为如此,所以我们需要把处理浏览器请求的代码写到service()方法中。
destroy( )
Servlet是不会轻易销毁的,通常都是在服务器关闭时Servlet才会离去。在服务器被关闭时,服务器会去销毁Servlet,在销毁Servlet之前服务器会先去调用Servlet的destroy()方法,我们可以把Servlet的被销毁前要执行的代码放到destroy()方法中,例如对某些资源的释放等代码放到destroy()方法中。
总结:在首次访问HelloServlet时,init()方法会被执行,而且也会执行service()方法。再次访问时,只会执行service()方法,不再执行init()方法。在关闭Tomcat时会调用destroy()方法。
Servlet接口相关类型
在Servlet接口中还存在三个我们不熟悉的类型:
-
getServletInfo():获取网页的说明信息。
-
ServletRequest:service() 方法的参数,它表示请求对象,它封装了所有与请求相关的数据,它是由服务器创建的。
-
ServletResponse:service()方法的参数,它表示响应对象,在service()方法中完成对客户端的响应需要使用这个对象。
-
ServletConfig:init()方法的参数,它表示Servlet配置对象,它对应Servlet的配置信息,那对应web.xml文件中的
<servlet>
元素。
ServletRequest/ServletResponse
ServletRequest:指Http请求协议。ServletResponse:Http响应协议。
ServletConfig
作用:创建Serlvet对象时,配置Servlet需要的配置信息。类似xxx.Properties
文件中应用。
场景:解决中文乱码的问题,指定字符编码,编码配置节点中数据库连接信息配置
,框架资源文件配置
。ServletConfig对象对应web.xml文件中的<servlet>
元素。例如你想获取当前Servlet在web.xml文件中的配置名,那么可以使用servletConfig.getServletName()方法获取。
ServletConfig对象是由服务器创建的,然后传递给Servlet的init()方法,你可以在init()方法中使用它。
-
String getServletName():获取Servlet在web.xml文件中的配置名称,即
<servlet-name>
指定的名称; -
ServletContext getServletContext():用来获取ServletContext对象。
-
String getInitParameter(String name):用来获取在web.xml中配置的初始化参数,通过参数名来获取参数值。
-
Enumeration getInitParameterNames():用来获取在web.xml中配置的所有初始化参数名称。
在<servlet>
元素中还可以配置初始化参数:
<servlet>
<servlet-name>servletA</servlet-name>
<servlet-class>com.coydone.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>paramName1</param-name>
<param-value>paramValue1</param-value>
</init-param>
<init-param>
<param-name>paramName2</param-name>
<param-value>paramValue2</param-value>
</init-param>
</servlet>
在servletA中,可以使用ServletConfig对象的getInitParameter()方法来获取初始化参数,例如:String value1 = servletConfig.getInitParameter(“paramName1”);//获取到paramValue1
请求的分发处理
package com.coydone.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello Servlet 被访问了");
// 类型转换,因为它有 getMethod()方法
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求的方式
String method = httpServletRequest.getMethod();
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
/*做 get 请求的操作 */
public void doGet(){
System.out.println("get 请求");
}
/*做 post 请求的操作 */
public void doPost(){
System.out.println("post 请求");
}
}
GenericServlet
GenericServlet概述
GenericServlet是Servlet接口的实现类,我们可以通过继承GenericServlet来编写自己的Servlet。GenericServlet还实现了ServletConfig接口,所以可以直接调用getInitParameter()、getServletContext()等ServletConfig的方法。
案例:获取xml中的信息
在web.xml中配置servlet
<servlet>
<servlet-name>world</servlet-name>
<servlet-class>com.coydone.servlet.Myservlet2</servlet-class>
<!--配置servlet的初始化信息-->
<init-param>
<!--参数名-->
<param-name>user</param-name>
<!--参数值-->
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>pwd</param-name>
<param-value>123</param-value>
</init-param>
</servlet>
<!--映射文件-->
<servlet-mapping>
<!--这个名称必须跟servlet的名称一样-->
<servlet-name>world</servlet-name>
<!--浏览器的请求访问的URL地址-->
<url-pattern>/world</url-pattern>
</servlet-mapping>
在com.coydone.servlet包下建立Myservlet2.java文件。
package com.coydone.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* 继承GenericServlet
*/
public class Myservlet2 extends GenericServlet {
//初始化方法
/* @Override
public void init(ServletConfig config) throws ServletException {
//获取pwd初始化参数的值
String pwd = config.getInitParameter("pwd");
System.out.println("pwd:"+pwd);
}*/
//初始化方法
@Override
public void init() throws ServletException {
String user = getInitParameter("user");
System.out.println("user:"+user);
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
//处理请求和响应
/* @Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("处理请求和响应。。。");
//每次都得把servletRequest对象强转成HttpServletRequest对象
//才能获取session对象
//HttpServletRequest request = (HttpServletRequest)servletRequest;
//request.getSession();
}*/
}
评论区