Servlet简介
Servlet实际上是运行在服务器上面的组件,负责于客户端进行通信,处理客户端的请求,在用户需要访问数据库时负责访问数据库中的数据。可以认为它是一个介于用户客户端和数据库之间的中间件。
- 根据用户请求给用户返回对应的HTML页面
- 与数据库进行通信。
servlet实际上是一个接口,我们需要自己写一个类实现它。其中service方法是最核心的方法,负责处理用户的请求。
package com.northplus.servlet;
import javax.servlet.*;
import java.io.IOException;
public class Myservelet implements Servlet{
@Override
/*
* init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,
* 在后续每次用户请求时不再调用。
* */
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
* service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service()
* 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,
* 服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),
* 并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
*
* */
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
/*destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。
destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、
把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。*/
@Override
public void destroy() {
}
}
我们要注意,在一个Java Web项目中,客户可以直接通过访问jsp文件,例如这里这里有一个名为index.jsp的文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>I am a world <h1>
$END$
</body>
</html>
输入http://localhost:8080/index.jsp
即可访问。但是用户不能这么访问servlet。为什么,实际上呢,我们的项目文件传给tomcat服务器的是这个war包。这个包里面WEB-INF是不允许用户直接访问的。
访问Servlet
实际上我们可以通过xml写入映射来访问serlet文件。
- 基于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>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.northplus.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
</web-app>
这样在访问http://localhost:8080/myservlet
时,就可以访问mysevlet文件了。当我们访问它时,它调用service()
函数,打印了hello world。而在我们访问jsp文件时,它不会执行这一步操作。
- 基于注解的方式
@WebServlet("/demo")
public class MyServlet implements Servlet{
}
这样, 当我们输入http://localhost:8080/demo
时,便可以直接访问servlet。有趣的是,注解和基于xml文件配置可以同时存在。访问http://localhost:8080/myservlet
和http://localhost:8080/demo
都能够得到servlet页面
不过有趣的是,这两种方式会分别得到一个servlet对象。
我们可以改写一下service函数,让其能够获得id
public void service(ServletRequest servletRequest, ServletResponse servletResponse)
throws ServletException, IOException {
// System.out.println("Hello world");
String id = servletRequest.getParameter("id");
System.out.println("Hello world Mr." + id);
servletResponse.setContentType("text/html;charset=UTF-8");
servletResponse.getWriter().write("hello client.");
}
当我们输入http://localhost:8080/myservlet?id=brok
时,在控制台上便会打印
Hello world Mr.brok
如果直接输入http://localhost:8080/myservle
便会打印
Hello world Mr.null
Servlet生命周期
1.当浏览器访问Servlet时,Tomcat会查询当前是否存在Servlet对象,如果存在,直接执行第3步。若不存在,则通过反射机制动态创建Servlet对象。
2.调用init方法完成初始化
3.调用service方法完成业务操作
4.关闭Tomcat时,调用destroy方法,释放当前对象的资源。
package com.northplus.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/demo")
public class MyServlet implements Servlet{
private int recallCnt;
// 记录被调用的次数
public MyServlet(){
recallCnt = 0;
System.out.println("Successfully created a Servlet object");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("Successfully initialized");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// System.out.println("Hello world");
// String id = servletRequest.getParameter("id");
// System.out.println("Hello world Mr." + id);
// servletResponse.setContentType("text/html;charset=UTF-8");
// servletResponse.getWriter().write("hello client.");
System.out.println("Recalled " + recallCnt + " times");
recallCnt++;
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
System.out.println("Successfully Destroyed");
}
}
Successfully created a Servlet object
Successfully initialized
Recalled 0 times
Recalled 1 times
Recalled 2 times
比较奇怪的是最后的销毁方法没有被调用。