Servlet 详解
文章目录
一、概念
1. Servlet
Servlet是server applet的缩写,译为:运行在服务器端的小程序
servlet就是一个接口,定义了java类被浏览器访问到[tomcat识别]的规则
我们可以自定义一个类,实现servlet接口,重写方法,实现逻辑
Servlet比较特殊,不需要new,自动就可以运行。也有创建、垃圾回收和销毁过程。
Servlet是JavaWeb的三大组件之一(Servlet、Filter、Listener),属于动态资源。
Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要:
接收请求数据
处理请求
完成响应
例如客户端发出登录请求,或者输出注册请求,这些请求都应该由Servlet来完成处理
Servlet需要我们自己来编写,每个Servlet必须实现javax.servlet.Servlet接口。Servlet对象驻留在服务器内存中。
2. servlet与servlet容器
Java Servlet(Java服务器小程序)是一个基于Java技术的Web组件,运行在服务器端,它由Servlet容器所管理,用于生成动态的内容。 Servlet是平台独立的Java类,编写一个Servlet,实际上就是按照Servlet规范编写一个Java类。Servlet被编译为平台独立 的字节码,可以被动态地加载到支持Java技术的Web服务器中运行。
Servlet容器(如 Tomcat)也叫做Servlet引擎,是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于 MIME的请求,格式化基于MIME的响应。Servlet没有main方法,不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用 Servlet的方法(如doGet()和doPost()),Servlet容器在Servlet的生命周期内包容和管理Servlet。在JSP技术 推出后,管理和运行Servlet/JSP的容器也称为Web容器。
注:常用的MIME类型:
text/html,application/pdf,video/quicktime,application /java,image/jpeg,application/jar,application/octet-stream,application/x-zip
有了servlet之后,用户通过单击某个链接或者直接在浏览器的地址栏中输入URL来访问Servlet,Web服务器接收到该请求后,并不是将 请求直接交给Servlet,而是交给Servlet容器。Servlet容器实例化Servlet,调用Servlet的一个特定方法对请求进行处理, 并产生一个响应。这个响应由Servlet容器返回给Web服务器,Web服务器包装这个响应,以HTTP响应的形式发送给Web浏览器。
二、简单示例
1、创建 java 工程
File >> New Project >> Java Enterprise,工程命名为 ServletTest
2、创建目录
在项目根目录创建目录: **web/WEB-INF **
在 WEB-INF 下创建目录 classes 和 lib
点击file菜单,选择project Structure (ctrl+alt+shift+s), 把当前项目的 **Paths ** 输出路径(Output path)改成 WEB-INF 下的 **classes **
3、创建Package
在 src 中创建 Package : com.crs811
在包中创建类文件:HelloServlet.java,内容如下:
1package com.crs811;
2
3import java.io.IOException;
4
5import javax.servlet.Servlet;
6import javax.servlet.ServletConfig;
7import javax.servlet.ServletException;
8import javax.servlet.ServletRequest;
9import javax.servlet.ServletResponse;
10
11public class HelloServletimplements Servlet {
12 @Override
13 public void init(ServletConfig config) throws ServletException {
14 }
15
16 @Override
17 public ServletConfig getServletConfig() {
18 return null;
19 }
20
21 @Override
22 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
23 //IDEA控制台输出: Hello World!!!
24 System.out.println("Hello World!!!");
25
26 PrintWriter out = servletResponse.getWriter();
27 out.println("<h1>hello world</h1>");
28 }
29
30 @Override
31 public String getServletInfo() {
32 return null;
33 }
34
35 @Override
36 public void destroy() {
37 }
38}
4、新建 web.xml
在 WEB-INF 中新建 web.xml 文件,web.xml文件是用来初始化配置信息:比如Welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别等。内容如下:
1<?xml version="1.0" encoding="UTF-8"?>
2<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
5 version="4.0">
6
7 <servlet>
8 <servlet-name>HelloServlet</servlet-name>
9 <servlet-class>com.crs811.HelloServlet</servlet-class>
10 </servlet>
11
12 <servlet-mapping>
13 <servlet-name>HelloServlet</servlet-name>
14 <url-pattern>/hello</url-pattern>
15 </servlet-mapping>
16
17</web-app>
5、配置 artifacts
Run >> Edit Configurations >> Deployment , 右方加号,如果没有 artifacts ,则需要添加,步骤如下
(1) 点击file菜单,选择project Structure (ctrl+alt+shift+s)
(2) 选择Modules, 找到需要部署的项目(ServletTest),右键,点击add, 找到web,点击web
(3) 选择Artifacts,然后点击+号,选择Web Application:exploded,然后选择from Modules, 选择对应的项目,点击ok即可, 添加好后,想要部署的项目就可以deployment中添加了
6、测试:
点击“运行”按钮运行项目,或在浏览器输入:http://localhost:8080/ServletTest_war_exploded/hello
则浏览器和控制台会输出 servlet 的内容:
浏览器:
控制台:
三、生命周期
首先加载servlet的class,实例化servlet,然后初始化servlet调用init()的方法,接着调用服务的service的方法,最后容器关闭时候调用destroy 销毁方法。
1.被创建:执行init方法,只执行一次
Servlet什么时候被创建?
--默认情况下,第一次被访问时,Servlet被创建,然后执行init方法;
--可以配置执行Servlet的创建时机;
2.提供服务:每个客户端请求都会执行service方法,执行多次,处理doGet和doPost方法
3.被销毁:当Servlet服务器正常关闭时,执行destroy方法,只执行一次
Servlet 调用过程详解,请点击下图看大图:
四、servlet 输出网页
在项目的包 com.crs811 中新建 WebpageServlet.java,内容如下:
1package com.crs811;
2
3import java.io.IOException;
4import java.io.PrintWriter;
5
6import javax.servlet.ServletException;
7import javax.servlet.annotation.WebServlet;
8import javax.servlet.http.HttpServlet;
9import javax.servlet.http.HttpServletRequest;
10import javax.servlet.http.HttpServletResponse;
11
12@WebServlet("/webpage")
13public class WebpageServlet extends HttpServlet{
14
15 @Override
16 protected void doGet(HttpServletRequest request, HttpServletResponse response)
17 throws ServletException, IOException {
18 //设置response查询的码表
19 //response.setCharacterEncoding("UTF-8");
20 //通过一个头 Content-Type 告知客户端使用何种码表
21 //response.setHeader("Content-Type", "text/html;charset=UTF-8");
22
23 <strong>response.setContentType("text/html;charset=UTF-8");
24 PrintWriter out=response.getWriter();
25 out.println("<html>");
26 out.println("<body>");
27 out.println("<span style='color: #ff0000;'><h1>要输入的内容.........</h1><p><font color='red'>我是红色文字</font></p></span>");
28 out.println("</body>");
29 out.println("</html>");</strong>
30 }
31
32 @Override
33 protected void doPost(HttpServletRequest request, HttpServletResponse response)
34 throws ServletException, IOException {
35 doGet(request, response);
36 }
37}
浏览器端输入:http://localhost:8080/ServletTest_war_exploded/webpage
可以看到,这种输出HTML页面的方式很麻烦,HTML代码和java代码混杂在一起,不便于维护
因此才使用 jsp 来将 HTML 页面和java 事务逻辑分离,因此形成了 javaweb 的 MVC结构
涉及的知识点
1、HttpServlet
广义上,Servlet 即实现了 Servlet 接口 的类,当我们创建一个自定义类,实现 Servlet 接口 的时候,会发现有 5 个方法需要重写,有init【初始化】,destroy【销毁】,service【服务】,ServletConfig【Servlet配置】,getServletInfo【Serlvet信息】。
这样做的话每次都需要实现 5 个方法,太麻烦了!
因此改进的方法是继承 HttpServlet 类,该类已经默认实现了 Servlet 接口中的所有方法,在编写 Servlet 的时候,只需要重写需要的方法就好了,并且该类还在原有 Servlet 接口上添加了一些与 HTTP 协议处理相关的方法,比 Servlet 接口的功能更强大。
Servlet 处理请求的方法一共有三种:
实现 service() 方法
重写 doGet() 和 doPost() 方法,并在 doGet() 中添加一句this.doPost(req, resp);(因为无论是get或post请求提交的数据,处理方式都基本相同,下同)
重写 doGet() 和 doPost() 方法,并在 doPost() 中添加一句this.doGet()(req, resp)
2、注解
注解是 Servlet 3.0 提出的新特性,支持注解配置,这大大简化了我们的工作。
在之前的开发工作中,我们总是去 **web.xml **文件中配置servlet,至少会出现8行:
而当一个项目中存在很多 Servlet ,那么配置文件就会变得非常臃肿,不便于后期的维护
在 Servlet 3.0 推出之后,我们可以使用注解来配置 Servlet,上面 8 行的配置可以简化为一行简单的注解:@WebServlet(name="WebpageServlet", urlPatterns="/webpage")
使用urlPatterns 或 value 定义访问的 URL,只有这个属性是必要的,name 是可以缺省的值,所以可以简写成:
@WebServlet("/foreServlet")