1. servlet为何不能获取PUT和DELETE请求的参数

Servlet的规范是POST的数据需要转给request.getParameter*()方法,没有规定PUT和DELETE请求也这么做

2. 解决方案

        2-1  前端使用ajax请求时,发送json类型的参数

        2-2  后端使用字符流读取前端传递的参数

3. 具体的实现

        3-1 前端部分

$(function () {
  // 1. 请求参数
  let params = {
    id: 51,
    phone: '17911113333',
    userCode: 'barrss',
    userName: 'barrss',
    address: '不详',
    userRole: 1,
    gender: 1,
    birthday: '1998-10-12',
  }
  // 2. 使用jQuery的$.ajax()发送put类型请求进行用户修改
  $.ajax({
    url: 'http://localhost/day81/updateUser',
    // 请求类型是put
    type: 'put',
    dataType: 'json',
    // 通过请求头告诉服务端,发送的数据是json类型
    contentType: 'application/json',
    // 前端必须传递json字符串,否则后端无法解析
    data: JSON.stringify(params),
    headers: { token: '***.***zAyMjYwfQ.***' },
    success(res) {
      console.log(res)
    },
    error(e) {
      console.log(e)
    },
  })
})

        3-2 后端MyUtil工具类中定义方法 getJSONParams

/**
   *  获得前端发送的json类型参数
   *
   * @param req 封装客户端请求信息的对象
   * @return 包含请求参数的Map集合
   */
  public static Map<String, String> getJSONParams(HttpServletRequest req) throws ServletException, IOException {
    // 1. 打开输入流读取客户端写入的json字符串
    InputStream in = req.getInputStream();
    // 2. 使用BufferedReader包装流,指定字符串
    BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
    String str = null;
    StringBuilder builder = new StringBuilder();
    // 3. 读取客户端传递的json字符串参数,拼接到StringBuilder中
    while ((str = reader.readLine()) != null) {
      builder.append(str);
    }
    String params = builder.toString();
    // 4. 去除json字符串中的{}
    params = params.substring(1, params.length() - 1);
    // 5. 去除json字符串中的 "
    params = params.replace("\"", "");
    Map<String, String> map = new HashMap<>();
    // 6. 拆分字符串,把key=value键值对, 存放到map中
    String[] arr = params.split(",");
    for (String item : arr) {
      String[] code = item.split(":");
      map.put(code[0], code[1]);
    }
    return map;
  }

      3-3 servlet中的doPut方法中使用getJSONParams即可

  @Override
  protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    Map<String, String> map = MyUtil.getJSONParams(req);
    req.setAttribute("params", map);
    doPost(req, res);
  }

4. 总结

        使用此种方法获取客户端的put和delete请求方法,要规定客户端必须传递json字符串,后端需要自己开发方法来进行获取,使用起来并不方便,也不灵活。可以考虑使用POST代替PUT或DELETE请求,方便获取参数,不仅安全,而且高效!不妥之处还请指正。

09-26 13:28