(JavaEE-05)Response与Request

如何才算掌握Servlet

  • ServletConfig
  • ServletContext
  • Request
  • Response
  • Cookie
  • Session

上面这些对象(固然不止这些,剩下的对象查阅ServletAPI,不是JavaEEAPI)都是web服务器在条用Servlet时所建立的交给Servlet的对象,将这些对象的API掌握熟练,就基本上掌握Servlet技术了,剩下的就是你的Java编程功力了,基本都是设计方面的事了。html

Web服务器

web服务器接受到客户端的http请求,会针对每一次请求,分别建立一个用于表明请求的request对象和表明相应的response对象。若是须要获取客户端的相关信息,就使用request对象,须要向客户端发送数据,就使用response对象java

这里的request对象和response对象都不是标准的HTTP协议的请求和响应,而是Web服务器根据标准的HTTP协议的请求和响应,而后再根据Servlet规范(接口)实现的Web对象。web

###Servlet技术 其实Servlet技术就是一套接口,这个接口是由当年的SUN公司指定的,Tomcat是一个web服务器,也是Servlet和JSP的容器,为何它是Servlet与JSP的容器呢,缘由就是它实现了SUN规定的那一套关于Servlet和JSP的规范与接口,因此在查阅ServletAPI时你会发现,不少都是接口,这是正常的,具体的显示类是由Tomcat来完成的,咱们只管调用。HttpServletResponse与HttpServletRequest都是接口。若是你本身编写了一个服务器,并且实现了Servlet与JSP的接口与规范,那么你本身编写的这个服务器也能够是Servlet和JSP的容器(不彻底的JAVAEE容器,由于彻底的还须要实现EJB相关接口和规范)。apache

HttpServletResponse

Response对象表明响应,一个标准的HTTP响应包含三部分:状态行响应头响应数据。 经常使用方法有:编程

  • setStatus(int sc),设置响应的状态信息
  • setHeader(java.lang.String name, java.lang.String value),设置响应的头信息
  • getWriter(),返回一个PrintWriter对象,给客户端发送信息
  • getOutoutStream() ,返回一个ServletOutputStream对象,给客户端发送流信息

在学习过程当中要注意,学习什么技术就查什么文档,例如如今在学习JavaEE中的Servlet技术,那么就查阅ServletAPI,不要查阅JavaEEAPI,这样更加方便,清晰。设计模式

###ResponseAPI数组

###response常见应用浏览器

  • 向客户端输出中文数据缓存

    • OutputStream向客户端发送中文数据(默认编码与设定编码的问题,乱码的缘由:客户端使用系统默认编码),处理方法:设置响应头信息
    • 使用HTML语言里面的<meta>标签来控制浏览器行为(模拟一个http响应头),也能够解决乱码问题
    • 使用OutputStream输出数字1,应该字符化
    • 使用PrintWriter来输出,设置response的编码(response默认的编码问题),还须要告诉浏览器(客户端)以什么编码方法打开,使用response的setHeader,简写可使用setConteType
  • 文件下载和中文文件的下载tomcat

    • 获取须要下载的文件、通知浏览器如下载的方式打开、向浏览器写出数据
    • 若是下载文件的名字是中文,必须使用URL编码来进行处理
  • 输出随机图片

    • 在内存中建立一张图片
    • 获得图片
    • 设置背景颜色
    • 设置图片边框
    • 设置图片干扰线
    • 向图片上写数据
    • 把图片发送给客户端
    • 使用中文作验证
    • 设置浏览器不要缓存图片
  • 定时刷新网页

    • 使用response的消息头就可让浏览器定时刷新网页
    • 使用meta标签模拟(<meta http-equiv='refresh' content='3;url=/webapp/index.html'>
  • 请求的重定向

    • 重定向与转发的区别(一个向服务器发了两次请求,一个向服务器发了一次请求)
    • 重定向发生,地址栏的地址会变化(重定向会增长服务器压力)
    • 使用 302 状态码和 location 头来完成,也可使用response的重定向跳转方法来完成

###response的细节

  • getOutputStreamgetWriter方法分别用于获得输出二进制数据、输出文本数据的ServletOutputStream和PrintWriter对象
  • 这两个方法是互斥的,调用了其中的一个,另外一个就不能再调用
  • 在一个请求的整个调用链中,只能有一个流存在,若是须要写多种数据,使用字节流来完成
  • Servlet引擎在service结束后,会自动检测response的流是否关闭,若是没有会自动关闭,而后再销毁Servlet,可是本身使用的流须要本身手动关闭

#HttpServletRequest HttpServletRequest对象表明客户端的请求,当客户端经过HTTP协议访问服务器时,HTTP请求头中的全部信息都封装在这个对象中,经过这个对象,就能够获取客户端的相关信息。

####经常使用方法:

  • getRequestURL方法返回客户端发出请求时的完整URL,资源在互联网上的位置
  • getRequestURI方法返回请求行中的资源名部分,资源的位置
  • getQueryString 方法返回请求行中的参数部分
  • getRemoteAddr方法返回发出请求的客户机的IP地址,屏蔽IP
  • getRemoteHost方法返回发出请求的客户机的完整主机名,注册DNS的主机名称,若是没有注册,返回IP
  • getRemotePort方法返回客户机所使用的网络端口号
  • getLocalAddr方法返回WEB服务器的IP地址
  • getLocalName方法返回WEB服务器的主机名
  • getMethod获得客户机请求方式

####获取客户端请求头:

  • getHead(name)方法
  • getHeaders(String name)方法
  • getHeaderNames方法

####获取客户端请求参数:

  • getParameter(name)方法
  • getParameterValues(String name)方法
  • getParameterNames方法
  • getParameterMap方法
  • getInputStream方法

###Request常见应用

####防盗链 防止本身网站的Web资源被别的网站使用。若是你有一个Servet,能够返回一些Web资源(图片、文章等等),那么在别的网站系统中,直接使用<a>连接,或者发送一个http请求给你的Servlet应用,那么就能获取你网站的Web资源。

  • 使用Request对象的getHeader(“referer”)方法来获取 referer 信息,rederer能够告诉咱们当前这个请求是从哪一个网站点击过来的。
  • 若是没有使用网页点击,而是直接发送的http请求,那么 rederer 的值为null
  • 检测 referer 的开头是不是本站,并且不能为 null,不然就重定向到本站首页

####获取各类表单输入项的数据 若是须要向服务器发送一系列数据,可使用表单来完成。表单能够提交表单中的表单元素(表单项)的数据到服务器,浏览器会把表单中的可用元素(有name属性、disabled属性不为false的元素)的值封装起来。若是表单以get方式提交,那么这些值就会以 url 参数的形式发送给服务器,若是使用的是 post 方式提交,那么浏览器会将这些数据添加到 http 请求的消息体中(负载)发送给服务器。

常见表单元素:

  • text
  • password
  • radio,若是两个radio的name相同,就代表它们是一组,每次只会有一个被选中,默认选中使用checked = "checked"设置,使用 value 值来提交真正的数据
  • checkbox,多个值的获取,将多选按钮的名字都设置能同样的,在服务端使用 getParameterValues(name)方法来获取多个值,返回值是一个数组,使用value值来提交真正的数据
  • file
  • select,配合 option 项来提交值,select 元素来设置name,具体的值用 option来设置
  • textarea,默认值的设置不是用 value ,在标签体中来设置
  • hidden,隐藏域

对于表单提交的数据,在服务端必定要作验证才能使用,否则很容易发生异常

####请求数据的中文乱码问题 在作web开发时,常常会遇到乱码的问题,最好的解决乱码的方式就是从一开始就统一编码。

  • 若是出现乱码,首先要分析出现乱码的缘由,也就是肯定是哪个环节致使了乱码
  • 通常常见的是:request的默认编码是 IOS8859-1,而页面提交的数据(页面的编码可使用响应头和<meta>标签来设置,通常推荐UTF-8)不是这个编码。对于这种编码通常很好解决,使用 request的 setCharacterEncoding(encoding) 方法来设置 request的编码就能够了,可是这种设置仅对 post 方式提交的请求有效
  • 对于以 get 方式提交的请求,在Servlet中处理的话,只能使用手动的转码来实现,将 ISO8859-1 转成响应的编码。
  • get 方式提交的请求的乱码,还有一种方式能够解决乱码:改变 Tomcat 的配置(给链接器配置一个属性:URIEncoding="UTF-8")。
  • 若是超连接中提交的数据包含中文,必定要进行URL编码处理

关于get的乱码解决还有一种方式,就是使用 useBodyEncodingForURI="true",这种配置,这个配置的意思是:URI的编码用request实际设置的编码,这样配置后,request的 setCharacterEncoding(encoding) 对于get请求同样有效了。 对于改变服务器配置来解决乱码的方法,在实际开发中并不推荐,不要依赖服务器。

####request对象实现请求转发 使用request也能够实现请求的转发,在实际开发中,使用request作请求转发的多,通常不使用ServletContext作转发。若是在转发过程当中须要传值到转发资源,使用request的setAttribute 方法来传值,在实际开发中,是使用 request 来进行转发和传值的,不使用ServletContext。由于ServletContext都整个Web应用中的Servlet共享,容易出现覆盖的问题,而request是独立的,不存在这个问题。 request也是一个域对象,是一个容器。

请求转发主要用来实现MVC设计模式。在MVC设计模式中,都是使用Servletl来处理用户请求,而且产生用户须要查看的数据,而后转发给jsp来显示,转发给jsp显示时,会把数据存在request域里面带给jsp。

####request域

  • setAttribute 方法
  • getAttribute 方法
  • removeAttribute 方法
  • getAttributeNames 方法

####请求转发中的细节 在使用转发的时候,有些小细节要注意:

  • 若是在调用forward方法以前,在Servlet程序中写入的部份内容已经被真正传送到了客户端,forward方法将抛出参数异常。(好比使用PrintWriter发送数据给客户端,而后关闭流,而后再使用request来转发,就会抛异常)
  • 屡次请求转发也是不可取的,同样会抛参数异常
  • 关闭response的流,意味着提交响应结果到客户端,若是不关闭,就没有提交,仍是有机会作别的响应处理的,那么别的响应处理将会覆盖掉以前的响应(以前的响应被清空,可是对于响应头的设置信息,会保留下来

总结:在请求转发的先后,都不要写数据,写了也没有用!!!在Servlet中,只产生数据,可是不作输出,输出交给JSP(MVC)

####请求重定向和请求转发的区别

  • 一个web资源收到客户端请求后,通知服务器去调用另一个web资源进行处理,称之为请求转发
  • 一个web资源收到客户端请求后,通知浏览器去访问另一个web资源,称之为请求重定向
  • RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还能够重定向到同一个站点上的其余应用程序中的资源,甚至是使用绝对URL重定向到其余站点的资源
  • 若是传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;若是建立RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录
  • 调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变
  • HttpServletResponse.sendRedirect方法对浏览器的请求直接做出响应,响应的结果就是告诉浏览器去从新发出对另一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另一个资源,浏览器只知道发出了请求并获得了响应结果,并不知道在服务器程序内部发生了转发行为
  • RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程

####RequestDispatcher的include方法

  • RequestDispatcher.include方法用于将RequestDispatcher对象封装的资源内容做为当前响应内容的一部分包含进来,从而实现可编程的服务器端包含功能
  • 被包含的Servlet程序不能改变响应消息的状态码和响应头,若是它里面存在这样的语句,这些语句的执行结果将被忽略

####Web工程中地址的写法 在web开发中,常常会使用地址,如:

  • this.getServletContext().getRealPath("/")
  • request.getRequestDispatcher("/")
  • response.sendRedirect("/")
  • response.getWriter().write("<meta http-equiv='refresh' content='3;url=/'>")
  • <form aciont="/">
  • <a href="/">,<img src="">

对于这些地址,里面均可以用"/",这些有什么区别呢?总结:凡是给服务器用的地址,"/"表明当前web应用;凡是给浏览器用的地址,"/"表明网站(webapps) 还有"/"与"",前者使用在虚拟路径或者URL地址;后者使用在硬盘地址。 使用斜杠的地址,都是绝对地址,还有一些状况是须要相对地址的(后续课程)。

相关文章
相关标签/搜索