Servlet服务器程序
1. Servlet的概念
Servlet(Server + Applet):运行在Web服务器端(Tomcat)的小程序。
Servlet的主要作用:接收客户端浏览器的请求,还可以为客户端浏览器做出响应。
-
学习Servlet技术三大目的:
-
让程序运行在服务器端
-
接收客户端浏览器的请求参数
-
用户需求,对客户端进行数据响应
-
JavaWeb技术有三大组件:Servlet,Filter,Listener
JavaWeb还有十三规范:Tomcat服务器支持其中的2个Servlet和jsp
2. Servlet程序快速入门
2.1 创建第一个Servlet项目(响应字符串)
① 创建Java EE(Java Enterprise),勾选Web Application(4.0)
② 在web目录下创建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Servlet请求: 前端 --> 后台</h1>
<a href="helloServlet">访问helloServlet</a>
</body>
</html>
③ 在scr目录下创建目录,并创建HelloServlet类
④ HelloServlet类继承HttpServlet,重写service方法(有两个service方法,注意选择)
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//请求 --- 响应(控制台输出字符串)
public class HelloServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("HelloServlet ---> 重写父类service方法");
}
}
⑤ 在WEB-INF中选择web.xml配置标签 建立HelloServlet关联
<?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>hello</servlet-name><!-- name值自定义,要求同一组servlet和servlet-mapping和name值要相同 -->
<servlet-class>com.aaa.servlet.HelloServlet</servlet-class><!-- 关联的”类“的完整路径 -->
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/helloServlet</url-pattern><!-- (前端页面的)请求路径,这里一定要加/ -->
</servlet-mapping>
</web-app>
⑥ 配置并启动Tomcat ,打开浏览器访问地址 配置Tomcat教程请见:idea配置tomcat
⑦ 点击超链接(重定向)标签,跳转至helloServlet页面,成功。
图解:
-
请求路径必须加”/“原因:
在<url-pattern>/helloServlet</url-pattern>中,/代表web_Servlet
效果: (gif动图建议放大观看)
2.2 标签方式&注解方式
使用注解方式配置的优势: 代码更加简单
使用注解方式配置的劣势: 耦合度高
在上文提到配置web.xml文件<servlet>标签,在Java中提供更简单的注解方式,只需要在类上加上@WebServlet(value = "请求地址")
注意:
-
注解方式和标签方式二选一即可,如使用注解方式 需要把web.xml中<servlet>标签注释或删除!
-
value的值等于原来的<url-pattern>中的值,简写 : @WebServlet("请求地址")
@WebServlet(value = "/test")
public class TestServlet extends HttpServlet {}
一般更推荐使用配置文件方式配置Servlet,尤其是配置第三方框架中的Servlet:例如SpringMVC中的DispatcherServlet,只能够使用配置文件方式进行配置。
2.3 响应跳转(sendRedirect)
① index.中新增超链接标签
<a href="testSend">使用sendRedirect</a>
② 新建success.html ,转发用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>跳转页面</title>
</head>
<body>
<h1>跳转页面</h1>
</body>
</html>
② 新建TestSendRedirect测试类
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//请求 -- 响应(跳转页面)
@WebServlet("/testSend")
public class TestSendRedirect extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service--->跳转success.html");
resp.sendRedirect("success.html");
}
}
执行查看效果: (gif动图建议放大观看)
3. Servlet的生命周期和生命周期方法
① Servlet对象的创建:构造器
-
默认情况下,Servlet容器第一次收到HTTP请求时创建对应Servlet对象。
-
容器之所以能做到这一点是由于我们在注册Servlet时提供了全类名,容器使用反射技术创建了Servlet的对象。
② Servlet对象初始化:init()
-
Servlet容器创建Servlet对象之后,会调用init(ServletConfig config)方法。
-
作用:是在Servlet对象创建后,执行一些初始化操作。例如,读取一些资源文件、配置文件,或建立某种连接(比如:数据库连接)
-
init()方法只在创建对象时执行一次,以后再接到请求时,就不执行了
-
在javax.servlet.Servlet接口中,public void init(ServletConfig config)方法要求容器将ServletConfig的实例对象传入,这也是我们获取ServletConfig的实例对象的根本方法。
③ 处理请求:service()
-
在javax.servlet.Servlet接口中,定义了service(ServletRequest req, ServletResponse res)方法处理HTTP请求。
-
在每次接到请求后都会执行。
-
上一节提到的Servlet的作用,主要在此方法中体现。
-
同时要求容器将ServletRequest对象和ServletResponse对象传入。
④ Servlet对象销毁:destroy()
-
服务器重启、服务器停止执行或Web应用卸载时会销毁Servlet对象,会调用public void destroy()方法。
-
此方法用于销毁之前执行一些诸如释放缓存、关闭连接、保存内存数据持久化等操作。
代码解析:
① index.html 中新增超链接标签
<a href="testServlet">testServlet生命周期</a>
② 新建TestServlet测试类(使用注解方式)
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/testServlet")
public class TestServlet extends HttpServlet {
public TestServlet(){
System.out.println("TestServlet--->无参构造器");
}
@Override
public void destroy() {
System.out.println("servlet--->destroy() 销毁方法");
}
@Override
public void init() throws ServletException {
System.out.println("servlet--->init() 初始化方法");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("TestServlet--->重写service");
}
}
执行查看效果: (gif动图建议放大观看)
-
Tomcat服务器启动的时候,直接创建Servlet对象
-
service方法:
-
接收浏览器请求的方法
-
每次请求,都会调用service方法,对象生命周期的中间部分
-
调用者是Tomcat引擎
-
-
Servlet对象的销毁时机
-
关闭Tomcat服务器,对象就销毁,会调用方法destroy(),Tomcat引擎调用
-
问题:destroy()方法,对象销毁之前调用
-
销毁:没有引用变量,保存该类的对象,不是在内存中清理了
-
将Web项目从服务器中移除
-
4. 相对路径的使用(不建议使用)
相对路径的概念:
相对路径是不以/
开头的路径写法,编写相对路径的原则是以目标资源的uri路径相对当前资源的uri路径
5. 绝对路径的使用(建议使用)
绝对路径的概念:
绝对路径是以/
开头的路径写法,编写绝对路径的原则是通过目标资源的uri访问目标资源,但是特殊情况是请求转发,如果是请求转发访问目标资源的话,那么绝对路径是在uri的基础之上省略/项目部署名
在请求转发的时候使用绝对路径的写法是: /资源名
,其实就是在uri的基础上省略/项目部署名
相对路径&绝对路径代码解析:
① 新建目录 a-b-c-c.html
② index.html 中新增超链接标签
<a href="testGoC">C.html</a>
③ 新建CtestServletTest测试类
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("testGoC")
public class CtestServletTest extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("跳转--- c.html");
resp.sendRedirect("a/b/c/c.html");
}
}
④ 新建c.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>C.html ---> (web\a\b\c\c.html)</h1>
<a href="ctest111">ctest111--相对路径(默认拼接之前访问路径)</a>
<a href="/web_Servlet/a/b/c/ctest222">ctest222--绝对路径</a>
</body>
</html>
⑤ 新建 CtestServlet1&CtestServlet2测试类
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(value = "/a/b/c/ctest111") //相对路径
public class CtestServlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("CtestServlet1()--->>>相对路径");
}
}
package com.aaa.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(value = "/a/b/c/ctest222") //绝对路径
public class CtestServlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("CtestServlet2()--->>>绝对路径");
}
}
图解:
对应关系: