|
|
51CTO旗下网站
|
|
移动端

原来HTTP协议这么简单!一文读懂HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

作者:程序猿小龙来源:今日头条|2019-05-14 10:50

 一、HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

二、jsp页面引入js,css文件的方式

在eclipse中新建一个web项目,目录结构如下:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

在jsp页面的最开始,获取项目的根路径:

  1. <% 
  2.  String path = request.getContextPath(); 
  3.  String basePath = request.getScheme() + "://" 
  4.  + request.getServerName() + ":" + request.getServerPort() 
  5.  + path + "/"
  6. %> 

在中,插入下述代码:

  1. <base href="<%=basePath%>" /> 

这句代码的作用是将整个页面的根路径设置为项目路径。

三、Request常用方法

1、获得客户机信息

getRequestURL()返回客户端发出请求时的完整URL。getRequestURI()返回请求行中的资源名部分。getQueryString ()返回请求行中的参数部分。getRemoteAddr()返回发出请求的客户机的IP地址。getPathInfo()返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以"/"开头。getRemoteHost()返回发出请求的客户机的完整主机名。getRemotePort()返回客户机所使用的网络端口号。getLocalAddr()返回WEB服务器的IP地址。getLocalName()返回WEB服务器的主机名。

  1. private void RequestMessages(HttpServletRequest req, HttpServletResponse resp) throws IOException{ 
  2.  String reqUrl = req.getRequestURL().toString();//得到请求的URL地址 
  3.  String reqUri = req.getRequestURI();//得到请求的资源 
  4.  String queryString = req.getQueryString();//得到请求的URL地址中附带的参数 
  5.  String remoteAddr = req.getRemoteAddr();//得到来访者的IP地址 
  6.  String remoteHost = req.getRemoteHost(); 
  7.  int remotePort = req.getRemotePort(); 
  8.  String remoteUser = req.getRemoteUser(); 
  9.  String method = req.getMethod();//得到请求URL地址时使用的方法 
  10.  String pathInfo = req.getPathInfo(); 
  11.  String localAddr = req.getLocalAddr();//获取WEB服务器的IP地址 
  12.  String localName = req.getLocalName();//获取WEB服务器的主机名 
  13.  resp.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器 
  14.  //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码 
  15.  resp.setHeader("content-type""text/html;charset=UTF-8"); 
  16.  PrintWriter out = resp.getWriter(); 
  17.  out.write("获取到的客户机信息如下:"); 
  18.  out.write("<br/>"); 
  19.  out.write("请求的URL地址:"+reqUrl); 
  20.  out.write("<br/>"); 
  21.  out.write("请求的资源:"+reqUri); 
  22.  out.write("<br/>"); 
  23.  out.write("请求的URL地址中附带的参数:"+queryString); 
  24.  out.write("<br/>"); 
  25.  out.write("来访者的IP地址:"+remoteAddr); 
  26.  out.write("<br/>"); 
  27.  out.write("来访者的主机名:"+remoteHost); 
  28.  out.write("<br/>"); 
  29.  out.write("使用的端口号:"+remotePort); 
  30.  out.write("<br/>"); 
  31.  out.write("remoteUser:"+remoteUser); 
  32.  out.write("<br/>"); 
  33.  out.write("请求使用的方法:"+method); 
  34.  out.write("<br/>"); 
  35.  out.write("pathInfo:"+pathInfo); 
  36.  out.write("<br/>"); 
  37.  out.write("localAddr:"+localAddr); 
  38.  out.write("<br/>"); 
  39.  out.write("localName:"+localName); 

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

2、获得客户机请求头

  • getHeader(string name)方法:String
  • getHeaders(String name)方法:Enumeration
  • getHeaderNames()方法
    1. private void RequestHead(HttpServletRequest req, HttpServletResponse resp) throws IOException{ 
    2.  resp.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器 
    3.  //通过设置响应头控制浏览器以UTF-8的编码显示数据 
    4.  resp.setHeader("content-type""text/html;charset=UTF-8"); 
    5.  PrintWriter out = resp.getWriter(); 
    6.  Enumeration<String> reqHeadInfos = req.getHeaderNames();//获取所有的请求头 
    7.  out.write("获取到的客户端所有的请求头信息如下:"); 
    8.  out.write("<br/>"); 
    9.  while (reqHeadInfos.hasMoreElements()) { 
    10.  String headName = (String) reqHeadInfos.nextElement(); 
    11.  String headValue = req.getHeader(headName);//根据请求头的名字获取对应的请求头的值 
    12.  out.write(headName+":"+headValue); 
    13.  out.write("<br/>"); 
    14.  } 
    15.  out.write("<br/>"); 
    16.  out.write("获取到的客户端Accept-Encoding请求头的值:"); 
    17.  out.write("<br/>"); 
    18.  String value = req.getHeader("Accept-Encoding");//获取Accept-Encoding请求头对应的值 
    19.  out.write(value); 
    20.  Enumeration<String> e = req.getHeaders("Accept-Encoding"); 
    21.  while (e.hasMoreElements()) { 
    22.  String string = (String) e.nextElement(); 
    23.  System.out.println(string); 
    24.  } 

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

3、获得客户机请求参数

getParameter(String name)根据name获取请求参数(常用)getParameterValues(String name)根据name获取请求参数列表(常用)getParameterMap()返回的是一个Map类型的值,该返回值记录着前端(如jsp页面)所提交请求中的请求参数和请求参数值的映射关系。(编写框架时常用)

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.  pageEncoding="UTF-8"%> 
  3. <% 
  4.  String path = request.getContextPath(); 
  5.  String basePath = request.getScheme() + "://" 
  6.  + request.getServerName() + ":" + request.getServerPort() 
  7.  + path + "/"
  8. %> 
  9. <html> 
  10. <head> 
  11. <base href="<%=basePath%>" /> 
  12. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"
  13. <title>表单提交</title> 
  14. <link href="css/bootstrap.css" rel="stylesheet"
  15. <script src="js/jquery-3.2.1.js"></script> 
  16. <script src="js/bootstrap.js"></script> 
  17. </head> 
  18. <body> 
  19.  <form class="form-horizontal" action="<%=request.getContextPath()%>/GetParameterRequest.html" role="form" method="post"
  20.  <div class="form-group"
  21.  <label for="firstname" class="col-sm-1 control-label">名字</label> 
  22.  <div class="col-sm-3"
  23.  <input type="text" class="form-control" name="name" 
  24.  placeholder="请输入名字"
  25.  </div> 
  26.  </div> 
  27.  <div class="form-group"
  28.  <label for="lastname" class="col-sm-1 control-label">年龄</label> 
  29.  <div class="col-sm-3"
  30.  <input type="text" class="form-control" name="age" 
  31.  placeholder="请输年龄"
  32.  </div> 
  33.  </div> 
  34.  <div class="form-group"
  35.  <label for="lastname" class="col-sm-1 control-label">性别</label> 
  36.  <div class="col-sm-3"
  37.  <input type="radio" name="sex" value="男" checked>男 
  38.  <input type="radio" name="sex" value="女">女 
  39.  </div> 
  40.  </div> 
  41.  <div class="form-group"
  42.  <label for="lastname" class="col-sm-1 control-label">爱好</label> 
  43.  <div class="col-sm-3"
  44.  <input type="checkbox" name="aihao" value="唱歌">唱歌 
  45.  <input type="checkbox" name="aihao" value="上网">上网 
  46.  <input type="checkbox" name="aihao" value="游戏">游戏 
  47.  <input type="checkbox" name="aihao" value="看书">看书 
  48.  </div> 
  49.  </div> 
  50.  <div class="form-group"
  51.  <div class="col-sm-offset-1 col-sm-3"
  52.  <button type="submit" class="btn btn-default">提交</button> 
  53.  <button type="reset" class="btn btn-default">重置</button> 
  54.  </div> 
  55.  </div> 
  56.  </form> 
  57. </body> 
  58. </html> 

使用getParameter方法和getParameterValues方法接收表单参数:

  1. public class GetParameterRequest extends HttpServlet{ 
  2.  private static final long serialVersionUID = 3903946972744326948L; 
  3.  @Override 
  4.  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  5.  this.doPost(req, resp); 
  6.  } 
  7.  @Override 
  8.  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.  //客户端是以UTF-8编码提交表单数据的,所以需要设置服务器端以UTF-8的编码进行接收,否则对于中文数据就会产生乱码 
  10.  req.setCharacterEncoding("UTF-8"); 
  11.  //获取名字 
  12.  String name = req.getParameter("name"); 
  13.  //获取年龄 
  14.  String age = req.getParameter("age"); 
  15.  //获取性别 
  16.  String sex = req.getParameter("sex"); 
  17.  //获取爱好,因为可以选中多个值,所以获取到的值是一个字符串数组,因此需要使用getParameterValues方法来获取 
  18.  String[] aihaos = req.getParameterValues("aihao"); 
  19.  String aihao = ""
  20.  if(aihaos != null){ 
  21.  for (int i = 0; i < aihaos.length; i++) { 
  22.  if(i == aihaos.length - 1){ 
  23.  aihao += aihaos[i]; 
  24.  } else { 
  25.  aihao += aihaos[i] + ","
  26.  } 
  27.  } 
  28.  } 
  29.  System.out.println("名字:" + name); 
  30.  System.out.println("年龄:" + age); 
  31.  System.out.println("性别:" + sex); 
  32.  System.out.println("爱好:" + aihao); 
  33.  req.setAttribute("aihao", aihao); 
  34.  //设置服务器端以UTF-8编码输出数据到客户端 
  35.  resp.setCharacterEncoding("UTF-8"); 
  36.  this.getServletContext().getRequestDispatcher("/request.jsp").forward(req, resp); 
  37.  } 

响应页面:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.  pageEncoding="UTF-8"%> 
  3. <% 
  4.  String path = request.getContextPath(); 
  5.  String basePath = request.getScheme() + "://" 
  6.  + request.getServerName() + ":" + request.getServerPort() 
  7.  + path + "/"
  8. %> 
  9. <html> 
  10. <head> 
  11. <base href="<%=basePath%>" /> 
  12. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"
  13. <title>表单提交</title> 
  14. <link href="css/bootstrap.css" rel="stylesheet"
  15. <script src="js/jquery-3.2.1.js"></script> 
  16. <script src="js/bootstrap.js"></script> 
  17. </head> 
  18. <body> 
  19. <table class="table"
  20.  <thead> 
  21.  <tr> 
  22.  <th>名称</th> 
  23.  <th>结果</th> 
  24.  </tr> 
  25.  </thead> 
  26.  <tbody> 
  27.  <tr> 
  28.  <td>姓名</td> 
  29.  <td><%=request.getParameter("name") %></td> 
  30.  </tr> 
  31.  <tr> 
  32.  <td>年龄</td> 
  33.  <td><%=request.getParameter("age") %></td> 
  34.  </tr> 
  35.  <tr> 
  36.  <td>性别</td> 
  37.  <td><%=request.getParameter("sex") %></td> 
  38.  </tr> 
  39.  <tr> 
  40.  <td>爱好</td> 
  41.  <td><%=request.getAttribute("aihao") %></td> 
  42.  </tr> 
  43.  </tbody> 
  44. </table
  45. </body> 
  46. </html> 

提交如下表单:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

后台打印:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

运行结果如下:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

四、request接收表单提交中文参数乱码问题

1、以POST方式提交表单中文参数的乱码问题

有如下表单:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.  pageEncoding="UTF-8"%> 
  3. <% 
  4.  String path = request.getContextPath(); 
  5.  String basePath = request.getScheme() + "://" 
  6.  + request.getServerName() + ":" + request.getServerPort() 
  7.  + path + "/"
  8. %> 
  9. <html> 
  10. <head> 
  11. <base href="<%=basePath%>" /> 
  12. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"
  13. <title>表单提交</title> 
  14. <link href="css/bootstrap.css" rel="stylesheet"
  15. <script src="js/jquery-3.2.1.js"></script> 
  16. <script src="js/bootstrap.js"></script> 
  17. </head> 
  18. <body> 
  19.  <form class="form-horizontal" action="<%=request.getContextPath()%>/PostRequest.html" role="form" method="post"
  20.  <div class="form-group"
  21.  <label for="firstname" class="col-sm-1 control-label">名字</label> 
  22.  <div class="col-sm-3"
  23.  <input type="text" class="form-control" name="name" 
  24.  placeholder="请输入名字"
  25.  </div> 
  26.  </div> 
  27.  <div class="form-group"
  28.  <div class="col-sm-offset-1 col-sm-3"
  29.  <button type="submit" class="btn btn-default">提交</button> 
  30.  <button type="reset" class="btn btn-default">重置</button> 
  31.  </div> 
  32.  </div> 
  33.  </form> 
  34. </body> 
  35. </html> 

后台接收参数:

  1. public class PostRequest extends HttpServlet{ 
  2.  private static final long serialVersionUID = 3903946972744326948L; 
  3.  @Override 
  4.  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  5.  this.doPost(req, resp); 
  6.  } 
  7.  @Override 
  8.  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.  String name = req.getParameter("name"); 
  10.  System.out.println("名字:" + name); 
  11.  } 

提交数据:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

运行结果:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收。

由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收,通过setCharacterEncoding方法统一编码格式:

  1. public class PostRequest extends HttpServlet{ 
  2.  private static final long serialVersionUID = 3903946972744326948L; 
  3.  @Override 
  4.  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  5.  this.doPost(req, resp); 
  6.  } 
  7.  @Override 
  8.  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.  //设置服务器以UTF-8的编码接收数据 
  10.  req.setCharacterEncoding("UTF-8"); 
  11.  String name = req.getParameter("name"); 
  12.  System.out.println("名字:" + name); 
  13.  } 

重新提交表单,中文乱码解决:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

2、以GET方式提交表单中文参数的乱码问题

有如下表单:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" 
  2.  pageEncoding="UTF-8"%> 
  3. <% 
  4.  String path = request.getContextPath(); 
  5.  String basePath = request.getScheme() + "://" 
  6.  + request.getServerName() + ":" + request.getServerPort() 
  7.  + path + "/"
  8. %> 
  9. <html> 
  10. <head> 
  11. <base href="<%=basePath%>" /> 
  12. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"
  13. <title>表单提交</title> 
  14. <link href="css/bootstrap.css" rel="stylesheet"
  15. <script src="js/jquery-3.2.1.js"></script> 
  16. <script src="js/bootstrap.js"></script> 
  17. </head> 
  18. <body> 
  19.  <form class="form-horizontal" action="<%=request.getContextPath()%>/GetRequest.html" role="form" method="get"
  20.  <div class="form-group"
  21.  <label for="firstname" class="col-sm-1 control-label">名字</label> 
  22.  <div class="col-sm-3"
  23.  <input type="text" class="form-control" name="name" 
  24.  placeholder="请输入名字"
  25.  </div> 
  26.  </div> 
  27.  <div class="form-group"
  28.  <div class="col-sm-offset-1 col-sm-3"
  29.  <button type="submit" class="btn btn-default">提交</button> 
  30.  <button type="reset" class="btn btn-default">重置</button> 
  31.  </div> 
  32.  </div> 
  33.  </form> 
  34. </body> 
  35. </html> 

后台接收参数:

  1. public class GetRequest extends HttpServlet{ 
  2.  private static final long serialVersionUID = 3903946972744326948L; 
  3.  @Override 
  4.  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  5.  this.doPost(req, resp); 
  6.  } 
  7.  @Override 
  8.  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.  String name = req.getParameter("name"); 
  10.  System.out.println("名字:" + name); 
  11.  } 

提交数据:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

运行结果:

原来HTTP协议这么简单!一文读懂HttpServletRequest(周末快乐)

之所以会产生乱码,对于以get方式传输的数据,默认的还是使用ISO8859-1这个字符编码来接收数据,客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的。

解决方法:

在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串

  1. public class GetRequest extends HttpServlet{ 
  2.  private static final long serialVersionUID = 3903946972744326948L; 
  3.  @Override 
  4.  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  5.  this.doPost(req, resp); 
  6.  } 
  7.  @Override 
  8.  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
  9.  String name = req.getParameter("name"); 
  10.  //以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串 
  11.  name = new String(name.getBytes("ISO8859-1") , "UTF-8"); 
  12.  System.out.println("名字:" + name); 
  13.  } 

【编辑推荐】

  1. HTTP 2还没上手,HTTP 3已经箭在弦上
  2. 网络层协议划分VLAN,你们会用吗?
  3. HTTP也有长短之分?HTTP的长连接 vs. 短连接
  4. 网络通信协议之TCP
  5. 是时候理解下HTTPS及背后的加密原理了
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

这就是5G

这就是5G

5G那些事儿
共15章 | armmay

111人订阅学习

16招轻松掌握PPT技巧

16招轻松掌握PPT技巧

GET职场加薪技能
共16章 | 晒书包

369人订阅学习

20个局域网建设改造案例

20个局域网建设改造案例

网络搭建技巧
共20章 | 捷哥CCIE

753人订阅学习

读 书 +更多

Web服务安全

Web服务技术是最近几年迅速兴起的一种应用集成技术,而安全问题是影响该技术广泛应用的一个关键因素。这个问题已成为最近几年来国内外研究...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微