1.概述
Servlet是Java Web开发的基石;是与平台无关的服务器组件;是运行在Tomcat(Servlet容器、Web应用服务器),负责与客户端通信。
2.使用Servlet
Servlet是在java.servlet包中的一组接口。因此,在添加Servlet依赖之后,可以自定义一个类,并实现Servlrt接口,则该类就具备了接受客户请求,以及做出响应的功能。
<!-- 在pom.xml中引用servlet依赖 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
import javax.servlet.*;
import java.io.IOException;
public class MyServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//初始化
}
@Override
public ServletConfig getServletConfig() {
//获取Servlet信息
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
//处理客户端请求,执行Servrlt业务方法
//在控制台输出
System.out.println("Hello A");
//在客户端输出
servletResponse.setContentType("text/html;charset=UTF-8");//运行服务器响应中文,否则会乱码
servletResponse.getWriter().write("Hello A");
//接收客户端传来的参数
//http://localhost:8080/myservlet?id=1&name=wcc
String id = servletRequest.getParameter("id");//id = 1
String name = servletRequest.getParameter("name");//name = wcc
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
//销毁,释放资源
}
}
3.Servlet映射
Java程序会被打包到WEB-INF文件夹中,且该文件夹不能被浏览器直接访问,但可以通过映射的方式访问。
(1)基于XML文件的配置方式
<servlet>
<servlet-name>myservlet</servlet-name> <!-- ① -->
<servlet-class>MyServlet</servlet-class><!-- 全类名,映射到该类 -->
<!-- 可选,定义参数 -->
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name><!-- 与①保持一致 -->
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
(2)基于注解的方式
@WebServlet("/myservlet")
public class MyServlet implements Servlet {
//实现Servlet接口的方法
}
此时,可以通过"localhost:8080/myservlet"访问Myservlet
4.Servlet的生命周期
(1)当服务器(客户端)第一次访问Servlet,服务器将执行init(),创建Servlet对象,并完成初始化;而后再执行service(),执行业务代码。
(2)当客户端再次发来请求,将不再执行init(),而是直接执行service()。
(3)当Tomcat服务暂停后,即关闭Tomcat,将执行destroy(),销毁对象,释放内存。
初始化创建对象,是通过反射机制进行的。即先解析XML文件,找到Application Context所映射的全类名,再通过反射机制,调用该类的无参构造函数创建对象。
寻常方式,是直接通过类的无参构造函数创建对象。
MyClass myclass = new MyClass();
反射机制,是通过全类名(亦或是通过对象,得到对象的类名),获得类的无参构造函数,从而创建类的对象。
Class c = Class.forName(str); //str为全类名 Constructor constructor = c.getConstructor(); //获取无参构造 Object obj = constructor.newInstance(); //调用无参构造创建对象
5.ServletConfig对象方法
ServletConfig接口用来描述Servlet的基本信息。
ServletConfig对象可以通过Servlet的实现类的getServletConfig()获得
MyServlet myclass = new MyServlet(); ServletConfig sc = myclass.getServletConfig();
//返回该类的全类名,即Servlet的实现类MyClass
String ClassName = sc.getServletName();
//获取配置文件web.xml中定义的参数的值,即<init-param>中
//此时不能使用基于注解的配置方式
String para = sc.getInitParameter("username");
//得到web.xml中所有的参数名
Enumeration<String> es = sc.getInitParameterNames();
while(es.hasMoreElements())
{
String element = es.nextElement();
}
//返回ServletContext对象
ServletContext servletContext = sc.getServletContext();
ServletContext,它是Servlet的上下文,整个Servlet的管理者,通过它可以得到整个服务的信息。
String path = servletContext.getContextPath(); //返回上下文路径,即配置的Application Context String info = servletContext.getServerInfo(); //返回当前Tomcat服务器的信息 //会输出Tomcat版本
ServletConfig与ServletContext的区别:
①ServletConfig作用于某个Servlet对象,每个Servlet对象都对应一个ServletConfig;
②ServletContext作用于整个Web应用,一个Web应用(含多个Servlet实例),对应一个ServletContext;
③获取的参数有所不同:
String para = servletConfig.getInitParameter("username"); //获取的是局部变量,定义在<servlet>中的<init-param> String all_para = servletContext.getInitParameter("UserName"); //获取的是全局变量,定义在<servlet>外的<context-param>
<!-- 在web.xml的<servelt>外 --> <!-- ServletContext取的变量 --> <context-param> <param-name>UserName</param-name> <param-value>admin_all</param-value> </context-param>
6.Servlet的层次结构
Servlet —> GenericServlet —> HttpServlet
在编程时,不需要直接实现Servlet接口,而是继承HttpServlet类。
public class Test extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
一个业务由CRUD——Creat、Read、Update、Delete组成
HTTP请求有很多类型,常用的有4种:
GET(读取)、POST(保存)、PUT(修改)、DELETE(删除)
底层细节:
public class GenericServlet implements Servlet { //实现Servlet接口 }
public class HttpServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest)servletRequest; HttpServletResponse response = (HttpServletResponse)servletResponse; String method = request.getMethod(); //请求类型 switch (method){ case "GET": this.doGet(request, response); break; case "POST": //doPost break; } } public void doGet(HttpServletRequest request, HttpServletResponse response){ //代码 } }
①GenericServlet实现Servlet接口,同时为它的子类屏蔽了不常用的方法,子类只需要重写service();
②HttpServlet继承GenericServlet,根据请求类型进行分发处理,GET进入doGet(),POST进入doPost();
③开发者自定义的Servlet类只需要继承HttpServlet,重写doGet(),doPost();