【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


相关内容

热门资讯

初中作文读后感【实用6篇】 初中作文读后感 篇一《红楼梦》读后感《红楼梦》是中国古代文学的巅峰之作,也是我读过的一本非常经典的小...
刻痕(精简3篇) 刻痕 篇一刻痕刻痕是指物体表面因外力作用而产生的破坏性痕迹。刻痕不仅会影响物体的外观美观度,还可能降...
春天作文(推荐6篇) 春天作文 篇一春天的美丽春天是一年四季中最美丽的季节之一。当冬天的严寒逐渐消退,春天的阳光温暖而明媚...
吃牙膏初一作文(实用6篇) 吃牙膏初一作文 篇一吃牙膏的危害牙膏是我们日常生活中必不可少的物品之一,它具有保护牙齿健康的作用。然...
我身边的胡胖作文800字(优... 我身边的胡胖作文800字 篇一胡胖是我的好朋友,他是一个胖胖的男孩,大家都亲切地叫他“胖胖”。胖胖的...
第一次吃自助餐初中作文(优选... 第一次吃自助餐初中作文 篇一第一次吃自助餐今天,我第一次去吃自助餐。这是我以前从未尝试过的新鲜事物,...
乐在元宵夜初中作文(精选6篇... 乐在元宵夜初中作文 篇一元宵节是我国传统的节日之一,也是中国农历正月十五的晚上。这一天,人们会举行各...
傣族泼水节作文(推荐6篇) 傣族泼水节作文 篇一傣族泼水节是中国云南省傣族人民传统的节日,也是中国国家级非物质文化遗产。每年农历...
以包汤圆为主题的优秀作文【优... 以包汤圆为主题的优秀作文 篇一包汤圆的乐趣包汤圆是中国传统的民间活动之一。每年农历正月十五的元宵节,...
校园生活二三事作文【最新6篇... 校园生活二三事作文 篇一我的校园生活充满了欢笑和感动。在这个充满活力的地方,我度过了许多难忘的时光。...
初一学生作文【精彩6篇】 初一学生作文 篇一:我的暑假计划初一学生作文 篇二:我的理想职业初一学生作文 篇三   我们平常看书...
自信作文【通用6篇】 自信作文 篇一自信是一种积极向上的心态,是人们在面对困难和挑战时保持坚定信念和积极态度的能力。自信是...
初中作文:爸爸,我想对您说【... 初中作文:爸爸,我想对您说 篇一亲爱的爸爸:您好!我想借此机会写一封信给您,表达我对您的感激之情和对...
初中生家长的寄语(优选5篇) 初中生家长的寄语 篇一亲爱的家长们:首先,我要向大家表示衷心的感谢,感谢你们一直以来对孩子的关心和支...
并列式议论文(实用5篇) 并列式议论文 篇一应该提高法定退休年龄随着现代医疗和生活水平的提高,人们的寿命也在不断延长。这使得许...
寂寞的天空初中作文【经典5篇... 寂寞的天空初中作文 篇一寂寞的天空天空,是一片广袤无垠的蓝色宇宙,是我们向往的自由之地。然而,有时候...
初中英语作文:美味的臭豆腐(... 初中英语作文:美味的臭豆腐 篇一Stinky Tofu: A Delicious DelicacyS...
亲情作文【优质6篇】 亲情作文 篇一:珍贵的亲情亲情,是我们生命中最珍贵的财富。无论是父母的爱护、兄弟姐妹的关怀,还是亲人...
成长路上的X初一作文20篇 成长路上的X初一作文 第一篇在一生当中,“人”没有完美的,只有尽量去做到完美!但如果怕去犯错或是做错...
雨的作文(精彩6篇) 雨的作文 篇一雨是大自然的一种神奇的馈赠,它给予了我们生活的滋润和希望。每当雨水纷纷扬扬地落在大地上...