Javaweb的三大组件分别是:Servlet、Filter(过滤器)、Listener(监听器)。
所以本篇主要就是聊一下Servlet,
servlet是什么?
这个先看一下官网的解释:
servlet 是运行在 Web 服务器中的小型 Java 程序。servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
然后看一个图:
还是理论知识就直接盗用一些他人总结:
Servlet 执行以下主要任务:
- 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。
创建一个servlet
首先导入servlet-api.jar 包
有些编程软件再创建javaweb的时候会自动将servlet-api.jar导入,但是再IDE2021不行,需要导入这个jar包。这个包可以从网站找资源下载,也可以直接再tomcat安装路径的lib文件夹下得到。
实现servlet接口
创建一个类,实现servlet接口:
public class test_servlet 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 {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
可以看出需要实现五个方法,然后看一下官网api:
其实五个方法中其中的三个方法涉及到一个servlet的生命周期:
-
servlet构造函数,这样初始化一个servlet对象。
-
Servlet 初始化后调用 init () 方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。
-
Servlet 调用 service() 方法来处理客户端的请求。
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
-
Servlet 销毁前调用 destroy() 方法。
estroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
-
最后的是垃圾回收机制:Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
还有两个方法也要聊一下:
方法 | 描述 |
---|---|
public ServletConfig getServletConfig() | 返回 ServletConfig 对象,该对象包含此 servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init 方法的对象。 |
public String getServletInfo() | 此方法返回的字符串应该是纯文本,不应该是任何种类的标记(比如 HTML、XML,等等)。 |
配置url
前端进行请求的时候自然会有一个url,而自己创建的servlet自然也要根据不同的请求url返回不同的数据。而配置url请求对应的servlet是那个,有两种方式。
通过web.xml文件进行配置
这个web.xml不需要自己创建,而默认的javaweb会自动生成这个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的名字(一般创建和名字相同)对应的那个类 -->
<servlet>
<servlet-name>test_servlet</servlet-name>
<servlet-class>com.xzd.test.test_servlet</servlet-class>
</servlet>
<!-- 通过上面创建一个servlet的名字(一般创建和名字相同) 然后设置一个url-pattern配置一个访问的请求会调用自己写的servlet类 -->
<servlet-mapping>
<servlet-name>test_servlet</servlet-name>
<!-- 这个是网址资源路径,一定要有/ 不然会报错的 -->
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
注意: 不同的url-pattern可以对应一个相同的servlet-class,但是不同的servlet-class不能对应一个相同的url-pattern。
通过注释
这其实再再servlet3.0之后才新增的功能,不需要再web.xml中进行配置,而是直接通过注释而解决,这个注释如下:
@WebServlet(name = "test_servlet",urlPatterns = "/test")
// 或者简写为
@WebServlet("/test" )
注释可以实现的话是通过反射而实现的。如果想要了解反射可以看一下前面的文章:传送阵
这个注释放在写的servlet上面,而这个urlPatterns的配置除了精确的配置地址,还可以使用正则表达式来实现这个功能。
urlPatterns匹配规则 | 例子 | 描述 |
---|---|---|
精确匹配 | urlPatterns = “/test” | 访问路径:http://localhost:8080/javaweb/test 只有这样才能请求带有注释的servlet |
任意匹配 | urlPatterns = “/*” | 访问路径:http://localhost:8080/javaweb/test 或 http://localhost:8080/javaweb/a 的可以请求带有注释的servlet |
扩展名匹配 | urlPatterns = “/*.do” | 访问路径:http://localhost:8080/javaweb/test.do 或 http://localhost:8080/javaweb/a.do 的可以请求带有注释的servlet |
当然上面的匹配也是有优先权的,自然是越精确的的权限越高。
补充
-
两种方式可以同时用,但是不能配置相同的路径,如果对同一个servlet配置的时候如果两者的url配置不同,其不会报错。但是一般的时候不会这样,毕竟有些多此一举。两者没有所谓的优先级,如果配置的web和url两个servlet的url一样,那么运行tomcat会报错。
-
web.xml优缺点
-
优点
web.xml是集中管理的配置文件不再代码中,所以具有更好的扩展性,而所有的路径通过web.xml配置让开发者很直观的看到路径与类的关系。
-
缺点
因为所有的信息配置再web.xml中,而这个如果配置很多文件就会很大,无论xml的读取两种方式:一次性读取或者一行一行的读取都会占用资源。
-
-
注释的优缺点
-
优点
因为其再类上进行注释所以其不必要维护两个文件,可以说在开发的时候方便很多。而程序在编译的时候报错很容易找到错误的所在。
-
缺点
因为注释在类上,所以修改注释路径的时候需要将项目重新编译,如果处理业务复杂,不如xml好修改,而xml配置的话可以有更多配置。
-
所以两者总结如下:
- xml配置书写较灵活、修改时不需要更改代码,更方便,且容易扩展,但维护困难,开发效率低一些。
- 注解配置书写简单,容易检测出问题,开发效率高一些,但修改麻烦,影响了代码的简洁性,且功能没有xml配置齐全
部署一个看一下
其实整体过程用下图表示:
现在可以运行一个servlet,然后整个类如下写:
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/test" )
public class test_servlet implements Servlet {
public test_servlet(){
System.out.println("构造方法初始化----方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init----方法");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig----方法");
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service----方法");
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo----方法");
return null;
}
@Override
public void destroy() {
System.out.println("destroy----方法");
}
}
启动服务器:
因为前端没有写东西,访问:http://localhost:8080/javaweb/test 是空白,但是可以看一下后台。
如果刷新几次,可以看到:
然后关闭tomcat可以看:
所以可以看出servlet的生命周期和前面聊的是一致的。
处理不同的请求方式
应该知道html协议中最常用两种请求方式GET
和POST
,如果对整个概念不了解可以看我另一篇文章:传送阵
所以在servlet中的时候,需要对访问来的请求进行判断, 请求方式不同(出了GET POSE 还有PUT等方式),其传递的参数处理也是不一样的,。
所以先看一下service方法中的两个参数:
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
看一下官网的解释:
参数名可能与IDE中自动生成的不一样,但是没有关系,可以看下进入包含所有的客户端自然也就包含了得到请求方式的方法。
但是看一下:ServletRequest 为要给接口自带的方法中好像没有得到请求方式的的方法,那么可以看一下其官网文档,毕竟接口无法创建对象的,而是通过一个实现这个接口的类才可以。所以现在看一下官网其实现的类或者继承的接口。
可以看见其子接口为
Interface HttpServletRequest extends ServletRequest
当然也可以使用ID查看,将光标放在ServletRequest上面然后按快捷键:Ctil+H.如下:
然后看见其子子接口中有一个方法:
所以可以在service方法如下写:
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 强制转换一下
String method=((HttpServletRequest)servletRequest).getMethod();
System.out.println(method);
}
javaweb访问项目不带有资源路径的时候:
默认是访问的是的主页是如下:
看jsp文件似乎和html文件一样,暂时先理解为就是一个html文件,然后可以使用html标签,具体后面会聊jsp文件是什么,修改如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/javaweb/test" method="post">
<input type="submit" value="提交">
</form>
</body>
</html>
然后启动的话,可以看如下
然后通过判断语句进行判断,而选择走处理get或者处理post请求的方法。
HttpServlet
再说一个挨打的事情,那就是前面聊这样多就是了解一下servlet是什么。然后看一下这个图:
然后如下看:
public abstract class extends GenericServletimplements Serializable
Extends: GenericServlet
然后看一下其拥有的方法:
所以使用中直接通过继承这个类,而创建servlet。如下:
public class test1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
配置url什么的和前面的几乎一致了。本篇就是简单聊了一下什么是servlet以及创建一个servlet的例子,后面具体聊如何互动,以及相互传递数据。