springboot开发日记(11)——请求参数处理

请求映射

Rest风格(使用HTTP请求方式动词来表示对资源的操作

 /user   GET-获取用户 DELETE-删除用户 PUT-修改用户 POST-保存用户
在index.html中添加表单标签:
<form action="/user" method="post">
    <input value="REST-post test" type="submit">
</form>
<form action="/user" method="get">
    <input value="REST-get test" type="submit">
</form>
<form action="/user" method="delete">
    <input value="REST-delete test" type="submit">
</form>
<form action="/user" method="put">
    <input value="REST-put test" type="submit">
</form>

我们会发现method属性中只有post和get两个值,但是我们先按照Rest风格的格式进行赋值。

在HelloController.java中编写对应处理方法

@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getUser(){
    return "GET-张三";
}

@RequestMapping(value = "/user",method = RequestMethod.POST)
public String saveUser(){
    return "POST-张三";
}


@RequestMapping(value = "/user",method = RequestMethod.PUT)
public String putUser(){
    return "PUT-张三";
}

@RequestMapping(value = "/user",method = RequestMethod.DELETE)
public String deleteUser(){
    return "DELETE-张三";
}

进入网站测试,依次点击四个测试按钮发现前两个使用post和get方法的结果正确,后两个方法的显示结果错误。原因是后两个方法目前不支持,所以直接按照默认值get执行,为了解决这个问题,我们不妨再次看一下源码:仍在是在WebMvcAutoConfiguration.class这个类下方寻找,找到一个名为public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter()的方法,我们可以通过这个过滤器启用Rest风格,同时也说明springboot是默认配置这个过滤器的。再查看OrderedHiddenHttpMethodFilter的源码,发现是HiddenHttpMethodFilter这个类的子类,继续向深层找,找到这个类的源码

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    HttpServletRequest requestToUse = request;
    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 HttpMethodRequestWrapper(request, method);
            }
        }
    }

    filterChain.doFilter((ServletRequest)requestToUse, response);
}
 我们发现最外层判断条件是当method的值为POST时才生效,String paramValue = request.getParameter(this.methodParam); 这句意思是获取名为methodParam的值观察上文发现methodParam被规定了值:private String methodParam = "_method";也就是说我们需要在form标签中添加一个名为_method的隐藏域,这个隐藏域的值则是我们希望该form标签生效的Rest风格。修改delete和put两个风格的form表单:
<form action="/user" method="post">
    <input type="hidden" name="_method" value="DELETE">
    <input value="REST-delete test" type="submit">
</form>
<form action="/user" method="post">
    <input type="hidden" name="_method" value="PUT">
    <input value="REST-put test" type="submit">

 此时我们再次执行测试发现仍然没有生效,于是我们再去查看源码:发现在WebMvcAutoConfiguration.class这个类下的public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter()方法的注释有所要求:

@Bean
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
@ConditionalOnProperty(
    prefix = "spring.mvc.hiddenmethod.filter",
    name = {"enabled"}
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
    return new OrderedHiddenHttpMethodFilter();
}
这两个@Conditional注解表示如果开发者没有配置HiddenHttpMethodFilter.class这个类则springboot会自动配置,重点在后面这个@Conditional注解,我们只有配置了规定的属性这个过滤器才会生效。如果没有配置该属性则默认不生效,那么我们需要在yaml文件中进行配置。
spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true

 开启过滤器后我们再进行测试发现功能正常,配置成功。

Rest原理(表单提交要使用REST的时候)

  • 表单提交会带上_method=PUT
  • 请求过来被HiddenHttpMethodFilter拦截
    • 请求是否正常,并且是POST
      • 获取到_method的值。
      • 兼容以下请求;PUT.DELETE.PATCH
      • 原生request(post),包装模式requesWrapper重写了getMethod方法,返回的是传入的值。
      • 过滤器链放行的时候用wrapper。以后的方法调用getMethod是调用requesWrapper的。

我们可以直接在Controller类使用四种Rest风格的注解:

@GetMapping
@PostMapping
@DeleteMapping
@PutMapping

注意:使用这四种注解也需要开启过滤器 


自定义filter 

 通过自定义fiilter可以自己选择methodParam的值

@Configuration(proxyBeanMethods = false)
public class WebConfig {
    @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
        HiddenHttpMethodFilter methodfilter= new HiddenHttpMethodFilter();
        methodfilter.setMethodParam("_m");
        return  methodfilter;
    }
}

这样我们index中隐藏域的name值就应该改为_m

 

 

 

 

posted @ 2023-02-12 11:40  YTARO  阅读(86)  评论(0编辑  收藏  举报