一、ServletRequest接口

  HttpServletRequest接口继承了ServletRequest接口,实现类通常代表一个实际的Http Request。

  Servlet容器负责创建一个HttpServletRequest对象(在Web服务器接收到浏览器的一个请求后),然后Servlet容器把这个HttpServletRequest传递给相关Servlet的service方法。(其实同时创建和传递的还有HttpServletResponse对象,这也是我们在编写相关Servlet时,无须关注request是如何被接收,也无须关注response最终如何被返回,这些都是Servlet容器和Web服务器的职责)

  ServletRequest接口,定义了一个能代表实际request的对象,它包含了这个request的各项信息。

  一个ServletRequest对象提供的数据包括了parameter name and value,attributes,以及input stream。HttpServletRequest对象还能提供额外的http协议相关的信息(他是唯一的子接口)。

  当然接口只是定义了行为规范,Java为其提供了两个基础的实现,以供开发人员扩展:

  HttpServletRequestWrapper, ServletRequestWrapper。

  二、Request中的parameter 和 attributes

  2.1 首先来个大体的区分

  Request parameter是客户端提交过来的参数,以“name=value”的字符串形式存储在Request对象中,所以对于parameter,只有getParameter方法。

  例如,我们登录时提交账户信息,假如是GET方法提交(实际上不会用GET提交),那么在提交的信息会以"?username=root&password=123456"这种形式附加在表单指向的url后面,这种形式称之为Query String。而POST方式则会把信息放在Request Body当中,这种形式称之为POST Body。

  StackOverFlow

  一个有意思的点是,Query string data is presented(显示) BEFORE post body data.

  例如,如果使用Query String提交“a=hello”和POST Body提交“a=goodbye“和”a=world”,则结果参数集将被排序为a=(hello, goodbye, world)。

  更新:发现我以前讲得不够清楚。可以参考下列网址:

  How are parameters sent in an HTTP POST request?

  HTTP中application/x-www-form-urlencoded字符说明

  四种常见的 POST 提交数据方式

  在将post表单数据填充到参数集(parameter set)之前,必须满足以下条件:

  • The request is an HTTP or HTTPS request.
  • The HTTP method is POST.
  • The content type is application/x-www-form-urlencoded.
  • The servlet has made an initial call of any of the 'getParameter' family of methods on the request object.

  如果不满足条件,且post表单数据不包含在参数集中,post数据仍然可以通过request object的输入流提供给servlet。

  如果满足这些条件,post表单数据将不再可以直接从请求对象的输入流中读取。

   Request attributes则与客户端无关,服务器端接收后产生的一个Request对象,可能在各个不同的Servlet间传递而进行必要的处理,这时我们可以在Servlet A中通过setAttribute(String name,Object)方法存储一些信息,然后在Servlet B中通过getAttribute(String name)方法,取出相关的Object对象,进行一些处理。

  API中提到了一点,Attributes are reset between requests,我有点疑惑为什么要特意提这样一句,直观上来说,在不同的Request对象上存储东西,二者当然不会共享吧?所以对Attributes的存储机制开始好奇了。

  An attribute is a server variable that exists within a specified scope i.e.:

  • application, available for the life of the entire application
  • session, available for the life of the session
  • request, only available for the life of the request
  • page (JSP only), available for the current JSP page only

  可以确定的一点是,当代码中出现了setAttribute()方法时,那么这个Request对象必定会与一个RequestDispatcher对象一起工作了,因为你在此处添加了一些有用的数据,肯定要在别处取出来用吧?

  2.2 RequestDispatcher接口

  先总结,RequestDispatcher接口类用于request的转发。

  RequestDispatcher也是一个接口,它定义一个这样的对象:接收来自客户端的request,然后把他们送到服务器的其他资源上去(如servlet,html文件,JSP文件)。所以,通常是Servlet容器创建RequestDispatcher对象,用于包装一个有特定路径或者名称的服务器端资源。

  这个接口用于包装servlet,但是servlet容器可以创建RequestDispatcher对象来包装任何类型的资源。

  在JDK中,这个接口没有任何子接口和实现类。但是在ServletContext接口(Defines a set of methods that a servlet uses to communicate with its servlet container)中有几个get方法来获得RequestDispatcher对象。

  RequestDispatcher接口,也仅有两个方法:

  void forward(ServletRequest request, ServletResponse response),把一个request从一个Servlet中转发到服务端的另一处资源(servlet, JSP file, or HTML file)。

  该方法允许一个servlet对请求进行初步处理,并允许另一个资源生成响应。

  对于通过getRequestDispatcher()获得的RequestDispatcher, ServletRequest对象调整了其路径元素和参数,以匹配目标资源的路径。

  forward()方法,应该在将response提交给客户机之前(在response body output被刷新之前)调用。如果response已经被提交了,调用forward()会抛出IllegalStateException。 response缓冲区中未提交的输出,在forward()调用前,会自动被清除。(Uncommitted output in the response buffer is automatically cleared before the forward.)

  传递给forward的两个对象,要和servlet中service方法中获得的对象是相同的。即针对的是同一次请求过程。

  void include(ServletRequest request, ServletResponse response),这个方法用于向response中添加一些资源(servlet, JSP page, HTML file)。

  这里就涉及到ServletResponse对象了,它代表着一个要被返回的Response。ServletResponse对象也由Servlet容器创建,(在这样的一个转发过程中)它的路径元素和参数与调用者的保持不变(The ServletResponse object has its path elements and parameters remain unchanged from the caller's. )而且进行include操作的servlet,无法改变response的状态码,也无法设置header信息,这样的操作会被无视掉。(why?)

  这里 include方法的ServletRequest request和ServletResponse response必须与传递给调用该include方法的servlet的service方法的两个ServletRequest request和ServletResponse response是同一对(反正一般也不会自己创建了),或者是包装前面这两个对象的ServletRequestWrapper或ServletResponseWrapper类的子类。

  三、ServletResponse接口

  3.1

  HttpServletResponse接口的父接口,定义一个对象来帮助servlet向客户端发送response。

  Servlet容器会创建一个 ServletResponse对象,然后与ServletRequest一起传递给servlet的service方法。

  如果要在MIME body response中发送二进制数据,请使用getOutputStream()返回的ServletOutputStream。(什么是MIME)

  要发送字符数据,使用getWriter()返回的PrintWriter对象。

  要混合二进制和文本数据,例如,创建一个multipart响应,请使用ServletOutputStream并手动管理字符部分。

  MIME主体响应的字符集可以使用以下任何一种技术显式指定:

 per request, per web-app (using ServletContext.setRequestCharacterEncoding(java.lang.String), deployment descriptor(即web.xml)), and per container (for all web applications deployed in that container, using vendor specific configuration(更改web容器的配置)).

  如果使用了前面提到的多种技术,那么优先级就是所列的顺序。

  对于每个请求,可以使用本接口中的setCharacterEncoding(java.lang.String)和setContentType(java.lang.String)方法显式地指定响应的字符集,或者隐式地使用setLocale(java.util.Locale)方法 。

  显式规范优先于隐式规范。如果没有明确指定字符集,将使用ISO-8859-1。

  setCharacterEncoding、setContentType或setLocale方法的调用必须在getWriter之前,并在提交要使用的字符编码的响应之前

  3.2 方法

  ServletResponse接口定义的方法并不复杂,都和设置response的相关的格式有关,其中的一些会设置reponse header。

  四、再谈谈ServletContext接口

  前面已经提到过了,ServletContext中定义了一系列方法让servlet与servlet容器打交道,例如获取文件的MIME类型、分派request或写入日志文件。

  每个Java虚拟机中的每个“web应用程序”,都有一个上下文(context)。

  而一个“Web Application”的定义:

  A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace, such as /catalog and possibly installed via a .war file.)

  对于在部署描述符中标记为“distributed”的web应用程序,每个虚拟机都有一个上下文实例。在这种情况下,上下文不能用作共享全局信息的位置(因为信息不是真正的全局的)。使用外部资源,比如数据库。

  ServletContext对象包含在ServletConfig对象中,这个对象用于Web服务器在初始化servlet时提供给servlet。API链接

  ServletContext提供的方法,与我们在web.xml中常进行的一些配置相似。如添加Filter、Listener、Servlet等。

  

Java HttpServletRequest中getAttribute()方法和getParameter()区别的更多相关文章

  1. 原生js中slice()方法和splice()区别

    slice()方法和splice()方法都是原生js中对数组操作的方法. slice(),返回一个新的数组,该方法可从已有的数组中返回选定的元素.例如:arrObject(start,end),sta ...

  2. Java基础之equals方法和"= ="的区别

    ==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符. 如果一个变量指向的数据是对象类型的 ...

  3. 线程中sleep方法和wait方法有什么区别?(转)

    本文转自https://www.cnblogs.com/linkstar/p/6043846.html 线程中sleep方法和wait方法有什么区别?   如果你没有接触过java的多线程,那么多对于 ...

  4. Classloader中loadClass()方法和Class.forName()区别

    Classloader中loadClass()方法和Class.forName()都能得到一个class对象,那这两者得到的class对象有什么区别呢 1.java类装载的过程 Java类装载有三个步 ...

  5. ThinkPHP 中M方法和D方法的具体区别(转)

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  6. ThinkPHP 中M方法和D方法的具体区别

    M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...

  7. Java提高篇——equals()方法和“==”运算符

    equals() 超类Object中有这个equals()方法,该方法主要用于比较两个对象是否相等.该方法的源码如下: public boolean equals(Object obj) { retu ...

  8. ThinkPHP 中M方法和D方法详解----转载

    转载的地址,http://blog.163.com/litianyichuanqi@126/blog/static/115979441201223043452383/ 自己学到这里的时候,不能清除的分 ...

  9. Java基础系列-equals方法和hashCode方法

    原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述         equals方法和hashCode方法都是有Object类定义的. publi ...

随机推荐

  1. Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作

    v-viewer 用于图片浏览的Vue组件,支持旋转.缩放.翻转等操作,基于viewer.js. 从0.x迁移 你需要做的唯一改动就是手动引入样式文件: 1 import 'viewerjs/dist ...

  2. websocket原理、为何能实现持久连接?

    WebSocket 是 HTML5 一种新的协议.它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是 ...

  3. opencv_traincascade级联训练人脸数据

    正负样本格式:  正样本 灰度化 24*24 2000张  负样本 灰度化 50*50 1000张 训练过程  第一步:dir /b >pos.txt 以及dir /b >neg.txt ...

  4. C++ STL Heap算法

    #include <iostream>#include <algorithm>#include <vector> using namespace std; int ...

  5. 5G 与 MEC 边缘计算

    目录 文章目录 目录 前言 参考文献 通信网络 核心网演进之路 早古时期 2G 网络架构 3G 网络架构 4G 网络架构 5G 5G 网络的需求 5G 网络架构的设计原则 5G 网络的逻辑架构 5G ...

  6. PAT 甲级 1021 Deepest Root (25 分)(bfs求树高,又可能存在part数part>2的情况)

    1021 Deepest Root (25 分)   A graph which is connected and acyclic can be considered a tree. The heig ...

  7. 免费申请https

    https://blog.csdn.net/MariaOzawa/article/details/81877756 实测有效

  8. 【计算机视觉】MTCNN的windows-cpu配置

    前言 MTCNN是级联卷积网络,原理基本上比较清晰,只是还缺少实战,看到一个CSDN上windows的实现过程,就拿来试试. 操作过程 参考here,某些步骤会添加博主遇到的问题的解释. 第一部分:c ...

  9. flask的jinja2过滤器使用:遍历索引指定标签class属性,实现样式变化

    在flask项目中实现上图效果,采用使用自定义过滤器的形式对 span 标签的 class 指定. 1.定义过滤器 # common.py def do_index_class(index): &qu ...

  10. 通用 spring cloud 微服务模板

    说明文档 功能 1. 基于映射数据库一键生成 spring cloud 微服务 2. 通用 Controller ,无需编写代码即可完成基于数据库的服务 3. 动态多条件 CRUD + 分页 使用说明 ...