• Servlet中常见的API详解


    目录

    1、核心方法:

    HttpServletRequest关键方法: 

    ​HttpServletResponse关键方法:

     2、获取GET请求信息:

    3、Post请求的构造

     4、Post请求信息的获取

    x-www-form-urlencode格式:

    json格式:

    5、响应的构造

    案例1: 设置响应状态码

    案例2:自动页面刷新

     案例3:重定向案例


    1、核心方法:

    这些方法的调用时机,就构成了“Servlet”的生命周期 

     生命周期

    注: 

    • 在写Servlet代码时,第一步就是先创建类,继承自HttpServlet,并且重写其中的某些方法
    • 在实际的开发中,主要重写doXXX方法,很少会重写init/destory/service 
    • HttpServlet的实例只是在程序启动时创建一次,而不是每次收到HTTP请求都重新创建实例
    • tomcat收到请求,实际上是先调用service,在service里面再去根据方法,调用不同的doXXX

    HttpServletRequest关键方法: 

    HttpServletResponse关键方法:


     2、获取GET请求信息:

    请求对象提供的都是getXXX方法,用来获取的,修改是setXXX方法

            对于请求的信息,我们运用HttpServletRequest类的方法来进行请求信息的获取:
            比如我们访问的url为http://127.0.0.1:8080/Test/requestServlet?key=10&a=100&b=200,很明显这是使用查询字符串构造的一个GET请求,通过HttpServletRequest类一系列对应的方法,我们可以获取到这个请求的方法类型,协议版本,URL,查询字符串,头部的一些信息等。其中查询字符串与头部信息的获取先要使用getParameterNames方法或者getHeaderNames方法获取所有的查询字符串或头部信息的所有key值,这个一个枚举对象,然后在根据getParameter或者getHeader方法通过key值遍历枚举对象获取value。

    代码测试看结果:

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. import java.util.Enumeration;
    8. @WebServlet("/requestServlet")
    9. public class ShowRequestServlet extends HttpServlet {
    10. @Override
    11. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    12. //访问链接:http://127.0.0.1:8080/hello_servlet/showreq?key=10&a=100&b=200
    13. StringBuilder stringBuilder = new StringBuilder();
    14. resp.setContentType("text/html; charset=utf-8");
    15. //1协议名称与版本
    16. stringBuilder.append("协议版本:");
    17. stringBuilder.append(req.getProtocol());
    18. stringBuilder.append("
      "
      );
    19. //2方法类型
    20. stringBuilder.append("方法:");
    21. stringBuilder.append(req.getMethod());
    22. stringBuilder.append("
      "
      );
    23. //3获取查URL路径
    24. stringBuilder.append("URL路径:");
    25. stringBuilder.append(req.getRequestURI());
    26. stringBuilder.append("
      "
      );
    27. //4URL(不包括查询字符串后面的部分)
    28. stringBuilder.append("URL(不包括查询字符串后面的部分):");
    29. stringBuilder.append(req.getRequestURL());
    30. stringBuilder.append("
      "
      );
    31. //5一级路径
    32. stringBuilder.append("一级路径:");
    33. stringBuilder.append(req.getContextPath());
    34. stringBuilder.append("
      "
      );
    35. //6查询字符串
    36. stringBuilder.append("查询字符串:");
    37. stringBuilder.append(req.getQueryString());
    38. stringBuilder.append("
      "
      );
    39. //7正文编码格式
    40. stringBuilder.append("正文编码格式:");
    41. stringBuilder.append(req.getCharacterEncoding());
    42. stringBuilder.append("
      "
      );
    43. //8mine
    44. stringBuilder.append("mine:");
    45. stringBuilder.append(req.getContentType());
    46. stringBuilder.append("
      "
      );
    47. //9正文长度
    48. stringBuilder.append("正文长度:");
    49. stringBuilder.append(req.getContentLength());
    50. stringBuilder.append("
      "
      );
    51. //10获得每一个查询字符串的键值:
    52. stringBuilder.append("

      获得每一个查询字符串的键值:

      "
      );
    53. Enumeration query = req.getParameterNames();
    54. while(query.hasMoreElements()) {
    55. String key = (String)query.nextElement();
    56. stringBuilder.append(key);
    57. stringBuilder.append(":");
    58. stringBuilder.append(req.getParameter(key));
    59. stringBuilder.append("
      "
      );
    60. }
    61. //11获得头部的键值
    62. stringBuilder.append("

      获得头部的键值:

      "
      );
    63. Enumeration header = req.getHeaderNames();
    64. while(header.hasMoreElements()) {
    65. String key = (String)header.nextElement();
    66. stringBuilder.append(key);
    67. stringBuilder.append(":");
    68. stringBuilder.append(req.getHeader(key));
    69. stringBuilder.append("
      "
      );
    70. }
    71. resp.getWriter().write(stringBuilder.toString());
    72. }
    73. }

            其中查询字符串与头部信息的获取先要使用getParameterNames方法或者getHeaderNames方法获取所有的查询字符串或头部信息的所有key值,这个一个枚举对象,然后在根据getParameter或者getHeader方法通过key值遍历枚举对象获取value。 

            成功启动后(如何部署程序,前面说过了,感兴趣的小伙伴可以自行去查看一下0,去浏览器查看结果:

             这里如果你出现乱码了,中文的编码有很多种,其中最常见就是utf8,如果没有显式的指定编码方式,则浏览器不能正确的识别编码,就会出现乱码,可以在代码中,通过resp.setContentType("text/html;charset=utf8");显式指定编码方法,一般情况就不会再有乱码了,但是,如果你还是乱码,可以去检查一下IDEA:

     这样设置后,应该就不会有问题啦!


    3、Post请求的构造

            在同一webapp里面,关联路径不能够相同,不然Tomcat跑不起来,对于GET请求,可以使用URL的查询字符串进行构造,但是POST请求不行,需要使用form或者ajax。

    构造Post请求(使用ajax构造):
            在webapp目录下创建一个HTML文件,用来构造POST请求,首先我们先的引入jquery依赖(https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js导入依赖),然后调用ajax构造请求。

    1. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">script>
    2. <script>
    3. $.ajax({
    4. type: "post",
    5. url: "method",
    6. success: function (body){
    7. console.log(body);
    8. }
    9. })
    10. script>

            注意上面的URL属性不能加/,加上表示的就是绝对路径了,当然你也可以使用./来表示相对路径,但是在Servlet注解关联路径必须得加上/。 

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. @WebServlet("/method")
    8. public class MethodServlet extends HttpServlet {
    9. @Override
    10. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. resp.setContentType("text/html; charset=utf8");
    12. resp.getWriter().write("POST请求");
    13. }
    14. }

     打包部署,刷新页面:ok


     4、Post请求信息的获取

            我们知道post请求的请求信息在http格式中的body部分当中,而body中的请求内容的格式是有很多种的,比如最常见的有:

    1. x-www-form-urlencode格式,通过form表单或者postman构造。
    2. json格式
    3. form-data格式

    x-www-form-urlencode格式:

    key=value&key=value&...

    form表单创建x-www-form-urlencode格式请求:

    1. html>
    2. <html lang="ch">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>posttitle>
    6. head>
    7. <body>
    8. <form action="./postParameter" method="post" accept-charset="utf-8">
    9. <span>userIdspan>
    10. <input type="text" name="userId">
    11. <span>classIdspan>
    12. <input type="text" name="classId">
    13. <input type="submit" value="提交">
    14. form>
    15. body>
    16. html>

    Servlet程序接收和处理请求:
            对于x-www-form-urlencode格式请求可以直接使用HttpServletRequest中的getParameter方法依据key来获取value,然后再将获取到的数据返回,form表单构造的请求会自动跳转页面。

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. @WebServlet("/postParameter")
    8. public class GetPostParameterServlet extends HttpServlet {
    9. @Override
    10. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //获取post请求body请求中的参数
    12. //设置请求与响应编码格式
    13. req.setCharacterEncoding("utf-8");
    14. resp.setContentType("text/html; charset=utf8");
    15. //比如useId = classId=
    16. String userId = req.getParameter("userId");
    17. String classId = req.getParameter("classId");
    18. //写会数据
    19. resp.getWriter().write("userId=" + userId + ", " + "classId=" + classId);
    20. }
    21. }

    结果:

    json格式:

    { \{{
    k e y : v a l u e , key:value,key:value,
    k e y : v a l u e , key:value,key:value,
    k e y : v a l u e , key:value,key:value,
    . . . ......
    } \}}

            对于json格式,手动解析不容易,因为json里面的字段是可以嵌套的,但我们可以借助第三方库来解析处理json,比如Jackson,Jackson依赖导入过程如下【中央仓库】:

    复制到pom.xml中:

     处理json请求步骤:
    第一步,在前端js代码中构造出格式为json格式的请求。
    其中ajax构造post请求,使用contentType来说明请求的类型,data属性来设置body的内容。

    1. html>
    2. <html lang="cn">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>jsontitle>
    6. head>
    7. <body>
    8. <input type="text" id="userId">
    9. <input type="text" id="classId">
    10. <input type="button" id="submit" value="提交">
    11. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">script>
    12. <script>
    13. let userIdInput = document.querySelector("#userId");
    14. let classIdInput = document.querySelector("#classId");
    15. let button = document.querySelector("#submit");
    16. button.onclick = function() {
    17. $.ajax({
    18. type : "post",
    19. url: "getJsonPost",
    20. contentType: "appliaction/json",
    21. data:JSON.stringify({
    22. userId: userIdInput.value,
    23. classId:classIdInput.value
    24. }),
    25. success: function(body){
    26. console.log(body);
    27. }
    28. })
    29. }
    30. script>
    31. body>
    32. html>

     第二步,在java后端代码中使用Jackson处理。

    • 创建Jackson核心对象ObjectMapper对象。
    • 读取请求中的body信息,该过程通过ObjectMapper对象的readValue方法实现。
    • 创建用来接受json数据的类。
    • readValue方法的参数有两个,第一个参数用来表示请求的来源,可以是路径字符串,与可以是InputSream对象,也可以是File对象,第二个参数表示接收json数据的类对象。
    • 处理并响应请求。 
    1. import com.fasterxml.jackson.databind.ObjectMapper;
    2. import javax.servlet.ServletException;
    3. import javax.servlet.annotation.WebServlet;
    4. import javax.servlet.http.HttpServlet;
    5. import javax.servlet.http.HttpServletRequest;
    6. import javax.servlet.http.HttpServletResponse;
    7. import java.io.IOException;
    8. class User {
    9. public String userId;
    10. public String classId;
    11. }
    12. @WebServlet("/JsonPost")
    13. public class GetJsonPostServlet extends HttpServlet {
    14. //1.创建一个Jackson的核心对象
    15. private ObjectMapper objectMapper = new ObjectMapper();
    16. @Override
    17. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    18. //格式
    19. resp.setContentType("text/html; charset=utf8");
    20. //处理
    21. //2.读取body请求的内容,使用ObjectMapper对象的readValue方法来解析
    22. //就是将字符串转换成java的对象,readValue方法的第一个参数可以是路径字符串可以是输入流对象,引入可以是File对象
    23. //第二个参数,表示需要将请求的json格式数据转换成哪一个java对象
    24. User user = objectMapper.readValue(req.getInputStream(), User.class);
    25. System.out.println(user.userId);
    26. System.out.println(user.classId);
    27. resp.getWriter().write("userId=" + user.userId + " ,classId=" + user.classId);
    28. }
    29. }

    结果;

    readValue方法基本原理:

            读取json格式的数据,并解析成键值对。
            便利这些键值对,获得key,并与所需传入的对象中的属性(反射)相比,如果key与属性的名字相同,则把key对应的value赋值给这个属性,否则就跳过,所有的键值对便利完后,这个对象差不多就被构造的差不多了。


    5、响应的构造

    案例1: 设置响应状态码

    设置方法很简单,只需要调用httpServletResponse对象中的setStatus方法就可以了

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. @WebServlet("/status")
    8. public class StatusServlet extends HttpServlet {
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //格式
    12. resp.setContentType("text/html; charset=utf8");
    13. //设置状态码
    14. int status = 200;
    15. resp.setStatus(status);
    16. resp.getWriter().write("hello,这是" + status + "状态码的响应内容!");
    17. }
    18. }

    网页显示:1

     我把状态码修改为404,网页显示如下:2

    案例2:自动页面刷新

            自动页面刷新只要在响应中设置一个header: Refresh就能实现页面的定时刷新了,对于响应header的设置,我们可以通过HttpServletResponse对象中的setHeader方法来设置Refresh属性和刷新频率。

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. @WebServlet("/autorefresh")
    8. public class AutoRefreshServlet extends HttpServlet {
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //格式
    12. resp.setContentType("text/html; charset = utf8");
    13. //设置Refresh,第二个参数表示刷新频率,单位是秒
    14. resp.setHeader("Refresh", "1");
    15. //响应
    16. resp.getWriter().write("时间戳:" + System.currentTimeMillis());
    17. }
    18. }

    页面显示:

    效果

     案例3:重定向案例

    第一步,设置状态码为302
    第二步,设置header:Location,调用setHeader方法时,第一个参数填Location,表示设置header字段为Location,第二个参数为重定向的目的地址,你要重定向到哪一个网址就传入哪一个地址的字符串。

    1. import javax.servlet.ServletException;
    2. import javax.servlet.annotation.WebServlet;
    3. import javax.servlet.http.HttpServlet;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. import java.io.IOException;
    7. @WebServlet("/redirect")
    8. public class RedirectServlet extends HttpServlet {
    9. @Override
    10. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    11. //格式
    12. resp.setContentType("text/html; charset = utf8");
    13. //设置状态码
    14. resp.setStatus(302);
    15. //设置重定向字段与地址,如跳转到力扣官网
    16. resp.setHeader("Location", "https://leetcode.cn/");
    17. }
    18. }

    效果: 

    3

             当然,servlet提供了更为简便的重定向方法,就是使用HttpServletResponse类中的sendRedirect方法。

    1. @WebServlet("/redirect")
    2. public class RedirectServlet extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. //格式
    6. resp.setContentType("text/html; charset = utf8");
    7. //设置状态码
    8. // resp.setStatus(302);
    9. // //设置重定向字段与地址,如跳转到力扣官网
    10. // resp.setHeader("Location", "https://leetcode.cn/");
    11. resp.sendRedirect("https://leetcode.cn/");
    12. }
    13. }

    效果与上面是一样的。

    本期结束啦!下期见~

  • 相关阅读:
    GBase 8a MPP集群VC管理之操作VC
    Hbase数据库安装部署
    Zuul使用总结
    Python搭配GBase 8s
    BOT模块论文阅读
    雪花算法基本原理与实现
    龙芯2k0300 - 智能车走马观碑组目标检测算法
    OpenSSL使用总结
    2023最新短剧小程序搭建,短剧分销系统功能介绍
    《痞子衡嵌入式半月刊》 第 98 期
  • 原文地址:https://blog.csdn.net/LYJbao/article/details/128082686