HttpServletRequest简介

Web服务器收到客户端的http请求,会针对每一次请求,创建一个用于代表请求的HttpServletRequest类型的request对象,并将"HTTP请求协议"的完整内容封装到该对象中。开发者获拿到request对象后就可以获取客户端发送给服务器的请求数据了。

HttpServletRequest的生命周期

当客户端浏览器向服务器发送请求后,服务器会根据HTTP请求协议的格式对请求进行解析。同时,服务器会创建 HttpServletRequest类型的对象,即请求对象,然后将解析出的数据封装到该请求对象中。此时HttpServletRequest实例就创建并初始化完毕了,也就是说,请求对象是由服务器创建。当服务器向客户端发送响应结束后,HttpServletRequest 实例对象被服务器销毁,HttpServletRequest对象的生命周期很短暂。
一次请求对应一个请求对象, 另外一次请求对应另外一个请求对象,即每次请求都会创建一个HttpServletRequest类型的对象,这些对象之间没有关系。

HttpServletRequest中常用的方法

  • Map<string,string[]> getParameterMap()
    获取包含所有请求参数及值的 Map 对象。需要注意,该 Map 的 value 为 String[],即一个参数所对应的值为一个数组。说明一个参数可以对应多个值。
  • Enumeration getParameterNames()
    获取请求参数 Map 的所有 key,即获取所有请求参数名。
  • String[] getParameterValues(String name)
    根据指定的请求参数名称,获取其对应的所有值。这个方法一般用于获取复选框(checkbox)数据。
  • String getParameter(String name)
    根据指定的请求参数名称,获取其对应的值。若该参数名称对应的是多个值,则该方法获取到的是第一个值。这个方法是最常用的方法。

获取客户端信息的方法:

    • getRequestURL方法返回客户端发出请求时的完整URL。
    • getRequestURI方法返回请求行中的资源名部分。
    • getQueryString 方法返回请求行中的参数部分。
    • getRemoteAddr方法返回发出请求的客户机的IP地址
    • getRemoteHost方法返回发出请求的客户机的完整主机名
    • getRemotePort方法返回客户机所使用的网络端口号
    • getLocalAddr方法返回WEB服务器的IP地址。
    • getLocalName方法返回WEB服务器的主机名
    • getMethod得到客户机请求方式
       /**
      * HttpServletRequest获取请求数据
      */
      public class RequestTest01 extends HttpServlet {
      private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      //根据html中的name的名字获取用户在input中填写的值
      String username = request.getParameter("username");
      String password = request.getParameter("password");
      //获取用户勾选的checkbox的值
      String[] hobby = request.getParameterValues("hobby"); System.out.println(username);
      System.out.println(password);
      for(String s:hobby){
      System.out.println(s);
      }
      } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      doGet(request, response);
      } }

      乱码的产生原因

      当用户通过浏览器提交一个包含 UTF-8 编码格式的两个中文请求时,浏览器会将这两个中文字符变为六个字节(一般一个 UTF-8 汉字占用三个字节),即形成六个类似%8E 的字节表示形式,并将这六个字节上传至 Tomcat 服务器。
      Tomcat 服务器在接收到这六个字节后,并不知道它们原始采用的是什么字符编码。而Tomcat 默认的编码格式为 ISO-8859-1。所以会将这六个字节按照 ISO-8859-1 的格式进行解码,解码后在控制台显示,所以在控制台会显示乱码。

      乱码的解决方案

      针对 POST 提交乱码的解决方式
      在接收请求参数之前先通过 request 的 setCharacterEncoding()方法,指定请求体的字符编码格式。这样的话,在接收到请求中的参数后,就可按照指定的字符编码进行解码。
      注意,request 的 setCharacterEncoding()方法只能解决 POST 提交方式中的乱码问题,对
      于 GET 提交方式的不起作用。因为该方法设置的是请求体中的字符编码, GET 提交中的参数不出现在请求体中,而出现在请求行。

    •      //设置post请求的字符编码
      request.setCharacterEncoding("utf-8"); //根据html中的name的名字获取用户在input中填写的值
      String username = request.getParameter("username");
      String password = request.getParameter("password");
      //获取用户勾选的checkbox的值
      String[] hobby = request.getParameterValues("hobby"); System.out.println(username);
      System.out.println(password);
      for(String s:hobby){
      System.out.println(s);
      }

      针对get提交乱码的解决方式
      可以通过修改 Tomcat 默认字符编码的方式来解决 GET 提交方式中携带中文的乱码问题。在 Tomcat 安装目录的 conf/server.xml 中,找到端口号为 8080 的标签,在其中添加 URIEncoding=”UTF-8″的设置,即可将 Tomcat 默认字符编码修改为 UTF-8。

       <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>

      需要注意的是在修改时要找到正确的server.xml文件。
      双击tomcat服务器,如下图:

      上图中有三个选项,不同的选项表示使用的不同路径下的tomcat

      1. 表示使用eclipse工作空间的tomcat,该路径在工作空间目录中的.metadata.plugins\org.eclipse.wst.server.core\tmp0目录中,如果你使用的是这个(eclipse会默认使用这个),需要修改该目录中的server.xml才会生效。
      2. 表示使用我单独下载的tomcat所在的路径,我本机的是在:F:\monkey1024\apache-tomcat-9.0.0.M26中,如果你使用的是这个,需要修改该目录中的server.xml文件。
      3. 表示自定义一个位置,即手动指定web应用运行的目录位置,如果你使用的是这个,需要修改该目录中的server.xml文件。

      万能解决方案

       //根据html中的name的名字获取用户在input中填写的值
      String username = request.getParameter("username");
      //将数据按照ISO8859-1编码后放到字节数组中
      byte[] bytes = username.getBytes("ISO8859-1");
      //将字节数组按照UTF-8解码为字符串
      username = new String(bytes,"UTF-8");

      先以 ISO8859-1 的形式先对单字节的数据进行编码,并将编码后的数据存放在字节数组中。然

      后,再将字节数组中的数据,按照指定的 UTF-8 格式进行解码,即变为了需要的 UTF-8 字符
      编码的数据,解决了中文乱码问题。
      通过上面的代码就可以解决get和post的乱码问题,但是代码量较大,开发中使用较少。

HttpServletResponse简介

Web服务器收到客户端的http请求,会针对每一次请求,创建一个用于代表响应的HttpServletResponse类型的response对象,开发者可以将要向客户端返回的数据封装到response对象中。

HttpServletResponse向客户端发送数据

ServletResponse 接口有一个方法 getWriter(),用于获取到一个输出流对象 PrintWriter,
该输出流对象是专门用于向客户端浏览器中输出字符数据的,称为标准输出流。

package com.monkey1024.servlet;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 使用HttpServletResponse向客户端发送数据
*
*/
public class ResponseTest01 extends HttpServlet {
private static final long serialVersionUID = 1L;
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置post请求的字符编码,此方式只对post请求有效
request.setCharacterEncoding("UTF-8");
//根据html中的name的名字获取用户在input中填写的value值
String username = request.getParameter("username"); //从response中取得PrintWriter对象
PrintWriter out = response.getWriter();
//向客户端发送数据
out.print("用户:" + username + "添加成功!<br>");
out.print("感谢您的注册");
//关闭PrintWriter
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }

HttpServletResponse响应乱码的解决方案

响应时会产生乱码的原因是在 HTTP 协议中规定,默认响应体的字符编码为ISO-8859-1。所以,若要解决乱码问题,就需要修改响应体的默认编码。一般情况下,有两种方式可以修改:

  • 方法一:HttpServletResponse 的 setCharacterEncoding(“utf-8”)方法,将编码修改为utf-8,然后再通过setHead(“Content-type”,”text/html;charset=UTF-8″);方法告诉客户端浏览器的编码方式。
    代码:

       response.setCharacterEncoding("UTF-8");
    response.setHead("Content-type","text/html;charset=UTF-8");
  • 方法二:为了简便操作,开发者可以直接使用HttpServletResponse 的 setContentType(“text/html;charset=utf-8”)方法,告诉浏览器的编码方式,该方法相当于方法一种的两条代码。
    代码:
     response. setContentType("text/html;charset=UTF-8");

注意:设置响应编码时必须在 PrintWriter 对象产生之前先设置,否则将不起作用。

转发:

 /**
* 转发
*/
public class Forward01 extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符编码
request.setCharacterEncoding("UTF-8");
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password"); request.setAttribute("username", username);
request.setAttribute("password", password); //转发
request.getRequestDispatcher("Other").forward(request, response);
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }

重定向:

 /**
* 重定向
*/
public class Redirect01 extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置字符编码
request.setCharacterEncoding("UTF-8");
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password"); request.setAttribute("username", username);
request.setAttribute("password", password); //重定向到上面的Other servlet中
response.sendRedirect("Other");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }

当点击之后注意浏览器地址栏中的url是会发生变化的,url后面请求的路径变为了Other。

如果想要重定向到另外一个项目的servlet上时,只需要在sendRedirect加上项目的访问名:

 response.sendRedirect("/other-app/Other");

其中other-app是另外项目的访问名。

转发和重定向的区别

  • 请求转发
    1. 浏览器只发出一次请求,收到一次响应
    2. 请求所转发到的servlet2中可以直接获取到请求中所携带的数据
    3. 浏览器地址栏显示的为用户所提交的请求路径
    4. 只能跳转到当前应用的资源中
  • 重定向
    1. 浏览器发出两次请求,接收到两次响应
    2. 重定向到的servlet2不能直接获取到用户提交请求中所携带的数据
    3. 浏览器地址栏显示的为重定向的请求路径,而非用户提交请求的路径。也正因为如此,重定向的一个很重要作用是:防止表单重复提交
    4. 重定向不仅可以跳转到当前应用的其它资源,也可以跳转到到其它应用中资源

请求转发与重定向的选择

  • 若需要跳转到其它应用,则使用重定向。
  • 若是处理表单数据的Servlet1要跳转到另外的Servlet2上,则需要选择重定向。为了防止表单重复提交。
  • 若对某一请求进行处理的 Servlet 的执行需要消耗大量的服务器资源(CPU、内存),此时这个 Servlet 执行完毕后,也需要重定向。
  • 其它情况,一般使用请求转发。

最新文章

  1. 关于Oracle AUTONOMOUS TRANSACTION(自治事务)的介绍
  2. Springboot数据库连接池报错的解决办法
  3. 【原】ios打包ipa的四种实用方法(.app转.ipa)
  4. Creating Icon Overlay Handlers / 创建图标标记 Handlers (翻译自MSDN) / VC++, Windows, DLL, ATL, COM
  5. How to easily create popup menu for DevExpress treelist z
  6. EXTJS 资料 Ext.Ajax.request 获取返回数据
  7. Android开发之onClick事件的实现
  8. How To Cluster Rabbit-MQ--reference
  9. NOI2014题解
  10. SQL Server索引进阶:第五级,包含列
  11. Matlab - 线性方程组求解
  12. GIT团队开发操作
  13. bootstrap 获得轮播中的索引或当前活动的焦点对象
  14. javascript bom 编程
  15. 类模板语法知识体系梳理(包含大量常犯错误demo,尤其滥用友元函数的错误)
  16. jQuery mouse and lunbo
  17. HTTP 404 Not Found Error with .woff or .woff2 Font Files
  18. Django-website 程序案例系列-17 forms表单验证的字段解释
  19. rc.d/rc.local 自动启 tomcat 启不来
  20. markdown的流程图实现和代码语法着色

热门文章

  1. Web开发(XAMPP服务器搭建)
  2. 2018-2019-2 20165336《网络对抗技术》Exp0 Kali安装 Week1
  3. Vue项目在开发环境跨域和生成环境部署跨域问题解决
  4. 关于Java项目打包成Runnable jar文件后运行时图片不显示的问题
  5. HBase JavaAPI
  6. C和C++字符串处理整理
  7. 【Solution】MySQL 5.8 this is incompatible with sql_mode=only_full_group_by
  8. 从零开始一起学习SLAM | 掌握g2o边的代码套路
  9. Excle中的使用小技巧
  10. 安装linux虚拟机