springmvc 框架使用 HiddenHttpMethodFilter 过滤器处理 PUT 和 DELETE 请求

springmvc 框架使用 HiddenHttpMethodFilter 过滤器处理 PUT 和 DELETE 请求,第1张

springmvc 框架使用 HiddenHttpMethodFilter 过滤器处理 PUT 和 DELETE 请求 一、问题的产生

如果你还记得 form 表单的请求方式,那么你应该找到在 form 表单中只有两种请求方式 GET、POST,那么 PUT 请求和 DELETE 请求是怎么处理的呢?接下来带你去了解一下。

二、HiddenHttpMethodFilter 过滤器的认识

对如何处理 PUT 和 DELETE 请求,可以使用 HiddenHttpMethodFilter 去进行处理。

我们先来看一下该类中的 doFilterInternal 方法,这是整个过滤器的核心方法:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
   HttpServletRequest requestToUse = request;
   // 获取请求方式,判断是否为 POST 请求,后面那个条件不用管,基本为 null
   if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
       String paramValue = request.getParameter(this.methodParam);
       if (StringUtils.hasLength(paramValue)) {
           String method = paramValue.toUpperCase(Locale.ENGLISH);
           if (ALLOWED_METHODS.contains(method)) {
               requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
           }
       }
   }

   filterChain.doFilter((ServletRequest)requestToUse, response);
}

上面的代码理解起来应该不难,首先请求的方式必须是 POST 才能进入 if 条件内,GET 请求没有意义,还是原样返回。从代码中看到 request.getParameter(this.methodParam) ,获取请求参数,也就是说在 form 表单中应该有那么一个参数,那么 methodParam 是什么呢?其实可以说是实际的请求方式,让我们来看一下:

private String methodParam = "_method";

在上面获取到实际的请求方式后,通过 StringUtils.hasLength(paramValue) 判断是否为空,如下:

public static boolean hasLength(@Nullable String str) {
    return str != null && !str.isEmpty();
}

将实际的处理方式通过 toUpperCase 转为大写后,通过ALLOWED_METHODS.contains(method)判断处理方式是否在允许的处理方式内,代码如下:

private static final List ALLOWED_METHODS;

static {
   ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
}

如果实际的处理方式为 PUT、DELETE、PATCH 那么就重构请求,requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);,我们来看一下 HttpMethodRequestWrapper 的代码,比较简单:

private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
   private final String method;

   public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
       super(request);
       this.method = method;
   }

   public String getMethod() {
       return this.method;
   }
}

在所有都完成后,通过 filterChain.doFilter((ServletRequest)requestToUse, response); 放行。

了解了 HiddenHttpMethodFilter 的源码后,就是如何配置过滤器,这个也比较简单,就是在 web.xml 文件中配置如下内容:


    hiddenHttpMethodFilter
    org.springframework.web.filter.HiddenHttpMethodFilter


    hiddenHttpMethodFilter
    /*

三、测试代码 1、首先测试没有过滤器的情况,我们直接在 form 表单中设置请求方式,我这里采用的是 springmvc 结合 Thymeleaf 模板引擎的方式去进行测试。
@GetMapping("/user")
public String getUsers () {
    System.out.println("查看所有用户信息");
    return "success";
}

@PostMapping("/user")
public String addUser(String username, String password) {
    System.out.println("添加用户信息 " + username +"," + password);
    return "success";
}

@PutMapping("/user")
public String updateUser(String username, String password) {
    System.out.println("修改用户信息 " + username +"," + password);
    return "success";
}

运行上面的代码,看结果,如果设置 put 请求是成功的那么我们应该会映射到 put 请求的路径下进行处理:


从请求路径和打印的信息中我们不难看出,他映射到了 GET 请求的处理路径(form 默认的请求方式是 GET)。

2、我们来正式编写使用 HiddenHttpMethodFilter 过滤器处理的代码。

(1)首先在 web.xml 文件下配置:


    hiddenHttpMethodFilter
    org.springframework.web.filter.HiddenHttpMethodFilter


    hiddenHttpMethodFilter
    /*

(2)编写业务代码

@GetMapping("/user")
public String getUsers () {
    System.out.println("查看所有用户信息");
    return "success";
}

@PostMapping("/user")
public String addUser(String username, String password) {
    System.out.println("添加用户信息 " + username +"," + password);
    return "success";
}

@PutMapping("/user")
public String updateUser(String username, String password) {
    System.out.println("修改用户信息 " + username +"," + password);
    return "success";
}

(3)编写测试的 html 页面代码,如下。


(4)测试,运行看结果


从上面的代码我们可以看到,这次响应了 PUT 请求的处理路径。

delete 请求代码这里就不展开写了,感兴趣的朋友们可以自行编写代码测试。码字不易,路过的朋友们请给博主点个赞呗!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5681308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存