【Servlet篇2】Servlet的工作过程,Servlet的api——HttpServletRequest
创始人
2024-05-27 18:24:58
0

 

一、Servlet的工作过程

二、Tomcat的初始化

步骤1:寻找到当前目录下面所有需要加载的Servlet(也就是类)

步骤2:根据类加载的结果创建实例(通过反射),并且放入集合当中

步骤3:实例创建好之后,调用Servlet的init()方法初始化一些属性

步骤4:创建TCP的socket,并且监听8080端口,等待客户端建立连接

步骤5:关闭服务器的时候,需要调用Servlet的destory()方法

 三、Tomcat处理请求

 步骤1:根据socket构造请求的对象(req)以及响应的对象(resp)

步骤2:判断请求的资源是否是一个静态的页面

步骤3:根据请求的URL找到处理请求的Servlet

步骤4:根据Servlet对象,来调用service方法

最后:简单概括一下Servlet的生命周期:

doPost方法乱码问题:

四、Servlet的核心api

HttpServletRequest类

 String getRequestURI()和String getRequestURL()

String getQueryString() 

     Enumeration getParameterNames()

      String getParameter(String name)

      String getHeader("name")

      InputStream getInputStream() 

      String getContextPath()

一、Servlet的工作过程

       需要了解的是,Sevlet是工作在应用层的,是一个应用程序。它是一个运行在用户态的的java进程

       第一步:客户端主机生产了http报文,然后经过一次封装,到达客户端的物理层。然后以光电信号的方式在网络当中传输。

       第二步:服务端主机在收到了对应的光电信号之后,进行了一次数据从物理层服务端的应用层的一次分用。

       第三步:服务端计算客户端的响应,然后在把数据通过response对象回写给客户端。


二、Tomcat的初始化

步骤1:寻找到当前目录下面所有需要加载的Servlet(也就是类)

       在这一篇文章当中,我们提到了如何把一个项目打包成一个war包。war包当中的文件都是.class为后缀名的。

        然后把这一个war包放入到Tomcat的webapps目录下面。双击startup.bat就可以运行Tomcat了。

【Servlet篇2】创建一个web项目_革凡成圣211的博客-CSDN博客Tomcat的web项目https://blog.csdn.net/weixin_56738054/article/details/129265315?spm=1001.2014.3001.5501         然后tomcat就会从webapps里找到那些.class对应的Servlet类,进行加载。

        可以看到,经过编译的Servlet,都变成了.class结尾的了。 伪代码实现:

 public void start(){//第一步:通过Tomcat加载所有的.class结尾的文件Class[] allServletClasses=Tomcat.load();}

步骤2:根据类加载的结果创建实例(通过反射),并且放入集合当中

         遍历上面的allServletClasses数组。并且在遍历的过程当中,每遍历一个,都通过反射创建一个Servlet的实例对象。创建完成之后,再次把这些实例添加到Servlet实例的集合当中。

          伪代码实现:

/***这是一个存放Servlet实例的集合*/private final List instanceServlet=new ArrayList<>();public void start() throws InstantiationException, IllegalAccessException {//第一步:通过Tomcat加载webapps下面所有的.class结尾的文件Class[] allServletClasses=Tomcat.load();//第二步:根据类加载的结果创建Servlet的实例for(Class servletClass:allServletClasses){//根据class加载的结果,创建servlet的实例对象Servlet servlet= servletClass.newInstance();//把Servlet的实例对象存放到集合当中instanceServlet.add(servlet);}}

步骤3:实例创建好之后,调用Servlet的init()方法初始化一些属性

         伪代码:

for(Servlet servlet:instanceServlet){//init方法默认情况下面什么都不做//但是可以初始化一些属性servlet.init();}

       前面的文章当中,我们提到了,如果一个普通的类想成为Servlet,那就一定需要首先继承于HttpServlet

       当然,也可以由当前的类初始化一些属性,那就需要重写init()方法了。

       每一个Servlet在启动的时候,都仅仅只会调用一次init()方法。


步骤4:创建TCP的socket,并且监听8080端口,等待客户端建立连接

 在服务端,使用线程池的的方式来处理每一个请求。

 在下面的伪代码当中,首先使用serverSocket监听8080端口。

然后服务端重复调用accept()方法等待客户端建立连接

并且使用往线程池当中提交任务的方式来处理请求

伪代码实现:

//这个socket是服务端TCP的socket,创建的时候默认占用8080端口ServerSocket serverSocket=new ServerSocket(8080);//使用线程池,添加任务ExecutorService service= Executors.newFixedThreadPool(10);while (true){//每当有一个客户端与当前的服务端建立连接的时候,就会监听8080端口//accept()一次Socket socket=serverSocket.accept();//向线程池提交任务service.execute(new Runnable() {@Overridepublic void run() {doHttpRequest(socket);}});}

其中,doHttpRequest方法内部,就是解析客户端发送请求的方法。也就是执行doGet被调用的过程。


步骤5:关闭服务器的时候,需要调用Servlet的destory()方法

 伪代码实现:

 //关闭服务器,销毁servletfor(Servlet servlet:instanceServlet){servlet.destroy();}

总览一下:Tomcat初始化的过程:


 三、Tomcat处理请求

 刚刚提到了,在doHttpServletRequest方法当中,是对于socket进行处理的过程。

 下面,继续通过伪代码的方式,来解析一下具体是怎样处理请求的。

 步骤1:根据socket构造请求的对象(req)以及响应的对象(resp)

 对于request:首先读取socket当中的数据,然后再按照HTTP协议的格式来返回。

 对于response:仅仅只是构造了一个空的对象,还没有填充响应的信息

伪代码: 

private void doHttpRequest(Socket socket) {//对于request,首先读取socket当中的数据,然后再按照HTTP协议的格式来返回HttpServletRequest request=HttpServletRequest.parse(socket);//构造一个没有填充数据是responseHttpServletResponse response=HttpServletResponse.build(socket);}

步骤2:判断请求的资源是否是一个静态的页面

伪代码:

       如果请求的资源是一个静态的页面,例如:https:....../.html这样的页面。那么就读取文件的内容,并且把文件的内容构造的resp对象当中。

【网络原理9】HTTP响应篇_革凡成圣211的博客-CSDN博客HTTP响应,HTTP状态码https://blog.csdn.net/weixin_56738054/article/details/129208502?spm=1001.2014.3001.5502         在HTTP响应篇这一篇文章当中提到了:HTTP响应头当中有一个属性代表的是返回的资源的类型(content type属性)。如果是一个静态的html页面,那么这个类型的值就是test/html

//访问的资源是一个静态的页面if(file.exists()){//通过response返回这一个页面return;}

步骤3:根据请求的URL找到处理请求的Servlet

伪代码:

//通过请求的URL路径,返回Tomcat加载的对应的那一个Servlet
Servlet ins=findInstance(request.getRequestURL());

 例如一个请求是:localhost:8080/hello106/hello

 那么这个hello代表的就是一个Servlet


步骤4:根据Servlet对象,来调用service方法

伪代码:

    try {//调用service方法ins.service(request,response);}catch (Exception e){}

其实在service方法内部,就是根据request的请求来判断当前的请求的方法是属于get还是post

如果是get请求,那么就交给doGet方法来进行处理。

如果是post请求,那么就交给doPost方法来及逆行处理。


下面,通过一张图,来总览一下Tomcat处理请求的各个步骤

最后:简单概括一下Servlet的生命周期:

当被tomcat初始化的时候:调用init方法完成一些属性的初始化操作;

当执行具体逻辑的时候:调用service方法,然后在内部判断是doGet还是doPost方法;

当执行完毕的时候:调用destroy方法销毁。


doPost方法乱码问题:

在一个类当中,首先让一个类继承于HttpServlet这一个类,然后重写doPost方法。

并且通过resp.getWriter().write(字符串内容);来在页面上面输出一段话:

/*** @author 革凡成圣211*/
@WebServlet("/method")
public class Servlet2 extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("POST响应");}
}

然后在前端页面当中通过post来提交请求(注意不可以直接在url地址栏当中输入,否则默认是get)

 

 但是看到,此处的中文出现了乱码:

  首先,分析一下,在当前的场景当中,字符串生成的两个环节:

  环节1:生成(idea里面通过硬编码的方式把这个字符串写进去)

  环节2:展示(浏览器把这个字符串显示到控制台当中)

如果以上的两个操作不一致,那么就比较容易出现乱码。

对于环节2,浏览器展示的时候,一般都是默认使用windows简体的中文版,默认是gbk

对于环节1,idea编码的方式一般都是使用utf-8

为了统一idea浏览器的编码方式,可以改变浏览器的读取的编码规则,让浏览器按照utf-8来读取。

/*** @author 革凡成圣211*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置响应头的响应格式,以及字符集编码方式resp.setContentType("text/html; charset=utf8");resp.getWriter().write("POST"+"响应");}
}

 也就是把HTTP响应头当中的两个键值对,一个是content-type,另外一个是charset

 不过,也有更简单的方式来发送post请求,那就是使用postman。

HttpServletRequest类

       每一个HttpServletRequest代表一个HTTP请求。也就是一个HTTP请求当中包含什么内容,那么一个HttpServletRequest就封装了什么内容。

       在这一篇文章当中,我们提到了:使用Fiddler抓包的时候,提到了一个HTTP请求是由三部分组成的:【网络原理7】认识HTTP_革凡成圣211的博客-CSDN博客HTTP抓包,Fiddler的使用https://blog.csdn.net/weixin_56738054/article/details/129148515?spm=1001.2014.3001.5502

   第一部分:请求行(URL)

   第二部分:请求头(多组键值对)

   第三部分:请求的body

        那么,通过一个HttpServletRequest同样也可以获取到一个HTTP请求当中的各类信息。


       下面,介绍几个HttpServletRequest的几个常用方法:

 String getRequestURI()和String getRequestURL()

       假如我想访问的资源是:http://localhost:8080/ServletLearning_war_exploded/hello

方法名称返回含义
String getRequestURI()"/ServletLearning_war_exploded/hello"除了域名+端口号往后的内容,也就是需要访问的具体是哪一个文件
String getRequestURL()"http://localhost:8080/ServletLearning_war_exploded/hello"一个完整的请求路径

       需要注意的是,无论是URI还是URL,请求路径当中如果包含了queryString(查询字符串)

       那么都无法在上述两个方法当中返回。

       


String getQueryString() 

       这个方法,仅仅在URL地址栏当中包含queryString的时候,才会生效。

       假如我想访问呢的URL地址为:

        http://localhost:8080/ServletLearning_war_exploded/hello?key=666

       可以看到,在上述的URL当中,携带了一个queryString,那就是key=666

        所以上述方法返回的就是:

        "key=666"这一个字符串


     Enumeration getParameterNames()

      也是在请求栏当中存在queryString的时候生效。得到的所有key,都是以枚举的方式来列举的

       


      String getParameter(String name)

       根据根据queryString的key来获取到value


      String getHeader("name")

       这一个方法是获取HTTP请求头当中多组键值对中,其中以"name"为key的value。

       例如: req.getHeader("Content-Type")

       那么,这个方法就是返回Content-Type的值是什么

       

       例如在上述的方法当中,返回的内容就是:application/x-www-form-urlencoded

       


      InputStream getInputStream() 

       可以通过这个输入流对象,读取到HTTP请求的body部分的内容。


      String getContextPath()

       这一个方法返回的是一个项目的名称

       例如一个URL请求为:http://localhost:8080/ServletLearning_war_exploded/hello

       那么返回的内容就是:/ServletLearning_war_exploded


相关内容

热门资讯

运动会致辞 运动会致辞(精选5篇)  无论在学习、工作或是生活中,大家或多或少都用到过致辞吧,致辞要求风格的雅、...
六一儿童节的主持稿 六一儿童节的主持稿(精选8篇)  随着社会一步步向前发展,我们都不可避免地要接触到主持稿,主持稿是主...
元旦文艺汇演主持稿 元旦文艺汇演主持稿范文(通用5篇)  在当下社会,很多情况下我们需要用到主持稿,主持稿起到承上启下的...
颁奖主持词 颁奖主持词三篇  主持人在一场活动中是十分重要的,一个好的主持人是一直带动着活动过程中的气氛,让大家...
婚宴答谢宴简短主持词 婚宴答谢宴简短主持词  主持词要根据活动对象的不同去设置不同的主持词。在人们积极参与各种活动的今天,...
汽车公司庆典主持词 汽车公司庆典主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。现今社会在不断向前发...
古筝音乐会主持词 古筝音乐会主持词6篇  主持词要把握好吸引观众、导入主题、创设情境等环节以吸引观众。在一步步向前发展...
小学元旦联欢会主持词开场白和... 小学元旦联欢会主持词开场白和结束词  根据活动对象的不同,需要设置不同的主持词。随着社会一步步向前发...
知识竞赛主持词 知识竞赛主持词(精选6篇)  主持词的写作需要将主题贯穿于所有节目之中。在人们越来越多的参与各种活动...
小学家长会学生欢迎词 小学家长会学生欢迎词小学家长会学生欢迎词文章标题:小学家长会学生欢迎词家长会欢迎辞亲爱的叔叔阿姨,爷...
消夏晚会主持词 2017消夏晚会主持词  漫漫暑假,天气越来越燥热,不妨在炎热的午后,参加一场纳凉晚会,欣赏社区带来...
周立波脱口秀台词 周立波脱口秀台词集锦四十岁之前喝酒是为了别人的一句~~厉害!醉了!!四十岁以后喝酒是为了自己的一句~...
圣诞节活动主持词节目串词 圣诞节活动主持词节目串词3篇  根据活动对象的不同,需要设置不同的主持词。在人们积极参与各种活动的今...
生日华诞主持词 生日华诞主持词范文各位领导,各位朋友,各位来宾,女士们,先生们:  中午好。  今天是个喜庆的日子,...
学术会议主持词 学术会议主持词  什么是主持词  由主持人于节目进行过程中串联节目的串联词。如今的各种演出活动和集会...
订婚仪式及主持词 订婚仪式及主持词范文(通用3篇)  活动对象的不同,主持词的写作风格也会大不一样。在现在的社会生活中...
古剑奇谭欧阳少恭经典台词参考 古剑奇谭欧阳少恭经典台词参考  大型古装玄幻剧《古剑奇谭》正在湖南卫视热播,剧中,乔振宇饰演温文尔雅...
幼儿园晨会主持词 幼儿园晨会主持词  美好的一天从早上开始,从晨会开始,从大家的好的状态开始,从最好的开始。以下是小编...
诗文诵读展示主持词 诗文诵读展示主持词  主持词没有固定的格式,他的最大特点就是富有个性。在当今不断发展的世界,很多晚会...