乐趣区

关于springboot:form表单putdelete方式提交处理

form 表单 put、delete 形式提交解决

form 表单只反对 get 和 post 的形式提交,而咱们应用 restful 格调必然要应用到 @PUTmapping、@DELETEmapping 等注解,那么在提交表单时的 method=“put/delete”也要对应注解,上面来看看 SpringMVC 和 SpringBoot 的解决形式。

1、SpringMVC 的解决

SpringMVC 通过在 web.xml 中配置如下过滤器 HiddenHttpMethodFilter 解决;而后在页面上提交一个暗藏的 input 来实现;

1、配置 HiddenHttpMethodFilter

<filter>
        <filter-name>HttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2、表单解决

<form th:action=""method="post">
    <!--
 发送 put 申请批改员工数据
 1、SpringMVC 中配置 HiddenHttpMethodFilter;2、页面创立一个 Post 表单;3、创立一个暗藏的 input 项,name=_method,value 就是咱们指定的申请形式;--> 
 <input type="hidden" name="_method" value="put" />
 </form>

留神这里的 name 属性只能为_method,value 为咱们想提交的形式;

2、SpringBoot 的解决

SpringBoot 曾经为咱们主动配置了 HttpMethodFilter,SpringBoot2.2.0 以上版本须要咱们手动开启配置;

1、开启配置

# 开启 hiddenmethod 过滤器
spring.mvc.hiddenmethod.filter.enabled=true

2、表单解决
同上;

3、看看源码

Ctrl+ N 搜寻 -WebMvcAutoConfiguration 类
而后 Ctrl+ F 搜寻 -hiddenmethod
看看 SpringBoot 如何主动配置的
源码如下:

@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
// 意为当咱们配置文件中没找到这个前缀(prefix)为 spring.mvc.hiddenmethod.filter 的名为 enabled 的属性就不开启这项配置,即默认 false;@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)

public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();
}

按住 Ctrl 并点击 HiddenHttpMethodFilter.class,去看看过滤器的源码

public class HiddenHttpMethodFilter extends OncePerRequestFilter {
    private static final List<String> ALLOWED_METHODS;// 容许的办法
    public static final String DEFAULT_METHOD_PARAM = "_method";
    private String methodParam = "_method";// 这就是 name="_method",也就是从页面拿到的参数
    public HiddenHttpMethodFilter() {}
    public void setMethodParam(String methodParam) {Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest requestToUse = request;
        // 这里 if 判断 request 是不是 post,这也是为什么 form 必须为 post 的起因
        if ("POST".equals(request.getMethod()) && request.getAttribute("javax.servlet.error.exception") == null) {
        
            // 利用 request.getParameter 取到 hidden 的 input 传来的 value;String paramValue = request.getParameter(this.methodParam);
            
            //hasLength()判断 paramValue 不为空行将 paramValue 转为大写并赋值给 method
            if (StringUtils.hasLength(paramValue)) {
            // 这个 method 才是咱们真正想要的申请形式
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                
                // 如果被容许的 method 中蕴含有咱们真正想要的申请形式
                if (ALLOWED_METHODS.contains(method)) {
                // 就应用咱们心愿的申请形式,把不是咱们传的 method 过滤掉了
                    requestToUse = new HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                }
            }
        }
        filterChain.doFilter((ServletRequest)requestToUse, response);
    }
    // 这里定义了 3 种容许的办法 DELETE、PUT、PATCH
    static {ALLOWED_METHODS = Collections.unmodifiableList(Arrays.asList(HttpMethod.PUT.name(), HttpMethod.DELETE.name(), HttpMethod.PATCH.name()));
    }
    
    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;}
    }
}
退出移动版