写在最后
为了这次面试,也收集了很多的面试题!
以下是部分面试题截图
当我点击浏览器的刷新按钮时,会出现只输出了servlet方法,而不再显示构造器方法和init方法:
最后,当我停止该程序时,控制台会输出destroy方法,不输出其它方法。
综合可知,这四个方法的生命周期如下图所示:
| 方法 | 生命周期2 |
| — | — |
| Servlet 构造器方法 | 只在第一次访问Servlet程序的时候会调用 |
| init初始化方法 | 只在第一次访问Servlet程序的时候会调用 |
| service方法 | 每次访问Servlet程序时都会调用 |
| destroy销毁方法 | 只在Servlet程序停止的时候调用 |
该小节内容需要结合本文第4、5、6章来理解
我们在HTML中知道,当以不同的方式提交表单后,出现的结果是不同的 ,那么这样就会存在一个问题,Tomcat服务器收到的请求和需要返回的请求是不同的,如果仅仅用ServletRequset,是无法区分GET与POST的。所以,我们需要利用ServletRequset的子类方法HttpServletRequest来解决这个问题。
在实际工作中,我们会采用如下代码所示的这样来对GET请求与POST请求进行区分,这样的话,当Tomcat接受到不同的请求也可以执行不同的操作。
package sharm.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class TestHelloServlet implements Servlet {
/**
-
service方法是专门用来处理请求和响应的,简单来说就是,只要执行servlet程序,就会执行该方法
-
@param servletRequest
-
@param servletResponse
-
@throws ServletException
-
@throws IOException
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException,
IOException {
System.out.println(“Hello Servlet.”);
// 强制类型转换(因为HttpServletRequest有getMethod()方法)
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
// 获取请求的方式
String method = httpServletRequest.getMethod();
if (“GET”.equals(method)) {
doGet();
} else if (“POST”.equals(method)) {
doPost();
}
}
}
1.5.1 实际工作中的GET和POST请求
| GET请求 | POST请求 |
| — | — |
| form标签中的method=get | form标签中的method=post |
| a标签 | |
| link标签引入CSS文件 | |
| script 标签引入js文件 | |
| img 标签引入图片 | |
| iframe 引入html 页面 | |
| 在浏览器地址栏中输入地址后敲回车 | |
1.5.2 GET和POST表单请求的差异
| GET请求 | POST请求 |
| — | — |
| 浏览器地址栏中的地址是:action 属性[+?+请求参数] (其中请求参数的格式是:name=value&name=value) | 浏览器地址栏中只有action 属性值 |
| 不安全 | 相对于GET请求要安全 |
| 它有数据长度的限制 | 理论上没有数据长度的限制 |
继承体系如下所示,具体的代码可以从源码中阅读。
所以,在实际工作中,我们常常是继承HttpServlet类而不是Servlet接口来实现Servlet程序。
具体步骤就是:
-
前端:在web目录下创建HTML页面
-
后端:在src目录下创建一个一个类去继承HttpServlet类,然后根据业务需要重写doGet 或doPost方法。
-
映射:到web.xml中的配置Servlet 程序在前端的访问地址。
===================================================================================
ServletConfig类是Servlet程序的配置信息类。Servlet 程序和ServletConfig类都是由Tomcat 负责创建,我们负责使用。Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet 程序创建时,就创建一个对应的ServletConfig 对象。
-
可以获取Servlet 程序的别名servlet-name的值
-
获取初始化参数init-param
-
获取ServletContext 对象
2.2 根据Servlet程序的操作流程来说明ServletConfig的三大功能
整个工程运行的流程就是:点击IDEA中的运行,之后Tomcat服务器便会运行起来 ,这个时候,可以在Chrome看到Tomcat的web网页,然后我在web网页的地址后添加一个资源路径,那么由于我在xml配置文件中已经将该资源路径与src中的Servlet程序相映射起来 ,所以,也就是运行了该 Servlet程序,这个时候,便会在IDEA的控制台是输出Servlet程序。
2.2.1 首先配置XML文件
username
sharm
password
sharmpass
TestServletConfig
sharm.servlet.TestServletConfig
username
sharm
url
www.sharm.com
TestServletConfig
/servletconfig
2.2.2 在src目录下的sharm.servlet包下编写TestServletConfig测试类
代码如下所示,完成ServletConfig的功能测试
package sharm.servlet;
import javax.servlet.ServletConfig;
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 TestServletConfig extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
//一定要加这个super,因为,当子类也有init,父类也有init,那么调用就会调用子类的,父类保存的this.config就会丢失。
// 这个时候,如果在子类init方法中重新super.init()一下父类,那么就没问题。
super.init(config);
//1 可以获取Servlet 程序的别名servlet-name 的值
System.out.println(“TestHelloServlet程序的别名是:”+config.getServletName());
//2 获取初始化参数init-param
System.out.println(“初始化参数username的值是:”+config.getInitParameter(“username”));
System.out.println(“初始化参数username的值是:”+config.getInitParameter(“username”));
//3 获取ServletContext 对象
System.out.println(config.getServletContext());
}
}
====================================================================================
1) ServletContext 是一个接口,它表示Servlet 上下文对象。
2) 一个web 工程,只有一个ServletContext 对象实例。
3) ServletContext 对象是一个域对象。(概念可能很难理解,具体使用可以看代码实现,一目了然)
什么是域对象:域对象是可以像Map一样存取数据的对象,这里的域值得是存取数据的操作范围,这个范围是整个web工程。Map与域对象的方法上的差异如下:
| 对象\功能 | 存数据 | 取数据 | 删除数据 |
| — | — | — | — |
| 域对象 | setAttribute() | getAttribute() | removeAttribute() |
| Map | put() | get() | remove() |
4) ServletContext 是在web 工程部署启动的时候创建。在web 工程停止的时候销毁。
什么是部署:运行上会有四个选择,其中部署指的是工程重启,但Tomcat服务器是没有重启的。
-
获取web.xml 中配置的上下文参数context-param
-
获取当前的工程路径,格式: /工程路径
-
获取工程部署后在服务器硬盘上的绝对路径
-
像Map一样存取数据
3.3 根据Servlet程序的操作流程来说明ServletContext的四大功能
3.1 首先配置XML文件
username
sharm
password
sharmpass
TestServletContext
sharm.servlet.TestServletContext
TestServletContext
/servletcontext
TestServletContext2
sharm.servlet.TestServletContext2
TestServletContext2
/servletcontext2
3.2 在src目录下的sharm.servlet包下编写TestServletContext测试类实现四个功能
package sharm.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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 TestServletContext extends HttpServlet {
//默认执行doGet方法,故只重写doGet方法
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext =getServletContext();
System.out.println(servletContext);
//1 获取web.xml 中配置的上下文参数context-param
String username=servletContext.getInitParameter(“username”);
System.out.println(“context-parax参数的username值为:”+username);
String passward=servletContext.getInitParameter(“passward”);
System.out.println(“context-parax参数的passward值为:”+passward);
//2 获取当前的工程路径,格式: /工程路径
System.out.println(“当前工程路径:”+servletContext.getContextPath());
//3 获取工程部署后在服务器硬盘上的绝对路径
System.out.println(“工程部署在服务器硬盘上的绝对路径:”+servletContext.getRealPath(“/”));
//4 像MAP一样存储数据
System.out.println(“保存之前,Context1获取key1的值是:”+servletContext.getAttribute(“key1”));
servletContext.setAttribute(“key1”, “value1”);
System.out.println(“Context1 中获取域数据key1 的值是:”+ servletContext.getAttribute(“key1”));
}
}
3.3 代码说明一个web 工程,只有一个ServletContext 对象实例
即可以从TestServletContext2类中得到TestServletContext的属性值。
package sharm.servlet;
import javax.servlet.ServletContext;
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 TestServletContext2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext =getServletContext();
System.out.println(“Context1 中获取域数据key1 的值是:”+ servletContext.getAttribute(“key1”));
}
}
========================================================================================
每次只要有请求进入Tomcat 服务器,Tomcat 服务器就会把请求过来的HTTP 协议信息解析好封装到Request 对象中。然后传递到service 方法(doGet 和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。(写的代码越多,越能读通顺这段解释的意义。)
| 方法名 | 功能 |
| — | — |
| getRequestURI() | 获取请求的资源路径 |
| getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
| getRemoteHost() | 获取客户端的ip 地址 |
| getHeader() | 获取请求头 |
| getParameter() | 获取请求的参数 |
| getParameterValues() | 获取请求的参数(多个值的时候使用) |
| getMethod() | 获取请求的方式GET 或POST |
| setAttribute(key, value) | 设置域数据 |
| getAttribute(key) | 获取域数据 |
| getRequestDispatcher() | 获取请求转发对象 |
见代码注释,非常的详细。
package sharm.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
public class TestHttpServletRequest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求的字符集为UTF-8,从而解决中文乱码问题
//但是需要把下面这行代码放在请求参数调用之前才有效,实际中,放在方法中的第一行是最保险的
request.setCharacterEncoding(“UTF-8”);
//获取请求的资源路径
System.out.println("URI => " + request.getRequestURI());
//获取请求的统一资源定位符(绝对路径)
System.out.println("URL => " + request.getRequestURL());
//获取客户端的ip地址
/**
-
在IDEA中,使用localhost访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1
-
在IDEA中,使用127.0.0.1访问时,得到的客户端 ip 地址是 ===>>> 127.0.0.1
-
在IDEA中,使用 真实ip 访问时,得到的客户端 ip 地址是 ===>>> 真实的客户端 ip 地址
*/
System.out.println("客户端 ip地址 => " + request.getRemoteHost());
//获取请求头
System.out.println("请求头User-Agent ==>> " + request.getHeader(“User-Agent”));
//获取请求的方式GET或POST
System.out.println( "请求的方式 ==>> " + request.getMethod() );
String name = request.getParameter(“name”);
String passward = request.getParameter(“passward”);
String[] hobby = request.getParameterValues(“hobby”);
System.out.println(“name:”+name);
System.out.println(“passward:”+passward);
System.out.println(“hobby:”+ Arrays.asList(hobby));
}
}
我认为请求转发的关键就是一个Servlet程序可以唤醒另一个Servlet程序,而这个关键的步骤便是request.getRequestDispatcher方法。
我们的目的是通过TestServletRequestDispatcher1类将请求转发到TestServletRequestDispatcher1中。其中TestServletRequestDispatcher1的代码如下所示:
package sharm.servlet;
import javax.servlet.RequestDispatcher;
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 TestServletRequestDispatcher1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数(查看办事的材料)
String name = request.getParameter(“name”);
System.out.println(“由HTML上传到Tomcat服务器的用户名为:”+name);
//HttpServletRequest也有SevletContext中的setAttribute这个方法
request.setAttribute(“key1”,“同意”);
//下面这几行代码才是请求转发的关键:只有书写了下面两行代码,请求转发才真正有效
//将该请求转发到/testServletRequestDispatcher2资源路径下,该路径就是我想请求转发到的路径
RequestDispatcher requestDispatcher = request.getRequestDispatcher(“/testServletRequestDispatcher2”);
//forward方法将当前资源的request和response转发到该requestDispatcher指定的资源
//使得Servlet2中的request和response与Servlet1一致
requestDispatcher.forward(request,response);
}
}
其中TestServletRequestDispatcher2的代码如下所示:
package sharm.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 TestServletRequestDispatcher2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数(查看办事的材料)
//如果我在form.html中action的是该类指定的资源路径,则会发现TestServletRequestDispatcher1类中的
Docker步步实践
目录文档:
①Docker简介
②基本概念
③安装Docker
④使用镜像:
⑤操作容器:
⑥访问仓库:
⑦数据管理:
⑧使用网络:
⑨高级网络配置:
⑩安全:
⑪底层实现:
⑫其他项目:
实践
目录文档:
[外链图片转存中…(img-KpkauHbP-1715671711732)]
[外链图片转存中…(img-2DNZMRMl-1715671711732)]
①Docker简介
②基本概念
③安装Docker
[外链图片转存中…(img-V74IZtEd-1715671711733)]
④使用镜像:
[外链图片转存中…(img-XcDsRp0W-1715671711733)]
⑤操作容器:
[外链图片转存中…(img-ljIeHsO5-1715671711733)]
⑥访问仓库:
[外链图片转存中…(img-hkRbxete-1715671711734)]
⑦数据管理:
[外链图片转存中…(img-aH5YBLjO-1715671711734)]
⑧使用网络:
[外链图片转存中…(img-U6paDYAG-1715671711734)]
⑨高级网络配置:
[外链图片转存中…(img-TUCBkIWM-1715671711735)]
⑩安全:
[外链图片转存中…(img-mWBRY2Z9-1715671711735)]
⑪底层实现:
[外链图片转存中…(img-XeQvih3t-1715671711736)]
⑫其他项目:
[外链图片转存中…(img-UBz2pFft-1715671711736)]