目录

1 关于系统结构分析

1.1 系统架构包括什么形式?

1.2 C/S架构?

1.3 B/S架构

2 配置Tomcat服务器

2.1 Tomcat概述

2.2 启动Tomcat

3 编写第一个webapp

4 模拟servlet本质

5 开发第一个Servlet

5.1 开发步骤

5.2 Servlet中编写JDBC连接数据库

6 使用IDEA工具开发Servlet

7 Servlet中的方法概述

8 适配器模式改造Servlet

9 ServletConfig接口详解

10 ServletContext接口详解

10.1 ServletContext概述

10.2 ServletContext作用

10.3 应用域


1 关于系统结构分析

1.1 系统架构包括什么形式?

C/S架构
        B/S架构

1.2 C/S架构?

Client/ Server (客户端/服务器)
C/S架构的特点:需要安装特定的客户端软件。
C/S架构的系统优点和缺点分别是什么?
优点:

  • 速度快(软件中的数据大部分都是集成到客户端软件当中的,很少量的数据从服务器端传送过来,所以C/S结构的系统速度快)
  • 体验好(速度又快,界面又酷炫,当然体验好了。)
  • 界面酷炫(专门的语言去实现界面的,更加灵活。)
  • 服务器压力小(因为大量的数据都是集成在客户端软件当中,所以服务器只需要传送很少的数据量,当然服务器压力小。)
  • 安全(因为大量的数据是集成在客户端软件当中的,并且客户端有很多个,服务器虽然只有- 个,就算服务器那边地震了,火灾了,服务器受损了,问题也不大,因为大量的数据在多个客户端.上有缓存,有存储,所以从这个方面来说,C/S结构的系统比较安全。)

缺点:

  • 升级维护比较差劲。 (升级维护比较麻烦。成本比较高。每一个客户端软件都需要升级。有一 些软件不是那么容易安装的。)

1.3 B/S架构

我们经常使用的百度、京东等等网页就是B/S架构。

B/S架构的优点和缺点。

优点:

  • 升级维护方便,成本比较低。 (只需要升级服务器端即可。)
  • 不需要安装特定的客户端软件,用户操作极其方便。只需要打开浏览器,输入网址即可。

缺点:

  • 速度慢(不是因为带宽低的问题,是因为所有的数据都是在服务器上,用户发送的每-个请求都是需要服务器全身心的响应数据,所以B/S结构的系统在网络中传送的数据量比较大。)
  • 体验差(界面不是那么酷炫, 因为浏览器只支持三个语言HTML CSS JavaScript。 在加上速度慢。)
  • 不安全(所有的数据都在服务器上, 只要服务器发生火灾,地震等不可抗力,最终数据全部丢失。)

2 配置Tomcat服务器

2.1 Tomcat概述

配置Tomcat服务器之前先安装jdk并配置好环境变量

关于Tomcat的安装:Tomcat是绿色版解压即是安装

关于Tomcat服务器的目录:

bin:这个目录是Tomcat服务器的命令文件存放的目录,比如:启动Tomcat,关闭Tomcat等。

conf:这个目录用来存放Tomcat服务器配置文件

lib:是Tomcat服务器的核心程序目录,因为Tomcat服务器是Java语言编写的,这里的jar包都是class文件

logs:Tomcat服务器的日志文件目录,Tomcat服务器启动等信息都会在这个目录下生成日志

temp:Tomcat服务器的临时目录,存放临时文件

webapps:存放大量的webapp——(web application:web应用)

work:存放JSP文件翻译后的Java文件以及编译之后的class文件

2.2 启动Tomcat

bin目录下有一个文件:startup.bat,通过它可以启动Tomcat服务器

xxx.bat是什么文件?bat文件是Windows操作系统专用的,bat文件是批处理文件,这种文件中可以编写大量的Windows的dos命令,然后执行bat文件就相当于批量的执行dos命令

startup.sh,这个文件在Windows当中无法执行,在Linux中可以使用。

分析startup.bat文件得出,执行这个命令,实际上最后是执行:catalina.bat文件

catalina.bat文件中有这样一行配置:MAINCLASS=org.apache.catalina.startup.Bootstrap(这个类就是main方法所在的类)

Tomcat服务器是Java语言写的,既然是Java语言写的,那么启动Tomcat服务器就是执行main方法

我们尝试在dos窗口输入startup.bat来启动Tomcat服务器。启动Tomcat服务器只配置path对应的bin目录是不够的,有两个环境变量需要配置:

JAVA_HOME=JDK的根             CATALINA_HOME=Tomcat服务器的根

这样就能成功启动Tomcat服务器,我们也终于发现了最开始学习Java时配置的JAVA_HOME到底有什么用,这就是Java的家。

总结一下:配置Tomcat服务器需要的环境变量有哪些?

JAVA_HOME=JDK的根   CATALINA_HOME=Tomcat服务器的根

PATH=%JAVA_ HOME%\bin;%CATALINA_ HOME%\bin

启动Tomcat:startup或者startup.bat

关闭Tomcat:stop(shutdown.bat重命名为stop.bat,为什么修改?以为与Windows的关机命令重复了,避免冲突或者是是避免使用错误导致电脑关机)

怎么在浏览器测试Tomcat服务器配置成功?

我们知道要想访问一个服务器需要输入IP地址和端口号即可,Tomcat的IP就是本机IP,端口号就是8080,经测试没有问题

3 编写第一个webapp

第一步:找到CTALINA_HOME\webapps目录,因为所有的webapp都要放到webapps目录下。没有为什么,这是王八的屁股--规定,如果不放到这,Tomcat服务器找不到你的应用。

第二步:在CTALINA_HOME\webapps目录新建一个子目录,起名:oa。这个名字就是你的webapp的名字

第三步:在oa目录下新建资源文件,例如:index.html。接着编写html内容

第四步:启动Tomcat服务器

第五步:打开浏览器输入URL:http://127.0.0.1:8080/oa/index.html

注意:在编写html时,绝对路径不需要添加html://127.0.0.1:8080,直接以/开始带项目名就是一个绝对路径,如本次项目中<a href="/oa/login.html">用户登录</a>,这就是绝对路径

在项目目录下编写两个html文件

两个HTML文件内容为:

<!DOCTYPE html>
<html><head><title>index</title></head><body><h1>我的第一个页面</h1><a href="/oa/login.html">用户登录</a></body>
</html>
<!DOCTYPE html>
<html><head><title>login</title></head><body><form><h2>用户登录</h2>用户名:<input type="text" name="username" /><br>密  码:<input type="password" name="password" /><br><input type="submit" value="登录"/></form></body>
</html>

不过本次第一个项目出了点小问题,输入URL无法访问到html资源,将服务器重启也不行,但是将dos窗口关闭重开就可以了不知道为啥捏。

4 模拟servlet本质

做了这么多准备终于到了servlet部分

根据上图,我们 发现要想完成一个完整的web服务,需要这四个部分,现在来模拟servlet的本质

主要模拟三部分:制定servlet规范;充当tomcat服务器开发者;充当webapp的开发者。

编写的三个webapp都要实现Servlet接口

当启动Tomcat服务器时,要求用户输入相应路径来启动相应的java小程序,这时java小程序和路径要有一个对照关系。这个对照关系就需要Java程序员来完成,需要一个配置文件。然后需要Tomcat服务器来解析配置文件。

代码:

Tomcat服务器:

//充当Tomcat服务器的开发者
package org.apache;import java.util.Scanner;
import java.util.Properties;
import java.io.FileReader;
import javax.servlet.Servlet;public class Tomcat
{public static void main(String[] args) throws Exception{System.out.println("Tomcat服务器启动成功,开始接收用户访问。");//用Scanner模拟用户的请求System.out.print("请输入您的访问路径:");Scanner sc = new Scanner(System.in);String key = sc.nextLine();//Tomcat服务器应该根据用户输入的请求路径获取相应的xxxServletFileReader reader = new FileReader("web.properties");Properties pro = new Properties();pro.load(reader);reader.close();//通过key获取valueString className = pro.getProperty(key);//通过反射机制获取对象Class clazz =  Class.forName(className);Object obj = clazz.newInstance();Servlet servlet = (Servlet)obj;servlet.service();}
}

Servlet:

package javax.servlet;public interface Servlet
{void service();
}

java小程序:

package com.itzw.servlet;import javax.servlet.Servlet;public class UserloginServlet implements Servlet
{public void service(){System.out.println("UserloginServlet's service....");}
}

结果:

由此我们可以看到,在实际开发中,对于javaweb程序员来说只需要做两件事:编写一类实现Servlet接口;编写配置文件指定请求路径和类名的关系。

同时我们也发现,Tomcat服务器的源码中已经规定好了配置文件的路径和名字,已经写死了,不能随便写。

Servlet规范包括什么?

规范了哪些接口、规范了哪些类、规范了一个web应用中应该有哪些配置文件、规范了一个web应用中配置文件的名字、规范了一个web应用中配置文件的内容、规范了一个合法有效的web应用它的目录结构应该是怎样的。

5 开发第一个Servlet

5.1 开发步骤

第一步:在webapps目录下新建一 个目录,起名crm (这个crm就是webapp的名字) 。当然,也可以是其它项目,比如银行项目,可以创建一个目录bank, 办公系统可以创建一个oa。
注意: crm就是这个webapp的根

第二步:在webapp的根下新建一 个目录: WEB-NF
注意:这个目录的名字是Servlet规范中规定的,必须全部大写,必须一模一 样。必须的必须。

第三步:在WEB-INF目录下新建一 个目录: classes
注意:这个目录的名字必须是全部小写的classes。 这也是Servlet规范中规定的。另外这个目录下一定存放的是Java程序编译之后的class文件(这里存放的是字节码文件)。

第四步:在WEB-INF目录下新建一 个目录: lib
注意:这个目录不是必须的。但如果一个webapp需 要第三方的jar包的话,这个jar包要放到这个lib目录下,这个目录的名字也不能随意编写,必须是全部小写的lib。例如java语言连接数据库需要数据库的驱动jar包。那么这个jar包就一定要放到ib目录下。这Servlet规范中规定的。

第五步:在WEB-INF目录下新建一个文件: web.xml
注意:这个文件是必须的,这个文件名必须叫做web.xml。这个文件必须放在这里。一个合法的webapp, web.xml文件是必须的,这个web.xml文件就是一个配置文件, 在这个配置文件中描述了请求路径和Servlet类之间的对照关系。这个文件最好从其他的webapp中拷贝,最好别手写。没必要。复制粘贴即可。

第六步:编写一个java程序,这个小java程序也不能随意开发,必须实现Servlet接口。                     编写小程序时,不一定要把源码写在classes目录中,只要把编译生成的class文件放入其中即可
注意:从JakartaEE9开始,Servlet接口的全名变了:jakarta.servlet.Servlet

第七步:编译我们编写的HelloServlet
重点:你怎么能让你的HelloServlet编译通过呢?配置环境变量CLASSPATH
CLASSPATH=.;D:\Java\dev\Javaweb\Tomcat\apache-tomcat-10.0.12\lib\servlet-api.jar                  CLSSPATH环境变量的作用就是,当编译java文件时,会去这个路径寻找需要的class文件前面的“.”表示在当前目录寻找,“;”表示去别的目录寻找。
思考问题:以上配置的CLASSPATH和Tomcat服务器运行有没有关系?
没有任何关系,以上配置这个环境变 量只是为了让你的HelloServlet能够正常编译生成class文件。

第八步:将以上编译之后的HelloSenvlet.lass文件拷贝到WEB-INF\classes目录下。

第九步:在web.xml文件中编写配置信息,让"请求路径"和"Servlet类名”关联在一起。
这一步用专业术语描述:在web.xml|文件中注册Servlet类。

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaeehttps://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0"metadata-complete="true"><!--servlet描述信息--><!--任何一个servlet都对应一个servlet-mapping --><servlet><servlet-name>fjafnjeml</servlet-name><!--这个位置必须是带有包名的全限定类名--><servlet-class>com.bjpowernode.servlet.HelloServlet</servlet-class></servlet><!--servlet映射信息--><servlet-mapping><!--这个也是随便的,不过这里写的内容要和上面的一样。--><servlet-name>fjafnjeml</servlet-name><!--这里需要一个路径--><!--这个路径唯一的要求是必须以 / 开始--><!--当前这个路径可以随便写--><url-pattern>/daw/dw/fe/qw</url-pattern></servlet-mapping></web-app>

第十步:启动Tomcat服务器

第十一步:打开浏览器,在浏览器地址栏上输入一个url, 这个URL必须是:http://127.0.0.1:8080/crm/zw/wzj/hhh                                                                                        浏览器路径复杂可以使用超链接,HTML页面只能放在WEB-INF目录外

注意一点:解决Tomcat服务器在DOS命令窗口中的乱码问题(控制台乱码)
将CATALINA_ HOME/conf/logging.properties文件中的内容修改如下: .
java.util.logging.ConsoleHandler.encoding = GBK

代码:

java小程序:

package com.bjpowernode.servlet;import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.IOException;
import java.io.PrintWriter;public class HelloServlet implements Servlet{// 5个方法public void init(ServletConfig config) throws ServletException{}public void service(ServletRequest request,ServletResponse response)throws ServletException , IOException{// 向控制台打印输出System.out.println("My First Servlet, Hello Servlet");// 设置响应的内容类型是普通文本或html代码// 需要在获取流对象之前设置,有效。response.setContentType("text/html");// 怎么将一个信息直接输出到浏览器上?// 需要使用ServletResponse接口:response// response表示响应:从服务器向浏览器发送数据叫做响应。PrintWriter out = response.getWriter();// 设置响应的内容类型时不要在获取流之后设置。//response.setContentType("text/html");out.print("Hello Servlet, You are my first servlet!");// 浏览器是能够识别html代码的,那我们是不是应该输出一段HTML代码呢?out.print("<h1>hello servlet,你好Servlet</h1>");// 这是一个输出流,负责输出字符串到浏览器// 这个输出流不需要我们刷新,也不需要我们关闭,这些都由Tomcat来维护。/*out.flush();out.close();*/}public void destroy(){}public String getServletInfo(){return "";}public ServletConfig getServletConfig(){return null;}
}

当我们想把内容输出到浏览器时需要写入这样的代码:PrintWriter out = response.getWriter();      response表示相应:从服务器向浏览器发送数据叫做响应。然后out.print("...");写入想要输出的内容即可。

当我们想在浏览器输出html语言时,需要写入这样的代码:response.setContentType("text/html");这表示设置相应的内容类型是普通文本或者html代码,需要再获取流对象之前设置,也就是在response那条代码之前。

5.2 Servlet中编写JDBC连接数据库

和之前学的类似,只需把JDBC代码放入service方法中即可,不过如今我们需要把数据输出到浏览器上,所以添加几行html相关代码即可,这个上一小节有学到。注意要将jdbc连接数据库的jar包加入到lib目录中,并且web.xml文件中添加一个新的目录与java小程序的对应关系。代码如下:

package com.bjpowernode.servlet;import jakarta.servlet.Servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.ServletConfig;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;public class StudentServlet implements Servlet{public void init(ServletConfig config) throws ServletException{}public void service(ServletRequest request,ServletResponse response)throws ServletException , IOException{response.setContentType("text/html");PrintWriter out = response.getWriter();out.print("学生信息如下:" + "<br>");// 编写JDBC代码,连接数据库,查询所有学生信息。Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try{// 注册驱动 (com.mysql.jdbc.Driver,这个已过时。)// 新版本中建议使用:com.mysql.cj.jdbc.Driver驱动。Class.forName("com.mysql.cj.jdbc.Driver");// 获取连接String url = "jdbc:mysql://127.0.0.1:3306/db1";String user = "root";String password = "123456";conn = DriverManager.getConnection(url, user, password);// 获取预编译的数据库操作对象String sql = "select id,loginName,loginPwd,realName from t_user";ps = conn.prepareStatement(sql);// 执行SQLrs = ps.executeQuery();// 处理查询结果集while(rs.next()){String id = rs.getString("id");String loginName = rs.getString("loginName");String loginPwd = rs.getString("loginPwd");String realName = rs.getString("realName");//System.out.println(no + "," + name);out.print(id + "," + loginName + "," + loginPwd +"," + realName + "<br>");}}catch(Exception e){e.printStackTrace();}finally{// 释放资源if(rs != null){try{rs.close();}catch(Exception e){e.printStackTrace();}}if(ps != null){try{ps.close();}catch(Exception e){e.printStackTrace();}}if(conn != null){try{conn.close();}catch(Exception e){e.printStackTrace();}}}}public void destroy(){}public String getServletInfo(){return "";}public ServletConfig getServletConfig(){return null;}
}
     <servlet><servlet-name>servletJDBC</servlet-name><servlet-class>com.bjpowernode.servlet.StudentServlet</servlet-class></servlet><servlet-mapping><servlet-name>servletJDBC</servlet-name><url-pattern>/zw/wzj/aaa</url-pattern></servlet-mapping>

结果:

6 使用IDEA工具开发Servlet

  • 第一步:New Project(我比较习惯先创建一个Empty Project【空工程】,然后在空工程下新建Module【模块】,这不是必须的,只是一种习惯,你可以直接新建非空的Project),这个Empty Project起名为:javaweb(不是必须的,只是一个名字而已。一般情况下新建的Project的名字最好和目录的名字一致。)
  • 第二步:新建模块(File --> new --> Module...)
    • 这里新建的是一个普通的JavaSE模块(这里先不要新建Java Enterprise模块)
    • 这个Module自动会被放在javaweb的project下面。
    • 这个Module起名:servlet01
  • 第三步:让Module变成JavaEE的模块。(让Module变成webapp的模块。符合webapp规范。符合Servlet规范的Module)
    • 在Module上点击右键:Add Framework Support...(添加框架支持)
    • 在弹出的窗口中,选择Web Application(选择的是webapp的支持)
    • 选择了这个webapp的支持之后,IDEA会自动给你生成一个符合Servlet规范的webpp目录结构。
    • 重点,需要注意的:在IDEA工具中根据Web Application模板生成的目录中有一个web目录,这个目录就代表webapp的根

  • 第四步(非必须):根据Web Application生成的资源中有index.jsp文件,这里我选择删除这个index.jsp文件。
  • 第五步:编写Servlet(StudentServlet)
    • class StudentServlet implements Servlet
    • 这个时候发现Servlet.class文件没有。怎么办?将CATALINA_HOME/lib/servlet-api.jar和jsp-api.jar添加到classpath当中(这里的classpath说的是IDEA的classpath
      • File --> Project Structrue --> Modules --> + 加号 --> Add JARS....
    • 实现jakarta.servlet.Servlet接口中的5个方法。
  • 第六步:在Servlet当中的service方法中编写业务代码(我们这里连接数据库了。)
  • 第七步:在WEB-INF目录下新建了一个子目录:lib(这个目录名可不能随意,必须是全部小写的lib),并且将连接数据库的驱动jar包放到lib目录下。
  • 第八步:在web.xml文件中完成StudentServlet类的注册。(请求路径和Servlet之间对应起来)
  • ​
    <?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>studentServlet</servlet-name><servlet-class>com.itzw.javaweb.servlet01.StudentServlet</servlet-class></servlet><servlet-mapping><servlet-name>studentServlet</servlet-name><url-pattern>/servlet/student</url-pattern></servlet-mapping>
    </web-app>​
  • 第九步:给一个html页面,在HTML页面中编写一个超链接,用户点击这个超链接,发送请求,Tomcat执行后台的StudentServlet。

    • student.html

    • 这个文件不能放到WEB-INF目录里面,只能放到WEB-INF目录外面。

    • student.html文件的内容

    • <!DOCTYPE html>
      <html lang="en">
      <head><meta charset="UTF-8"><title>student page</title>
      </head>
      <body><!--这里的项目名是 /xmm ,无法动态获取,先写死--><a href="/xmm/servlet/student">student list</a>
      </body>
      </html>
      
  • 第十步:让IDEA工具去关联Tomcat服务器。关联的过程当中将webapp部署到Tomcat服务器当中。

    • IDEA工具右上角,绿色小锤子右边有一个:Add Configuration
    • 左上角加号,点击Tomcat Server --> local
    • 在弹出的界面中设置服务器Server的参数(基本上不用动)
    • 在当前窗口中有一个Deployment(点击这个用来部署webapp),继续点击加号,部署即可。
    • 修改 Application context为:/xmm
  • 第十一步:启动Tomcat服务器

    • 在右上角有绿色的箭头,或者绿色的小虫子,点击这个绿色的小虫子,可以采用debug的模式启动Tomcat服务器。
    • 我们开发中建议适用debug模式启动Tomcat
  • 第十二步:打开浏览器,在浏览器地址栏上输入:http://localhost:8080/xmm/student.html

java小程序代码:

package com.itzw.javaweb.servlet01;import jakarta.servlet.*;import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;public class StudentServlet implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {//设置响应格式response.setContentType("text/html");PrintWriter out = response.getWriter();Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接String url = "jdbc:mysql://127.0.0.1:3306/db1";String user = "root";String password = "123456";conn = DriverManager.getConnection(url,user,password);//获取预编译的数据库操作对象String sql = "select id,balance from t_act";ps = conn.prepareStatement(sql);//执行sqlrs = ps.executeQuery();//处理结果集while (rs.next()){int id = rs.getInt("id");String balance = rs.getString("balance");out.print(id + "," + balance + "<br>");}} catch (Exception e) {e.printStackTrace();}finally {if (rs != null) {try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (ps != null) {try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}}}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

7 Servlet中的方法概述

构造方法只执行一次,在Tomcat服务器启动时并不会调用任何方法,当用户访问服务器时,Tomcat会先调用构造方法。

init方法只执行一次,init被翻译为初始化,在Servlet对象被创建之后执行,在构造方法之后执行。init方法使用很少,通常在init方法中做初始化操作,如初始化数据库连接池,初始化线程池等等。

service方法:用户发送一次请求执行一次,发送N次请求执行N次,service方法是我们使用最多的,是处理用户请求的核心方法。

destroy方法:只执行一次,在Tomcat关闭前执行,相当于遗言,此方法使用也很少,通常在destroy方法中进行资源关闭等。

注意:init方法的功能好像和无参构造一样,init能完成的构造方法也可以,为什么还需要init方法?更多的原因是,不建议我们自己写构造方法,因为如果忘记写无参构造只写了有参构造就会出现错误(500错误),500是一个HTTP协议的错误状态码,一般情况下是因为服务器端的java程序出现了异常。

8 适配器模式改造Servlet

通过上面的练习发现一个问题,每次都要实现Servlet接口,而Servlet中的方法很多却基本上用不到,搞得代码很丑陋,怎么解决?

现实生孩子我们发现,当我们想给手机充电时需要一个充电器或者说适配器,它像一个中介或者说一个接口来过度能更方便的充电,我们也可以写一个适配器来协助更方便的写代码。

写个适配器:

package com.itzw.javaweb.servlet;import jakarta.servlet.*;import java.io.IOException;public abstract class GenericServlet implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}/*** 抽象方法最常用,注意抽象方法没有主体,不需要大括号* @param servletRequest* @param servletResponse* @throws ServletException* @throws IOException*/@Overridepublic abstract void service(ServletRequest servletRequest, ServletResponse servletResponse)throws ServletException, IOException ;@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

简单些个servlet继承适配器:

package com.itzw.javaweb.servlet;import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;import java.io.IOException;public class LoginServlet extends GenericServlet{/*这样就很简洁*/@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("登陆成功了捏。。。");}
}

添加配置文件:

    <servlet><servlet-name>loginServlet</servlet-name><servlet-class>com.itzw.javaweb.servlet.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>loginServlet</servlet-name><url-pattern>/login</url-pattern></servlet-mapping>

配置Tomcat

运行:

但是有个问题,当我想在service中用init方法中的ServletConfig对象就用不了了,需要再改造。

我们知道的是,ServletConfig对象创建在init方法中,是局部变量,但是此方法是Tomcat操作的,所以Tomcat中会创建一个ServletConfig对象传入到init方法中从而执行init方法。那么如何在service方法中拿到这个对象呢?

可以创建使用ServletConfig创建一个变量,然后在init方法中将ServletConfig对象传到这个变量中,很巧的是在Servlet接口中有getServletConfig方法,好像就是给这种情况准备一样,在getServletConfig方法中返回这个变量,这样就能在继承的service方法中调用getServletConfig方法得到这个对象了。运行确实可以得到。

但是这样又有一个问题,假如我真的要用到init方法该怎么办,虽然用的少,但是确实我想重写init该怎么办?需要再改造。

假如我在子类重写了init方法,那么父类的init方法就不会执行,那上一步的改造就废了。所以不能让子类重写init方法,不允许子类重写方法可以加个final关键字。但是我想重写啊,该怎么办?那既然子类不能重写就在父类重写。可以先在父类重写一个无参init方法,在有参init方法中调用这个无参init方法,然后我在子类中再重写这个无参init方法,这样有参init必然会执行,也就必然会调用到无参init,而子类重写的init必然是无参init,这样保证了service方法中可以正常使用ServletConfig对象,也可以重写init方法。

 

执行成功。

有个好消息是忙活了半天,GenericServlet这个适配器Tomcat中已经写好了,打开源码发现和我们写的差不多,我们直接使用就可以了。

测试一下:

package com.itzw.javaweb.servlet;import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;import java.io.IOException;public class UserServlet extends GenericServlet {@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("Tomcat的GenericServlet执行了。。。");}
}

更好的消息是,还有更好用的“适配器”,我们一般也不用GenericServlet。。。。日常白学。

9 ServletConfig接口详解

ServletConfig是Servlet中的一员,ServletConfig是一个接口,Tomcat服务器实现了这个接口,一个Servlet对象中有一个ServletConfig对象,它们一一对应,在创建Servlet对象的同时创建了ServletConfig对象

ServletConfig有什么用?

在翻开GenericServlet接口我们发现里面有这样三个方法,其中getServletConfig就是来获取ServletConfig对象,而其它两个方法都用到了这个对象,通过翻开帮助文档我们得知ServletConfig里面装的是配置文件信息,是servlet标签中的信息,也就是可以获取到web.xml文件中的初始化参数配置信息。

接下来我们在web.xml文件中写入一些初始化信息,这些信息写在servlet标签内

<servlet><servlet-name>config</servlet-name><servlet-class>com.itzw.javaweb.servlet.ConfigTest</servlet-class><!--在这里写入Servlet对象的初始化信息--><init-param><param-name>driver</param-name><param-value>com.mysql.cj.jdbc.Driver</param-value></init-param><init-param><param-name>url</param-name><param-value>jdbc:mysql://localhost:3306/db1</param-value></init-param><init-param><param-name>user</param-name><param-value>root</param-value></init-param><init-param><param-name>password</param-name><param-value>123456</param-value></init-param></servlet>

接下来我们在java小程序内借助getServletConfig获取这些信息。

package com.itzw.javaweb.servlet;import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;public class ConfigTest extends GenericServlet {@Overridepublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();//获取servlet名称String servletName = this.getServletName();//结果和web.xml中的信息是对应的 <servlet-name>config</servlet-name>out.print(servletName + "<br>");//获取初始化信息中的nameEnumeration<String> names = this.getInitParameterNames();while (names.hasMoreElements()){String s = names.nextElement();//根据name获取valueString value = this.getInitParameter(s);out.print("name:" + s + ",value:" + value + "<br>");}}
}

结果:

从这我们可以看出这个小东西还是挺有用的,在后面连接数据库中应该可以更方便。

10 ServletContext接口详解

10.1 ServletContext概述

ServletContext是接口,是Servlet规范中的一员,ServletContext是Tomcat服务器实现的。ServletContext对象再WEB服务器启动时创建的,ServletContext对象时WEB服务器创建的,经测试,我们发现对于webapp来说,ServletContext对象只有一个,ServletContext对象在关闭服务器时销毁,ServletContext对象其实对应的就是整个web.xml文件,因为在同一个webapp中不管有多少java小程序或者说有多少servlet,只有一个web.xml文件,这里和ServletConfig区分开来。

10.2 ServletContext作用

用处一:既然ServletContext对象对应整个web.xml文件,那么它可以获取到web.xml中的配置文件信息,不过这个信息是应用级的配置信息,一般一个项目中共享的配置信息会放到这里,下面是这种配置信息的模式:

    <context-param><param-name>pageSize</param-name><param-value>10</param-value></context-param><context-param><param-name>startIndex</param-name><param-value>0</param-value></context-param>

以上的信息使用ServletContext对象可以获取,下面演示如何获取

        //获取ServletContext对象ServletContext application = this.getServletContext();out.print("ServletContext的对象是:" + application+ "<br>");//获取所有上下文初始化参数的nameEnumeration<String> names = application.getInitParameterNames();//遍历namewhile (names.hasMoreElements()){String s = names.nextElement();//根据name获取对应的valueString value = application.getInitParameter(s);out.print(s + "=" + value + "<br>");}

这种信息有什么用呢:一般用在限制一页网页展示的信息量上。

用处二:获取应用的根路径(非常重要)

在java代码中,不要将根路径写死,这也是我们学代码一直在讲的解耦合,提高代码的通用性:

        //获取context的根String contextPath = application.getContextPath();out.print("此应用的根:" + contextPath + "<br>");//获取文件的绝度路径,这里的文件是web目录下的文件,默认去web下面找//前面加不加“/”都可以String realPath = application.getRealPath("index.jsp");out.print(realPath + "<br>");

用处三:写日志

需要注意的是,日志文件存放在运行tomcat后在idea中找到这样一个目录:

        //写日志application.log("大家好,我是练习时长两年半的个人练习生,喜欢唱跳rap蓝球。");//可以使用日志记录异常int age = 17;if (age < 18){application.log("对不起您未成年,请绕行",new RuntimeException("小屁孩滚滚滚"));}

10.3 应用域

ServletContext对象还有另一个名字:应用域(后面还有其它域,例如:请求域、会话域)

如果所有用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中。

为什么这些共享数据很少修改或者说不修改,因为如果涉及修改必然存在线程并发所带来的安全问题,所以放在ServletContext对象中的数据一般是只读的。

存:怎么向ServletContext应用域中存数据

  • setAttribute方法

取:怎么从ServletContext应用域中取数据

  • getAttribute方法

删:怎么删除ServletContext应用域中的数据

  • removeAttribute方法

这个小程序完整代码:

package com.itzw.javaweb.servlet;import jakarta.servlet.*;import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;public class AServlet extends GenericServlet {@Overridepublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();//获取ServletContext对象ServletContext application = this.getServletContext();out.print("ServletContext的对象是:" + application+ "<br>");//获取所有上下文初始化参数的nameEnumeration<String> names = application.getInitParameterNames();//遍历namewhile (names.hasMoreElements()){String s = names.nextElement();//根据name获取对应的valueString value = application.getInitParameter(s);out.print(s + "=" + value + "<br>");}//获取context的根String contextPath = application.getContextPath();out.print("此应用的根:" + contextPath + "<br>");//获取文件的绝度路径,这里的文件是web目录下的文件,默认去web下面找//前面加不加“/”都可以String realPath = application.getRealPath("index.jsp");out.print(realPath + "<br>");//写日志application.log("大家好,我是练习时长两年半的个人练习生,喜欢唱跳rap蓝球。");//可以使用日志记录异常int age = 17;if (age < 18){application.log("对不起您未成年,请绕行",new RuntimeException("小屁孩滚滚滚"));}//准备数据User user = new User("王德发","123");//存//application.setAttribute("userObj",user);//取Object userObj = application.getAttribute("userObj");out.print(userObj);//删application.removeAttribute("userObj");}
}

JavaWeb-Servlet(上)相关推荐

  1. JavaWeb——Servlet(全网最详细教程包括Servlet源码分析)

    JavaWeb--Servlet Tomcat工作机制动画演示(点击动图可全屏观看) 什么是Servlet Servlet(Server Applet),全称Java Servlet,未有中文译文.是 ...

  2. java flex 上传文件_使用Flex和java servlet上传文件

    资源都是来自网上.本实例将展示使用Flex和java servlet上传文件. 事前准备就是到http://commons.apache.org 下载common-fileupload-1.1.1.j ...

  3. 上传文件到服务器并显示,J2EE如何实现Servlet上传文件到服务器并相应显示功能...

    J2EE如何实现Servlet上传文件到服务器并相应显示功能 发布时间:2021-07-10 11:44:54 来源:亿速云 阅读:82 作者:小新 这篇文章将为大家详细讲解有关J2EE如何实现Ser ...

  4. Servlet上传文件和下载文件示例

    Java Web应用程序中的文件上载和下载以及常见任务. 由于最近我写了很多有关Java servlet的文章 ,因此我想提供一个使用servlet上传和下载文件的示例示例. 用例 我们的用例是提供一 ...

  5. servlet上传下载(任何格式的都可以)

    jar不能低于此版本,JDK1.6以上,否则户报错 <dependency> <groupId>commons-fileupload</groupId> <a ...

  6. 原生Servlet 上传文件

    依赖jar <dependency><groupId>commons-fileupload</groupId><artifactId>commons-f ...

  7. Javaweb servlet体系结构与原理剖析

    Javaweb servlet体系结构与原理剖析 1.Servlet的工作过程 2.Servlet体系结构 3.Servlet工作原理 4.Servlet生命周期 1.Servlet的工作过程 当用户 ...

  8. Javaweb Servlet 下载文件

    JavaWeb Servlet 实现下载文件 Servlet类 import javax.servlet.ServletException; import javax.servlet.ServletO ...

  9. javaweb(servlet)+jsp+Mysql实现的简单相册管理系统(功能包含登录、管理首页、添加图片、分类管理、修改密码、图片详情等)

    博客目录 javaweb(servlet)+jsp+Mysql实现的简单相册管理系统 实现功能截图 系统功能 使用技术 代码 完整源码 javaweb(servlet)+jsp+Mysql实现的简单相 ...

  10. javaweb(servlet)+jsp+Mysql实现的酒店客房管理系统(功能包含登录、用户管理、住客信息管理、房型管理、房间管理、会员星级管理、订单管理等)

    博客目录 javaweb(servlet)+jsp+Mysql实现的酒店客房管理系统 实现功能截图 系统功能 使用技术 代码 完整源码 javaweb(servlet)+jsp+Mysql实现的酒店客 ...

最新文章

  1. Oracle删除表主键语句
  2. python基础教程第三版怎么样-Python基础教程(第三版)(七)再谈抽象
  3. JDK源码分析(7)之 Reference 框架概览
  4. DATAX工具同步数据从hdfs到drds性能优化
  5. .NET Core容器化@Docker
  6. Linux云服务ModuleNotFoundError: No module named 'MySQLdb'
  7. $routeParams $route.current.params
  8. html调用python_flask之模板html中调用python函数方法
  9. 华为5g鸿蒙折叠,华为5G折叠概念新机:内折叠+麒麟9000+鸿蒙OS 这才是华为的实力...
  10. Java运行原理研究(未完待续)
  11. coxphfit+matlab,Cox Proportional Hazards Model
  12. l2-004 这是二叉搜索树吗?_MySQL索引为何选择B+树
  13. 英语总结系列(十四):换一种心情充满趣味的二月
  14. mac Sourcetree 账号密码输入错误后, 重新输入的方法
  15. 拓端tecdat|R语言生存分析: 时变竞争风险模型分析淋巴瘤患者
  16. Mysql ODBC 数据源配置
  17. N1盒子刷入codesys当PLC使用
  18. 在Eclipse中安装JSHint插件
  19. 无人机影像的植被覆盖度、叶面积指数估算
  20. 一览数据异步加载的解决方案

热门文章

  1. 快递100Api调用实时快递查询
  2. 常用网络结构:Alex,VGG,Resnet对比
  3. python 定时运行 定时关闭_Python脚本用于定时关闭网易云音乐PC客户端
  4. 【基础框架-SSM】Maven_进阶
  5. 2020 web前端面试题及答案大全
  6. From detailed models to formal spiking neurons
  7. 微信网页授权校验文件
  8. 基于安卓的校园跳蚤市场app
  9. epoch mysql_PostgreSQL中epoch的用法
  10. Trade strategy交易策略