分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

HttpServletRequest对象

发布时间:2023-09-06 01:08责任编辑:蔡小小关键词:暂无标签


HttpServletRequest对象

  我们都知道浏览器通过http协议与Tomcat(web服务器)通信时,会生成两个对象,一个是HttpServletRequest对象,一个是HttpServletResponse对象。它们是一对数据封装对象,前者封装客户端的请求头,后者封装服务器的响应头。而在这里要介绍的是HttpServletRequest对象,HttpServletRequest实际上是个接口,是Java所定制的接口,这个接口是由开发web服务器的人员去做实现的。

可以看一下HttpServletRequest的源码:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEA44604474DCC44D9A19A5A9B996753EB/4477" alt="4477" />



我们可以看看Tomcat中实现这个接口的两个类:

Request类:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEB46947C6F685405BA14429F6F8CAF6A2/4478" alt="4478" />



RequestFacade类:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE9C2061B0722A4A0E99FCFBD0A781F774/4479" alt="4479" />



  可以看到以上这两个类都各自实现了HttpServletRequest接口,但实际上这个两个类是有关联的,具体的代码实现其实是由Request类完成的,而RequestFacade类只是作为一个转发的存在。而且从类的名称上也可以看得出来,Facade是外观、正面的意思,所以这是一个外观类,而在这个RequestFacade类后面的真正实现类是Request。可以想象成RequestFacade是Request的前端、门面,Request则是RequestFacade的后台、后端。

看一下RequestFacade的构造器和部分代码就知道了:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE463DB7416B784064913FC3D8B496F80B/4480" alt="4480" />



再来看看RequestFacade的部分代码:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE0C10B52DA850424DB37A08A2F30BBFA0/4481" alt="4481" />



而且这个类的代码行数也不到一千行:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE111866BF8D8E48B69C2D803EFBD5611A/4482" alt="4482" />



下面再来看看Request类的代码:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEEC0F6981EE024CD7900661BE16BFD564/4483" alt="4483" />

可以看到getContextPath这个方法是在Request类上实现的,并且因为实现代码在这个类里,所以代码行数比RequestFacade类多:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE6015433D73794B6CB48385CBF1BEBAC2/4484" alt="4484" />



示意图:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE1E58E68E9B2D4A2BAC67851714757EF9/4485" alt="4485" />


  从上图可以看到HttpServletRequest接口和Request、RequestFacade实现类之间构成了一个模式,这个设计模式就是外观模式。外观模式为子系统中的一组接口提供了一个一致的界面,这个界面就是RequestFacade,并且定义了一个高层接口这个接口就是HttpServletRequest,这个接口使得这一子系统更加容易使用。

外观模式好处在于隐藏了系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口(HttpServletRequest)。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性,这个模式实现了子系统与客户端之间的松耦合关系。所以我们都是通过HttpServletRequest接口对象去调用方法的,而实现类和界面类都隐藏在背后,而且这两个类也不是Java实现的,而是开发web服务器的人员实现的(Java的尿性一贯如此)。


关于对象池:

  HttpServletRequest和HttpServletResponse对象是存放在一个对象池中的,这是一个活动的能够自动增长的对象池,就和自动增长的线程池一样,每当对象不够用的时候就会新增加对象。这个对象池可以优化服务器资源,因为这两个对象可以反复的利用,不会造成资源的浪费。如果没有这个对象池的话,每次用户访问就会新建一次对象的话,这么做十分耗费资源,而且速度还慢。所以从这一点可以知道,这个对象池就是起到了一个优化资源的作用(好像池子都是这么回事)。

我们可以打印这个两个对象的hash值查看一下就知道了(需要不断的刷新访问页面):

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEF711EEEF790F4C16BD78C9A5AAB03ECD/4486" alt="4486" />


运行结果:

650) this.width=650;" style="width:444px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEFD4F19DC47EE46D09304B8F21A349F74/4488" alt="4488" />

  从图中可以看到有几个hash值重复了好几次,所以从这一点就可以得知它使用了对象池机制。


  好了,以上简单介绍完HttpServletRequest中接口与实现类的一些关系和使用到了什么设计模式与对象池机制,接下来介绍一下HttpServletRequest中较为常用的一些方法:

获得服务器相关信息方法:

方法名称

作用

getInputStream()

获得本次通信的Input流对象

getServerName()

获得服务器的名称

getServerPort()

获得服务器的端口

getContextPath()

获得web工程的路径

getLocale()

获得区域所使用的语言


代码示例:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE8391C8E81C194265B8BD141867B76719/4489" alt="4489" />


运行结果:

650) this.width=650;" style="width:454px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEF54F6FCEA1E84729A96539E61B8F67B2/4490" alt="4490" />




获得请求头信息方法(请求头中的信息是键/值对形式的):

方法名称

作用

getHeader(String)

参数为键,获得该键的值

getHeaderNames()

返回所有的键

getHeaders(String)

参数为键,获得拆分的值

getContentLength()

获得网页文件的长度,没有的话就会返回-1

getContentType()

获得网页文件的类型

getMethod()

获得请求的方法

getQueryString()

获得请求的参数,但是要注意:只有get类型的请求方式才有效果

getRequestURI()

获得访问的目标Servlet所在工程下的那一部分内容

getRequestURL()

获得整个URL


代码示例:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE78C18AC1B1944E22B7574103F7C41417/4491" alt="4491" />


运行结果:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE50FD09F04D5D4D959C743E4450C27AF8/4492" alt="4492" />




获得客户端的IP和端口方法:

方法名称

作用

getRemoteAddr()

获得客户端IP地址

getRemoteHost()

获得客户端IP地址

getRemotePort()

获得客户端端口


代码示例:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE3912678BFC25486881525A04CAFC155D/4493" alt="4493" />


运行结果:

650) this.width=650;" style="width:420px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEC0E2B3D8DD6F4769949627708E970566/4494" alt="4494" />





获得和设置表单数据方法(如果是上传文件的话则无法获取文件中的数据):

方法名称

作用

setCharacterEncoding(String)

设置表单提交上来的文本编码

getParameter(String)

得到表单中某一个指定的name属性的值

getParameterMap()

获得所有的键值对

getParameterNames()

获得所有的name属性的值:

getParameterValues(String)

获得重复的name属性的值


Html代码示例:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE9D7775914F894F95BBE5A305FFC39E64/4495" alt="4495" />


Java代码示例:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE145C22796B6242098375D44991907C20/4496" alt="4496" />

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE9C51E6637F6B4F498E7B7F6A81237D4A/4497" alt="4497" />


浏览器表单:

650) this.width=650;" style="width:372px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEBC004FDED965457DBB63183531875D0E/4498" alt="4498" />


控制台结果:

650) this.width=650;" style="width:553px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE7A221849D6544DC88FCAE0BC59792980/4499" alt="4499" />





获得和设置表单属性相关方法:

方法名称

作用

getAttribute(String)

获得属性对象

getAttributeNames()

获得所有的属性名称

removeAttribute(String)

删除参数中字符串描述的属性

setAttribute(String, Object)

设置属性和属性的值,这是键/值对形式的

注意:以上这几个方法只是在web容器内部流转,仅在具有转发关系的Web组件之间共享,也就说只在这个范围内有效,所以不能直接把值获得到代码中打印,以下使用实际示例演示一下就知道无法直接获得值了:


代码示例:

650) this.width=650;" style="width:552px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEF9AAB23F26D043C3B5A1395C432C85E2/4500" alt="4500" />


浏览器:

650) this.width=650;" style="width:372px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICEA29BA9F8A1BC4BB0AB3A977F0FE1E212/4501" alt="4501" />


控制台结果:

650) this.width=650;" style="width:350px;" src="http://note.youdao.com/yws/public/resource/4a8bcb2fef8038ec896a931c563e5474/xmlnote/OFFICE1ADC949E80AD45AFBB7C13411FDAA828/4502" alt="4502" />

























本文出自 “zero” 博客,请务必保留此出处http://zero01.blog.51cto.com/12831981/1979476

HttpServletRequest对象

原文地址:http://zero01.blog.51cto.com/12831981/1979476

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved