目录
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 应用域
C/S架构
B/S架构
Client/ Server (客户端/服务器)
C/S架构的特点:需要安装特定的客户端软件。
C/S架构的系统优点和缺点分别是什么?
优点:
缺点:
我们经常使用的百度、京东等等网页就是B/S架构。
B/S架构的优点和缺点。
优点:
缺点:
配置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文件
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,经测试没有问题
第一步:找到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,直接以/开始带项目名就是一个绝对路径,如本次项目中用户登录,这就是绝对路径
两个HTML文件内容为:
index
我的第一个页面
用户登录
login
不过本次第一个项目出了点小问题,输入URL无法访问到html资源,将服务器重启也不行,但是将dos窗口关闭重开就可以了不知道为啥捏。
做了这么多准备终于到了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服务器应该根据用户输入的请求路径获取相应的xxxServlet
FileReader reader = new FileReader("web.properties");
Properties pro = new Properties();
pro.load(reader);
reader.close();
//通过key获取value
String 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应用它的目录结构应该是怎样的。
第一步:在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类。
fjafnjeml
com.bjpowernode.servlet.HelloServlet
fjafnjeml
/daw/dw/fe/qw
第十步:启动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("hello servlet,你好Servlet
");
// 这是一个输出流,负责输出字符串到浏览器
// 这个输出流不需要我们刷新,也不需要我们关闭,这些都由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那条代码之前。
和之前学的类似,只需把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("学生信息如下:" + "
");
// 编写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);
// 执行SQL
rs = 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 + "
");
}
}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;
}
}
servletJDBC
com.bjpowernode.servlet.StudentServlet
servletJDBC
/zw/wzj/aaa
结果:
studentServlet
com.itzw.javaweb.servlet01.StudentServlet
studentServlet
/servlet/student
第九步:给一个html页面,在HTML页面中编写一个超链接,用户点击这个超链接,发送请求,Tomcat执行后台的StudentServlet。
student.html
这个文件不能放到WEB-INF目录里面,只能放到WEB-INF目录外面。
student.html文件的内容
student page
student list
第十步:让IDEA工具去关联Tomcat服务器。关联的过程当中将webapp部署到Tomcat服务器当中。
第十一步:启动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 {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public 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);
//执行sql
rs = ps.executeQuery();
//处理结果集
while (rs.next()){
int id = rs.getInt("id");
String balance = rs.getString("balance");
out.print(id + "," + balance + "
");
}
} 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();
}
}
}
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
构造方法只执行一次,在Tomcat服务器启动时并不会调用任何方法,当用户访问服务器时,Tomcat会先调用构造方法。
init方法只执行一次,init被翻译为初始化,在Servlet对象被创建之后执行,在构造方法之后执行。init方法使用很少,通常在init方法中做初始化操作,如初始化数据库连接池,初始化线程池等等。
service方法:用户发送一次请求执行一次,发送N次请求执行N次,service方法是我们使用最多的,是处理用户请求的核心方法。
destroy方法:只执行一次,在Tomcat关闭前执行,相当于遗言,此方法使用也很少,通常在destroy方法中进行资源关闭等。
注意:init方法的功能好像和无参构造一样,init能完成的构造方法也可以,为什么还需要init方法?更多的原因是,不建议我们自己写构造方法,因为如果忘记写无参构造只写了有参构造就会出现错误(500错误),500是一个HTTP协议的错误状态码,一般情况下是因为服务器端的java程序出现了异常。
通过上面的练习发现一个问题,每次都要实现Servlet接口,而Servlet中的方法很多却基本上用不到,搞得代码很丑陋,怎么解决?
现实生孩子我们发现,当我们想给手机充电时需要一个充电器或者说适配器,它像一个中介或者说一个接口来过度能更方便的充电,我们也可以写一个适配器来协助更方便的写代码。
写个适配器:
package com.itzw.javaweb.servlet;
import jakarta.servlet.*;
import java.io.IOException;
public abstract class GenericServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 抽象方法最常用,注意抽象方法没有主体,不需要大括号
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
@Override
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse)
throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public 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{
/*这样就很简洁*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("登陆成功了捏。。。");
}
}
添加配置文件:
loginServlet
com.itzw.javaweb.servlet.LoginServlet
loginServlet
/login
配置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 {
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Tomcat的GenericServlet执行了。。。");
}
}
更好的消息是,还有更好用的“适配器”,我们一般也不用GenericServlet。。。。日常白学。
ServletConfig是Servlet中的一员,ServletConfig是一个接口,Tomcat服务器实现了这个接口,一个Servlet对象中有一个ServletConfig对象,它们一一对应,在创建Servlet对象的同时创建了ServletConfig对象
ServletConfig有什么用?
在翻开GenericServlet接口我们发现里面有这样三个方法,其中getServletConfig就是来获取ServletConfig对象,而其它两个方法都用到了这个对象,通过翻开帮助文档我们得知ServletConfig里面装的是配置文件信息,是servlet标签中的信息,也就是可以获取到web.xml文件中的初始化参数配置信息。
接下来我们在web.xml文件中写入一些初始化信息,这些信息写在servlet标签内
config
com.itzw.javaweb.servlet.ConfigTest
driver
com.mysql.cj.jdbc.Driver
url
jdbc:mysql://localhost:3306/db1
user
root
password
123456
接下来我们在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 {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//获取servlet名称
String servletName = this.getServletName();
//结果和web.xml中的信息是对应的 config
out.print(servletName + "
");
//获取初始化信息中的name
Enumeration names = this.getInitParameterNames();
while (names.hasMoreElements()){
String s = names.nextElement();
//根据name获取value
String value = this.getInitParameter(s);
out.print("name:" + s + ",value:" + value + "
");
}
}
}
结果:
从这我们可以看出这个小东西还是挺有用的,在后面连接数据库中应该可以更方便。
ServletContext是接口,是Servlet规范中的一员,ServletContext是Tomcat服务器实现的。ServletContext对象再WEB服务器启动时创建的,ServletContext对象时WEB服务器创建的,经测试,我们发现对于webapp来说,ServletContext对象只有一个,ServletContext对象在关闭服务器时销毁,ServletContext对象其实对应的就是整个web.xml文件,因为在同一个webapp中不管有多少java小程序或者说有多少servlet,只有一个web.xml文件,这里和ServletConfig区分开来。
用处一:既然ServletContext对象对应整个web.xml文件,那么它可以获取到web.xml中的配置文件信息,不过这个信息是应用级的配置信息,一般一个项目中共享的配置信息会放到这里,下面是这种配置信息的模式:
pageSize
10
startIndex
0
以上的信息使用ServletContext对象可以获取,下面演示如何获取
//获取ServletContext对象
ServletContext application = this.getServletContext();
out.print("ServletContext的对象是:" + application+ "
");
//获取所有上下文初始化参数的name
Enumeration names = application.getInitParameterNames();
//遍历name
while (names.hasMoreElements()){
String s = names.nextElement();
//根据name获取对应的value
String value = application.getInitParameter(s);
out.print(s + "=" + value + "
");
}
这种信息有什么用呢:一般用在限制一页网页展示的信息量上。
用处二:获取应用的根路径(非常重要)
在java代码中,不要将根路径写死,这也是我们学代码一直在讲的解耦合,提高代码的通用性:
//获取context的根
String contextPath = application.getContextPath();
out.print("此应用的根:" + contextPath + "
");
//获取文件的绝度路径,这里的文件是web目录下的文件,默认去web下面找
//前面加不加“/”都可以
String realPath = application.getRealPath("index.jsp");
out.print(realPath + "
");
用处三:写日志
需要注意的是,日志文件存放在运行tomcat后在idea中找到这样一个目录:
//写日志
application.log("大家好,我是练习时长两年半的个人练习生,喜欢唱跳rap蓝球。");
//可以使用日志记录异常
int age = 17;
if (age < 18){
application.log("对不起您未成年,请绕行",new RuntimeException("小屁孩滚滚滚"));
}
ServletContext对象还有另一个名字:应用域(后面还有其它域,例如:请求域、会话域)
如果所有用户共享一份数据,并且这个数据很少的被修改,并且这个数据量很少,可以将这些数据放到ServletContext这个应用域中。
为什么这些共享数据很少修改或者说不修改,因为如果涉及修改必然存在线程并发所带来的安全问题,所以放在ServletContext对象中的数据一般是只读的。
存:怎么向ServletContext应用域中存数据
取:怎么从ServletContext应用域中取数据
删:怎么删除ServletContext应用域中的数据
这个小程序完整代码:
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 {
@Override
public 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+ "
");
//获取所有上下文初始化参数的name
Enumeration names = application.getInitParameterNames();
//遍历name
while (names.hasMoreElements()){
String s = names.nextElement();
//根据name获取对应的value
String value = application.getInitParameter(s);
out.print(s + "=" + value + "
");
}
//获取context的根
String contextPath = application.getContextPath();
out.print("此应用的根:" + contextPath + "
");
//获取文件的绝度路径,这里的文件是web目录下的文件,默认去web下面找
//前面加不加“/”都可以
String realPath = application.getRealPath("index.jsp");
out.print(realPath + "
");
//写日志
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");
}
}