Java 中的 HttpServletRequest 和 HttpServletResponse 对象

HttpServletRequest对象详解

  javax.servlet.http.HttpServletRequestSUN制定的Servlet规范,是一个接口。表示请求HTTP请求协议”的完整内容都被封装到request对象中,HttpServletRequest接口的父接口是javax.servlet.ServletRequest

  Apache软件基金会开发的“Tomcat容器”对javax.servlet.http.HttpServletRequest接口的实现类完整类名是org.apache.catalina.connector.RequestFacade,但是我们javaweb程序员不需要关心具体的请求对象类型,不需要关心是哪个容器,我们只需要面向HttpServletRequest接口调用方法即可。

  一次请求对应一个请求对象,请求开始,请求对象被创建,请求结束,请求对象被回收,下一次请求的时候是一个新的请求对象。如何理解一次请求:浏览器向服务器发送请求到服务器响应结束为一次请求。

  HttpServletRequest接口中常用的方法

  通过用户提交的参数name获取参数value最常用的方法)

  String value = request.getParameter(String name);

  HttpServletRequest对象中存储数据(绑定)

  request.setAttribute(String name,Object obj);

  从HttpServletRequest对象中获取数据(读取数据)

  Object obj = request.getAttribute(String name);

  移除HttpServletRequest对象中的数据

  request.removeAttribute(String name);

  使用request对象完成转发(转发是一次请求,一次请求跨越多个Servlet 

  request.getRequestDispatcher(“资源路径”).forward(request,response);

  获取客户端的IP地址

  String clientIP = request.getRemoteAddr();

  获取URI

  String uri = request.getRequestURI();

  获取URL

  StringBuffer url = request.getRequestURL();

  获取Servlet Path

  String servletPath = request.getServletPath();

  获取应用程序的根路径,获取应用上下文路径

  String contextPath = request.getContextPath();

  解决请求体中的乱码问题(在从request对象中获取任何数据之前设置有效)

  request.setCharacterEncoding(“UTF-8”);

  在服务器端获取用户发送的请求中的所有Cookie

  Cookie[] cookies = request.getCookies();

  获取会话对象session

  HttpSession sessoin = request.getSessoin();  获取session对象,如果获取不到则开启新session

  HttpSession sessoin = request.getSession(true);   获取session对象,如果获取不到则开启新session

  HttpSession sessoin = request.getSession(false);  获取session对象,如果获取不到则返回null

  HttpServletRequest对象是一个请求级别的对象,一次请求一个对象,所以request对象只能完整在同一次请求中进行数据的传递,可以跨越多个Servlet进行数据的传递,但是必须使用转发机制。如果request对象和ServletContext对象都可以完成此功能,我们优先选择request范围。request不能完成跨用户传递数据。只能完成在一次请求中传递数据。

HttpServletResponse对象详解

  javax.servlet.ServletResponse是接口,是SUN制定的响应对象,专门完成向浏览器的响应动作。

  javax.servlet.http.HttpServletResponse父接口是ServletResponse

  获取响应流:PrintWriter out = response.getWriter();

  关于PrintWriter中的方法:

    1、println方法:输出到浏览器的HTML源码换行

    2、print方法:输出到浏览器的HTML源码不换行,如果想在网页中做到换行效果,需要使用HTML识别的 <br>标签。

    3、向特定的浏览器客户端发送Cookie:response.addCookie(cookie);

  重定向:response.sendRedirect(/webcontextPath/servletPath);

关于转发和重定向

转发与重定向的区别(资源跳转),如下图所示

 

代码上的实现:

转发

request.getRequestDispatcher("/servletPath").forward(request,response); 

重定向

response.sendRedirect("/webcontextPath/servletPath");

注意资源路径:在转发中不需要编写web应用的根路径名称。但是在重定向的时候需要编写web应用的根路径名称,假设web应用的根路径名称是StudyServlet,该web应用的根下有a资源,如果是转发则路径写 /a,如果是重定向则 /StudyServlet/a

  RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的资源(这个资源可能是Servlet、JSP、HTML等),而HttpServletResponse.sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到另一个WEB应用中的资源

  调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。

  HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个绰号叫“浏览器”的人写信找张三借钱,张三回信说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。于是,“浏览器”又按张三提供通信地址给李四写信借钱,李四收到信后就把钱汇给了“浏览器”。可见,“浏览器”一共发出了两封信和收到了两次回复, “浏览器”也知道他借到的钱出自李四之手。RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。这个过程好比绰号叫“浏览器”的人写信找张三借钱,张三没有钱,于是张三找李四借了一些钱,甚至还可以加上自己的一些钱,然后再将这些钱汇给了“浏览器”。可见,“浏览器”只发 出了一封信和收到了一次回复,他只知道从张三那里借到了钱,并不知道有一部分钱出自李四之手。       

  RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。对于同一个WEB应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,并要使用HttpServletRequest.setAttribute方法传递预处理结果,那就应该使用RequestDispatcher.forward方法。不同WEB应用程序之间的重定向,特别是要重定向到另外一个WEB站点上的资源的情况,都应该使用HttpServletResponse.sendRedirect方法。      

  无论是转发还是重定向,转发和重定向后面不能再有转发和重定向相关的代码。(转发和重定向在同一个Servlet中只能有一次。

怎么选择是重定向还是转发呢?

通常情况下转发更快,而且能保持request内的对象,所以它是第一选择。但是由于在转发之后,浏览器中URL仍然指向开始页面,此时如果重载当前页面,开始页面将会被重新调用。如果你不想看到这样的情况,则选择重定向(页面刷新问题)。     

重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。  

转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。

1、 如果是web应用之间资源的跳转,必须使用重定向。

2、 为了解决页面的刷新问题,必须使用重定向。

3、 如果在Servlet中向request对象中存储了一个数据,希望在下一个Servlet/JSP页面中把request对象中的数据取出来,这个时候必须使用转发,因为重定向是两次请求,request不能跨请求传递数据。其它情况都可以使用重定向。

 

posted @ 2017-05-06 19:57  一线大码  Views(2676)  Comments(0Edit  收藏  举报