JavaWeb Request和Response

Posted Mr.Aaron

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb Request和Response相关的知识,希望对你有一定的参考价值。

1. RequestResponse

1.1. Web应用运行机制

到目前为止,我们已经掌握了Web应用程序的运行机制,现在学习的就是Web应用程序运行机制中很重要的内容 —— RequestResponse

首先,我们先来看一看RequestResponseWeb应用程序运行时,是怎么样的。

 

通过上图的Web应用程序运行机制,我们可以知道关于RequestResponse的信息:

  • Web应用程序接收一次请求,就创建一个Request对象和Response对象。
  • 通过Request对象可以在服务器端获取客户端发送的请求数据内容。
  • 通过Response对象可以生成服务器端向客户端响应的数据内容。
  • Request对象和Response对象并不是Web应用程序所创建的,而是由Tomcat服务器创建(JavaEE并没有RequestResponse的实现类)。
  • JavaEE提供了javax.servlet.http包中提供了HttpServletRequestHttpServletResponse接口,这两个接口是继承于javax.servlet包中的ServletRequestServletResponse接口。
  • javax.servlet包中的ServletRequestServletResponse接口是与协议无关的,而javax.servlet.http包中的HttpServletRequestHttpServletResponse接口是与Http协议有关的。

1.2. 百度百科

  • Request

Request这个对象不用事先声明,就可以在JSP网页中使用,在编译为Servlet之后,它会转换为javax.servlet.http.HttpServletRequest形态的对象,HttpServletRequest对象是有关于客户端所发出的请求的对象,只要是有关于客户端请求的信息,都可以藉由它来取得,例如请求标头、请求方法、请求参数、客户端IP,客户端浏览器等等信息。

  • Response

Response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应。Response对象只提供了一个数据集合cookie,它用于在客户端写入cookie值。若指定的cookie不存在,则创建它。若存在,则将自动进行更新。结果返回给客户端浏览器。

2. 掌握Response

2.1. Response概述

ResponseWeb应用程序用来封装向客户端响应信息的,是Servlet接口的service()方法的一个参数,类型为javax.servlet.http.HttpServletResponse。客户端每次发送请求时,服务器都会创建一个Response对象,并传递给Servlet接口的service()方法,来完成向客户端的响应工作。

下列是javax.servlet.http.HttpServletResponse常用的API列表:

Method Summary

 void

addDateHeader(String name, long date) 
          Adds a response header with the given name and date-value.

 void

addHeader(String name, String value) 
          Adds a response header with the given name and value.

 void

sendRedirect(String location) 
          Sends a temporary redirect response to the client using the specified redirect location URL.

 void

setDateHeader(String name, long date) 
          Sets a response header with the given name and date-value.

 void

setHeader(String name, String value) 
          Sets a response header with the given name and value.

 void

setStatus(int sc) 
          Sets the status code for this response.

下列是javax.servlet.ServletResponse常用的API列表:

Method Summary

 ServletOutputStream

getOutputStream() 
          Returns a ServletOutputStream suitable for writing binary data in the response.

 PrintWriter

getWriter() 
          Returns a PrintWriter object that can send character text to the client.

 void

setCharacterEncoding(String charset) 
          Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8.

 void

setContentType(String type) 
          Sets the content type of the response being sent to the client, if the response has not been committed yet.

针对HttpServletResponseServletResponse常用的API,我们进行逐一讨论。

2.2. Response重定向

在学习Http响应协议时,我们曾做过重定向案例,但那时我们并不清楚其原理,下面我们就讨论一下利用HttpServletResponse来完成重定向的功能。

  • 创建一个Servlet来完成重定向功能。
public class ResponseServlet1 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setStatus(302);
        response.setHeader("Location", "/response/index.html");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
  • Web工程的web.xml文件中注册Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>ResponseServlet1</servlet-name>
    <servlet-class>app.java.response.ResponseServlet1</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ResponseServlet1</servlet-name>
    <url-pattern>/response1</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • 创建一个HTML页面。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>index.html</title>
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <h1>Request与Response内容</h1>
  </body>
</html>
  • Web工程发布到Tomcat服务器,并启动Tomcat服务器。
  • 打开浏览器,在地址栏中输入http://localhost:8080/response/response1。

通过上述案例,我们可以发现在重定向中,实际上客户端向服务器端发送了两次请求,具体步骤如下:

  • 在浏览器地址输入URL,访问服务器端的Servlet,这是第一次发送的请求。
  • 服务器端接收到客户端的请求后,由Servlet做出处理,重定向到index.html页面,并响应给客户端浏览器。
  • 客户端浏览器接收到服务器端的响应后,再次发送第二次请求。
  • 服务器端接收到客户端的第二次请求后,并响应index.html给客户端浏览器显示。

其实Response对象提供了sendRedirect(String location)方法,同样可以完成重定向的工作。

public class ResponseServlet1 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.sendRedirect("/09_request&response/response/index.html");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
} 

2.3. 登录错误案例

利用Response对象提供了sendRedirect(String location)方法可以完成重定向的功能,实现登录功能中如果错误的案例。具体实现步骤如下:

  • 创建一个用于登录的HTML页面。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>login.html</title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <h1>登录案例:登录错误重定向回当前页面</h1>
    <form id="form1" action="/response/response2" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        <input type="submit" value="登录">
    </form>
  </body>
</html>
  • 创建一个Servlet用于处理登录是否成功逻辑。
public class ResponseServlet2 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取客户端浏览器提交的用户名与密码内容
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //模拟查询数据库:admin/admin
        if(username.equals("admin")&&password.equals("admin")){
            // 登录成功
            response.setContentType("text/html;charset=utf-8");
            PrintWriter out = response.getWriter();
            out.println("<h1>登录成功</h1>");
        }else{
            // 登录错误
    response.sendRedirect("/response/response/login.html");
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
} 
  • Web工程的web.xml文件中注册Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>ResponseServlet2</servlet-name>
    <servlet-class>app.java.response.ResponseServlet2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ResponseServlet2</servlet-name>
    <url-pattern>/response2</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • Web工程发布到Tomcat服务器,并启动Tomcat服务器。
  • 打开浏览器,在地址栏中输入http://localhost:8080/response/response/login.html

2.4. 自动刷新案例

在学习Http响应协议时,我们曾做过自动刷新案例,但那时我们并不清楚其原理,下面我们就讨论一下利用HttpServletResponse来完成自动刷新的功能。

  • 创建一个Servlet用于设置5秒钟后自动刷新页面的功能(自动跳转到登录页面)。
public class ResponseServlet3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("refresh", "5;url=/response/response/login.html");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("当前页面会在5秒钟后自动跳转到登录页面.");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
} 
  • Web工程的web.xml文件中注册Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>ResponseServlet3</servlet-name>
    <servlet-class>app.java.response.ResponseServlet3</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ResponseServlet3</servlet-name>
    <url-pattern>/response3</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • Web工程发布到Tomcat服务器,并启动Tomcat服务器。
  • 打开浏览器,在地址栏中输入http://localhost:8080/response/response3

在学习HTML技术的时候,我们知道在head标签中有meta标签,该标签同样可以完成自动刷新页面的功能。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>refresh.html</title>
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="refresh" content="5;url=/response/response/login.html">
  </head>
  <body>
    <h1>当前页面会在5秒钟后自动跳转到登录页面.</h1>
  </body>
</html>

使用Response对象的setHeader()方法与HTML页面的<meta>标签,同样可以完成页面自动刷新功能,但是两者是有区别的:

  • 使用Response对象的setHeader()方法:refresh信息是显示在响应头信息中。
  • 使用HTML页面的<meta>标签:refresh信息是显示在响应体信息中。

在上述基础上,完成动态效果的倒计时功能,需要使用javascript技术来完成。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>refresh.html</title>
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta http-equiv="refresh" content="5;url=/response/response/login.html">
  </head>
  <script type="text/javascript">
      var times = 5;
      function init(){
        document.getElementById("times").innerHTML = times;
        times--;
        setTimeout("init()",1000);
    }
  </script>
  <body onload="init();">
    <h1>当前页面会在<span id="times"></span>秒钟后自动跳转到登录页面</h1>
  </body>
</html>

2.5. 禁止浏览器缓存案例

在学习Http响应协议时,我们知道响应协议中有三个头信息可以禁止浏览器本地缓存,分别是Cache-Control、Pragma和Expires。下面我们就通过一个案例来讨论一下。

  • 创建一个Servlet用来向客户端浏览器响应一些数据内容。
public class ResponseServlet4 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("当前时间是:"+new Date().toString());
        System.out.println("已经成功地访问了当前Servlet...");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
} 
  • Web工程的web.xml文件中注册Servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <servlet-name>ResponseServlet4</servlet-name>
    <servlet-class>app.java.response.ResponseServlet4</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ResponseServlet4</servlet-name>
    <url-pattern>/response4</url-pattern>
  </servlet-mapping>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  • 打开浏览器,选择“工具”->Internet选项”->“浏览历史记录”中的“设置”->“查看文件”,清空所有缓存内容。
  • 在浏览器在地址栏中输入http://localhost:8080/response/response4进行访问。
  • 这时再查看浏览器缓存内容的文件夹,会发现产生了这次访问的缓存内容。
  • 这时再查看控制台信息,会发现打印了相关内容,说明客户端成功访问了服务器端的Servlet
  • 这时再次访问http://localhost:8080/response/response4地址,会发现内容不再变化,也不会产生请求和响应内容。

由于IE浏览器的本地缓存问题,第二次再次访问相同Servlet拦截路径时,不会再访问服务器端的Servlet,而是访问本地缓存内容。要想每次客户端访问都访问到服务器端的Servlet的话,我们需要禁止浏览器缓存机制。

  • 我们可以通过响应头信息中的三个相关内容来设置禁止浏览器缓存。
public class ResponseServlet4 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //设置响应头信息,禁止浏览器缓存.
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", -1);
        PrintWriter out = response.getWriter();
        out.println("<h1>已经成功地访问了当前Servlet...</h1>");
     }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
} 
  • 重新发布Web工程到Tomcar服务器,并重启Tomcat服务器。
  • 打开浏览器,清空本地缓存内容,在地址栏中输入相同URL地址。
  • 但是,现在查看浏览器本地缓存文件夹,会发现没有任何缓存内容。
  • 这时再次访问http://localhost:8080/response/response4地址。
  • 而且控制台也会打印相关信息,说明第二次也成功地访问服务器端的Servlet

2.6. 生成响应体内容

到目前为止,操作的都是Response对象的响应头信息。而Http协议的响应协议中,除了响应头信息之外,还有响应体,如何利用Response对象向客户端发送响应体呢?可以利用Response对象的getWriter()方法或getOutputStream()方法获取响应输出流,通过响应输出流向客户端进行响应。具体操作步骤如下:

  • 创建一个Servlet用于向客户端响应内容。
public class ResponseServlet5 extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("<HTML>"javaweb入门-----request与response的作用

[JavaWeb-HTTP]request对象和response对象的原理

javaWeb的Response和Request基础

JavaWeb学习笔记四 request&response

javaweb中重定向和请求转发(response.sendRedirect()和request.getRequestDispatcher(rul).forward(request,response)

Java实战之04JavaWeb-02Request和Response