zoukankan      html  css  js  c++  java
  • JSP Servlet中的Request和Response的简单研究

      本文参考了几篇文章所得,参考目录如下:

      1.http://www.cnblogs.com/guangshan/p/4198418.html

      2.http://www.iteye.com/problems/17048

      3.http://blog.csdn.net/a859522265/article/details/7259115

      4.http://www.cnblogs.com/xiaoqv/archive/2011/12/21/2295681.html

      下面就开始进入正题。

      之前做项目一直用jsp,然后肯定是要用到request和response的,代码主要是别人给搭建好了,然后自己在里面进行一些前台显示以及后台增删改查的操作。前段时间给我身边的新人讲东西,讲到request和response这一部分,具体我也没有细研究,就只说了request是请求,response是响应。然后就有人问我,request和response在我们的项目里究竟怎么去区别的?怎么看着一直在用request而没有用response,不是说request是请求,response是响应么,为什么响应也是用的request?因为在我们的项目里,java代码获取到后台传递的值之后给前台jsp界面响应的时候是用的request.setAttribute()进行处理的。这个问题问住我了,我说我再看看,然后再说。结果现在才看。。。

      简单来说,Web服务器收到客户端的HTTP请求,会针对每一次的请求分别创建一个用于代表请求的request对象和代表响应的response对象。要得到客户端提交过来的请求数据,只需要找request对象就行了,要想向客户端发送数据,只需要找response就行了。这两者起到了服务器与客户端之间的信息传递作用。

       Request对象:为脚本提供了客户端请求一个页面或者传递一个窗体时,客户端提供的全部信息,包括指明浏览器,用户的HTTP变量,这个域名下存放在浏览器中的cookie,任何作为查询字符串而附于URL后面的字符串或者form表单中的值。

      Response对象:用来访问服务器端所创建的并发回到客户端的相应信息,为脚本提供HTTP变量,指明服务器和服务器的功能和关于发回浏览器的内容信息,以及任何将为这个域而存在浏览器里的新的cookie,还提供一系列方法创建输出。

      Request对象提供了5个集合,可以用来访问客户端对Web服务器请求的各类信息,这些集合如下:

      (1)ClientCertificate:当客户端访问一个页面或其他资源时,用来向服务器表明身份的客户证书的所有字段或条目的数值集合,每个成员均为只读。

      (2)Cookies:根据用户请求,用户系统发出的所有cookie的值得集合,这些cookie对相应域有效,成员只读。

      (3)Form:当有表单要提交且method为post时,所有作为请求提交的<form>中HTML空间单元的值得集合,每个成员只读。

      (4)QueryString:依附于用户请求的URL后的名称/数值对或者作为请求提交的且method为get的form中所有HTML空间单元的值,每个成员只读。

      (5)ServerVariables:随客户端发出的HTTP报头值,以及Web服务器的几种环境变量的值得集合。每个成员只读。

      Response对象只有一个集合

      (1)cookies:当前响应中,发回客户端的所有cookie的值,只写!

      (2)Response有几种方法需要注意,分别是

        ①Write():向客户端发送浏览器能够处理的各种数据,包括html代码,脚本程序等。

        ②Redirect():作用是在服务器端重定向与另一个网页

        ③End:用来终止脚本程序

        ④Clear():用于删除缓冲区中的所有 HTML 输出,但只删除响应正文而不删除响应标题。对应方法为Response.Buffer()

        ⑤Flush():当Buffer的值为True时,Flush用于将缓冲区中的当前页面内容立刻输出到客户端。

      

      说了这么多,那么开头的问题是怎么个解释呢?为什么服务器端返回的数据要用request.setAttribute来进行返回到客户端呢?

      首先要明确一个概念,JSP不是客户端,或者说jsp不是浏览器中的界面,如果把界面看成是鸡蛋,那么jsp是下蛋的鸡。(这是网友的比喻)。jsp和action都是服务器端的程序,所以action转发给jsp也是一种请求,那么response响应的是客户端,而jsp不是客户端,你要下发jsp时,对jsp也是一种请求,既然是请求,那么就要用request了。

      其实对我们所接触的东西来说,最主要用到的是HttpServletRequest和HttpServletResponse对象。这两者承接了HTTP请求与响应的大部分功能。下面对这两个对象的大部分常用方法以及功能在下面做了下总结,希望会有帮助。

     1 request.getAsyncContext();     AsyncContext   // 获取异步传输的文本内容
     2 request.getAttribute(String);    Object            //Attribute与Parameter不同,Attr是在程序里用SetA设置进去的,而Par是接收网页的参数,多用于session的设值,session.setA,可以设置自己的类型,getP只能接收String,而getA可以为object
     3 request.getAttributeNames();    Enumeration<String>//获取一个枚举类型,hasmoreelement,nextelement
     4 request.getAuthType();    String    //返回身份验证方法的名称,basic,SSL,form,client_cert和digest,若没有身份验证则为null
     5 request.getCharacterEncoding();    String    //返回网页使用的编码,在网页的charset中的值
     6 request.getContentType();    String    //获取content-type,包括编码。<meta content="text/html; charset=gb2312" http-equiv="Content-Type"/> Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
     7 request.getContextPath();    String    //获取项目的根目录名,
     8 request.getCookies();    Cookie[]    //返回网页的cookies,数组形式cookie是名称+值的形式保存的
     9 request.getParameter("code");    String    //获取提交参数
    10 request.getParameterMap();    Map<String,String[]>    //返回类型是String[]的原因是参数名称有可能相同,如果用getPara返回同名参数多个值的会把各个值结合起来
    11 request.getParameterNames();    Enumeration<String>    //获取参数名的枚举
    12 request.getParameterValues("code");    String[]    //获取同名参数的多个值
    13 request.getSession();    HttpSession    //获取Session对话,用于与网页通信,很有用

    以上是一些常用的方法,还有很多方法在项目中用的不多,基本用几次就够了的。其余方法会在最后附上。

    下面说一下HttpServletResponse的各种方法

    1 response.sendRedirect("xx.html");//返回一个重定向,并把新的request与response交给重定向的页面进行处理.sendRedirect方法向客户发出临时重新导向的响应。它生成的响应状态码为302。
    2 response.setCharacterEncoding("utf-8");// 设置字符编码
    3 response.addCookie(new Cookie("a","aa"));    void    //增加cookie
    4 response.flushBuffer();    void   // 立即发送缓冲区字符给客户端即浏览器
    5 response.getStatus();    int    //获取response的状态码,有200,301,404,500
    6 response.setBufferSize(123);    //设置缓冲区大小

    以上是我接触到的比较常用的方法,response用到的方法不多。

    最后附上大部分HttpServletRequest和HttpServletResponse对象的全部方法。

    1.HttpServletRequest

    /*
         * 记录各个request.get的值
         * request.getAsyncContext();AsyncContext
         * 获取异步传输的文本内容
         * request.getAttribute(String);Object
         * Attribute与Parameter不同,Attr是在程序里用SetA设置进去的,而Par是接收网页的参数
         * 多用于session的设值,session.setA,可以设置自己的类型,getP只能接收String,而getA可以为object
         * request.getAttributeNames();Enumeration<String>
         * 获取一个枚举类型,hasmoreelement,nextelement
         * request.getAuthType();String
         * 返回身份验证方法的名称,basic,SSL,form,client_cert和digest,若没有身份验证则为null
         * AuthType可在web.xml中配置,使用<login-config><auth-method>xx<real-name>xxx来配置
         * 一般用于远程网页链接,即输入网页地址,弹出一个登陆界面,那里的时候才会用
         * 读取文件头中的Authorization信息
         * request.getCharacterEncoding();String
         * 返回网页使用的编码,在网页的charset中的值
         * request.getContentLength();int
         * 只用于POST请求,表示所发送数据的字节数
         * request.getContentLengthLong();long
         * 同上,用于数据量非常大时,long八个字节
         * request.getContentType();String
         * 获取content-type,包括编码。<meta content="text/html; charset=gb2312" http-equiv="Content-Type"/>
         * Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
         * request.getContextPath();String
         * 获取项目的根目录名,如本项目应该是/MyTestWeb。返回指定servlet上下文(web应用)的URL的前缀。
         * 用绝对路径时,可以使用getRealPath()(不推荐),request.getSession().getServletContext().getRealPath("/")
         * request.getCookies();Cookie[]
         * 很明显,返回网页的cookies,数组形式cookie是名称+值的形式保存的
         * request.getDateHeader("String");long
         * 用于将指定头信息的部分转换成方便转换为时间类型的长整数型,简化getHeaders
         * request.getDispatcherType();DispatcherType
         * 未知...
         * request.getHeader("headname");String
         * 获取指定头信息
         * request.getHeaderNames();Enumeration<String>
         * 获取名字的枚举,用于遍历
         * request.getHeaders("headersname");Enumeration<String>
         * 获取一个name的多个值序列,返回请求给出的指定类型的所有HTTP头标的名称的枚举值,它对具有多取值的头标非常有用。
         * request.getInputStream();ServletInputStream继承自io.InputStream
         * 获取请求内容,可以获取post方法在网页中通过send传递的内容,但是要通过InputStreamReader实例化
         * 同时InputStreamReader也不能直接被读取为字符串,要使用BufferedReader实例化InputStreamReader
         * 之后就可以使用BufferedReader的readline来获取中间的数据了。
         * 或者直接使用InputStream的read方法写给read的参数,byte数组
         * 该方法只能读取一次,因为是流,所以读完就没了
         * request.getIntHeader("head");int
         * 从头内容获取数值
         * request.getLocalAddr();String
         * 获取本地地址,根据访问方法不同而不同,为127.0.0.1或者公网ip
         * request.getLocale();Locale(util中)
         * 获取本地位置信息,若ZHCN等等
         * request.getLocales();Enumeration<Locale>
         * 有多个位置信息时获取枚举
         * request.getLocalName();String
         * 获取本地IP的名称,如127.0.0.1就是localhost
         * request.getLocalPort();int
         * 获取端口号,本应用就是8081
         * request.getMethod();String
         * 获取Http方法,有get,head,put,delete,post,options
         * request.getParameter("code");String
         * 获取提交参数,即网址?后面的内容,一一对应关系。即便是POST,这个也只能获取?后面的参数
         * POST与GET的不同是可以send里面写内容,网址里面传递的参数还是一样的
         * request.getParameterMap();Map<String,String[]>
         * 返回类型是String[]的原因是参数名称有可能相同,如果用getPara返回同名参数多个值的会把各个值结合起来
         * PS:遍历Map的方法,Set<Entry<String, String[]>> set = map.entrySet();先获取EntrySet
         * 然后获取EntrySet的迭代器Iterator<Entry<String, String[]>> it = set.iterator();
         * 接着使用迭代的getNext来获取各个元素Entry<String, String[]> entry = it.next();
         * 最后使用Entry.getvalue获取字符串数组
         * request.getParameterNames();Enumeration<String>
         * 获取参数名的枚举
         * request.getParameterValues("code");String[]
         * 获取同名参数的多个值
         * request.getPart("file");Part
         * 用于上传文件,一个Part为一个文件,mime类型为multipart/form-data
         * 程序中需要添加@MultipartConfig注解
         * request.getParts();Collection<Part>
         * 获取一个Part的集合,用于上传多个文件
         * request.getPathInfo();String
         * 返回在URL中指定的任意附加路径信息。不带参数,一般是相对于Servlet的路径
         * pathinfo返回的字符串是经过Servlet服务器URL Decode过的。
         * 输出:URL中Servlet路径之后、查询字符串之前的那部分。
         * request.getPathTranslated();String
         * 映射到服务器实际路径之后的路径信息。
         * request.getProtocol();String
         * 获取协议信息和版本号,即HTTP/1.1
         * request.getQueryString();String
         * 这是字符串形式的附加到URL后面的查询字符串,数据仍旧是URL编码的。
         * 在Servlet中很少需要用到未经解码的数据,一般使用getParameter访问各个参数。
         * request.getReader();BufferedReader
         * 获取BufferedReader,和inputStream那一大堆获取的内容一样。。。
         * request.getRealPath("/");String
         * 获取绝对路径,被废弃了,请使用request.getSession().getServletContext().getRealPath("/")
         * request.getRemoteAddr();String
         * 客户端的IP
         * request.getRemoteHost();String
         * 客户端的主机名
         * request.getRemotePort();int
         * 客户端的端口号
         * request.getRemoteUser();String
         * 客户端的用户名
         * request.getRequestDispatcher("");RequestDispatcher
         * 请求转发,获取请求过来的地址,与该地址共享一个Request
         * request.getRequestedSessionId();String
         * 返回这个请求相应的session id
         * request.getRequestURI();String
         * 获得请求URL,不包含请求内容,不包含域名
         * request.getRequestURL();StringBuffer
         * 获取URL,包含域名,不包含请求内容
         * 未被Servlet服务器URL Decode过。
         * request.getScheme();String
         * 返回协议名称,http
         * request.getServerName();String
         * 获得服务器名,本地IP
         * request.getServerPort();int
         * 获取服务器端口号
         * request.getServletContext();ServletContext
         * 获取该Servlet的相关信息,getServletConfig().getServletContext().getServerInfo()
         * request.getServletPath();String
         * URL中调用Servlet的那一部分,不包含附加路径信息和查询字符串。
         * request.getSession();HttpSession
         * 获取Session对话,用于与网页通信,很有用
         * equest.getSession(boolean);HttpSession
         * request.getSession(true):若存在会话则返回该会话,否则新建一个会话。
         * request.getSession(false):若存在会话则返回该会话,否则返回NULL
         * request.getUserPrincipal();Principal
         * 返回一个java.security.Principal  对象,该对象包含当前授权用户的名称
         * 使用request.getUserPrincipal().getName()得到用户名
         * 没有通过认证就没有返回值,是用户登录后才有值的,通过了JAAS认证,也就是登录
         *
         * request.authenticate(HttpServletResponse response);boolean
         * 证明是真实的、可靠的或有效的;鉴定,使生效
         * request.changeSessionId();String
         * Change the session id of the current session associated with this request and return the new session id.
         * request.isAsyncStarted();boolean
         * 异步传输是否开始
         * request.isAsyncSupported();boolean
         * 是否支持异步传输
         * isRequestedSessionIdFromCookie();boolean
         * SessionId是否是从cookies中获得的
         * request.isRequestedSessionIdFromUrl();boolean
         * SessionId是否是从URL中获取的,已废弃
         * request.isRequestedSessionIdFromURL();boolean
         * 同上,这个没废弃
         * request.isRequestedSessionIdValid();boolean
         * 检查SessionId是否是有效的
         * request.isSecure();boolean
         * 是否是安全的,即是否使用了安全协议,如https
         * request.isUserInRole("role");boolean
         * 判断用户是否是某个种类的角色,类型可以在web.xml中配置(tomcat-users.xml)
         * request.login("user", "password");void
         * 使用用户名和密码进行登录
         * request.logout();void
         * 用户登出
         * request.notify();request.notifyAll();void
         * 用于线程操作,详细见教材
         * request.removeAttribute("at");void
         * 删除某个属性值,对应set
         * request.setAttribute("at", request);void
         * 设置某个属性值
         * request.setCharacterEncoding("utf-8");void
         * 设置获取各个字符时使用的编码方式,应与网页的编码方式一样
         * 仅仅只适用于设置post提交的request body的编码而不是设置get方法提交的queryString的编码。
         * 该方法告诉应用服务器应该采用什么编码解析post传过来的内容。
         * request.startAsync(request, response);void
         * 开始异步传输,可以不带参数
         * request.upgrade();void
         * 开始更新?
         * request.wait(12);
         * 实现了线程的类都有该方法,用于等待
         */

    2.HttpServletResponse

    /*
         * response对象
         * response.addCookie(new Cookie("a","aa"));void
         * 增加cookie
         * response.addDateHeader("date", 23456789l);void
         * 在头部增加日期
         * response.addHeader("asf", "sff");void
         * 增加头部信息
         * response.addIntHeader("fsf", 12);void
         * 在头部增加数值类型
         * response.encodeRedirectUrl("utf-8");废弃
         * response.encodeRedirectURL("utf-8");String
         * 通过指定的编码对URL进项编码,并携带sessionid,跨应用
         * response.encodeUrl("utf-8");废弃
         * response.encodeURL("utf-8");String
         * 通过指定的编码对URL进项编码,并携带sessionid,本应用
         * 假如有sessionId,且不是从cookie中获得的,就放到url尾部,否则直接返回原url。
         * response.flushBuffer();vodi
         * 立即发送缓冲区字符给客户端即浏览器
         * response.getBufferSize();int
         * 获取缓冲区大小
         * response.getCharacterEncoding();String
         * 获取编码类型
         * response.getContentType();String
         * 获取Content的MIME类型和编码
         * response.getHeaderNames();Collection<String>
         * 获取所有Header的name列表
         * response.getHeaders("aa");Collection<String>
         * 获取所有aa的头的值列表
         * response.getLocale();Locale
         * 获取本地信息,如zhcn
         * response.getOutputStream();ServletOutputStream继承自OutputStream
         * 获取输出流,和inputStream对应,bufferedReader和printWriter对应
         * response.getStatus();int
         * 获取response的状态码,有200,301,404,500
         * response.getWriter();PrintWriter
         * 获取一个PrintWriter,用于向response返回数据,从而向客户端返回数据,比Stream使用方便
         * response.isCommitted();boolean
         * 调用PrintWriter对象的close()方法关闭底层输出流,方法在关闭输出流之前会先把缓冲区内的数据提交到客户端。
         * 因此在调用PrintWriter 对象的 close()方法之前,response.isCommitted()方法返回 false;
         * 而在调用PrintWriter对象的close()方法之后,response.isCommitted()方法返回true。
         * response.reset();void
         * 清除buffer,设置页面不缓存,同时清除状态码和头,如果已经发送数据则跑出异常
         * response.resetBuffer();void
         * 只清除buffer
         * response.sendError(1,"123");void
         * response.sendError(123);
         * response.sendError(1,"123");
         * setStatus方法用来设置Servlet向客户端返回的状态码,它用来设置没有出错的状态。
         * 如果Servlet运行出错,Servlet可以使用sendError方法设置状态码,
         * 如sendError(int sc)方法设置错误状态代码。sendError(int sc,String msg)方法除了设置状态码
         * 还向客户发出一条错误信息。
         * response.sendRedirect("xx.html");
         * 返回一个重定向,并把新的request与response交给重定向的页面进行处理
         * sendRedirect方法向客户发出临时重新导向的响应。它生成的响应状态码为302。
         * 该响应给了客户一个新的URL分区。如果缓冲器已经被清空,这个方法会弹出一个IllegalStateException例外。
         * response.setBufferSize(123);
         * 设置缓冲区大小
         * response.setCharacterEncoding("utf-8");
         * 设置字符编码
         * response.setContentLength(123);
         * 设置返回内容的长度,在header中也有
         * response.setContentLengthLong(1345l);
         * 长度非常长是使用
         * response.setContentType("dfd");
         * 设置ContentType,包括编码和类型信息
         * 网页的Http头中ContentType("text/html; charset=GBK")的作用:
         * 告诉浏览器网页中数据是什么编码
         * 表单提交时,通常浏览器会根据ContentType指定的charset对表单中的数据编码,然后发送给服务器的。
         * 这里需要注意的是:这里所说的ContentType是指http头的ContentType,而不是在网页中meta中的ContentType。
         * response.setDateHeader("asd", 123l);
         * 修改日期头
         * response.setHeader("sfds", "sdfsdf");
         * 修改头
         * response.setIntHeader("sf", 3123);
         * 设置数值头
         * response.setLocale(locale );
         * 设置本地环境
         * response.setStatus(1);
         * 设置Http状态码,为出错的情况用
         * response.setStatus(12, "dasd");
         * 设置状态码并带一条消息
         * 
         * 
         * 
         */

    综上,request和response是两个最常用的对象,还是要好好学习,好好使用。

  • 相关阅读:
    vue项目index.html缓存
    vue刷新当前页面
    keep-alive
    JS刷算法题:二叉树
    CSS动效集锦,视觉魔法的碰撞与融合(三)
    算法:栈和队列题目集合(一)
    浅谈设计模式(二):装饰器模式|中介模式|原型模式
    聊聊JS的二进制家族:Blob、ArrayBuffer和Buffer
    浅谈设计模式(一):状态模式|外观模式|代理模式
    纵论WebAssembly,JS在性能逆境下召唤强援
  • 原文地址:https://www.cnblogs.com/Pillar/p/4212939.html
Copyright © 2011-2022 走看看