http content type的含义和Springweb PUT方法支持

常见表单提交格式

先从可以看到的地方说起,postman是一个很好用的工具,

form-data,是提交form表单的标准选项之一,如果html form标签没有指定enctype,那么默认使用这种方式提交表单,内容格式如下:

{boundary}
Content-Disposition: form-data; name={direct name}

{value}
...<loop line1 to line4>...
{boundary}--

header中content-type应该指定multipart/form-data; boundary={boundary}

x-www-form-urlencoded,是提交form表单的标准选项之一,形式是

{encoded_name1}={encoded_value1}&{encoded_name2}={encoded_value2}

客户端的name和value都是字符串,然后encode之后拼接添加到http request的entity。发送。

raw,不是http协议的一种content-type,只是postman的称呼而已,用户为了提供entity数据给server而不是为了提交form表单。表单是一种特殊含义的数据,一般都是name value对,而提交数据的含义则广泛得多,例如elasticsearch查询时候需要提供json作为entity,但是并不要求把json作为value,与一个name关联,从而形成一个form表单提交。
在postman中raw的用法就可以是:

{"query":"...."}

header中增加Content-Type: application/json
或者当提交xml的时候也可以是:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
   ">
   <bean id="xxx" ...>

</beans>

header中添加Content-Type:text/xml。

强调

html的form控件只能用multipart/form-data或者application/x-www-form-urlencoded,因此form标签做不到application/json或者text/xml提交。
Ajax可以更灵活,发送json content-type的entity

Spring 对PUT的支持

Browsers can submit form data via HTTP GET or HTTP POST. Non-browser clients can also submit forms via HTTP PUT. This presents a challenge because the Servlet specification requires the ServletRequest.getParameter*() family of methods to support form field access only for HTTP POST, not for HTTP PUT.To support HTTP PUT and PATCH requests, the spring-web module provides the filter HttpPutFormContentFilter, which can be configured in web.xml:

<filter>
    <filter-name>httpPutFormFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>httpPutFormFilter</filter-name>
    <servlet-name>dispatcherServlet</servlet-name>
</filter-mapping>

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

The above filter intercepts HTTP PUT and PATCH requests with content type application/x-www-form-urlencoded, reads the form data from the body of the request, and wraps the ServletRequest in order to make the form data available through the ServletRequest.getParameter() family of methods.
可知,servlet规范规定,只有POST方法可以getParameter
,PUT,DELETE都不行,更不要说GET了。

网上提到的Tomcat的DefaultServlet的readonly问题与这个不同。DefaultServlet是提供静态资源访问和list目录的servlet,该servlet有自己的配置,默认不接受PUT和DELETE方法的请求。由于tomcat开箱即提供静态资源访问的能力,后端就是依赖这个DefaultServlet。如果只使用了DefaultServlet的情况下,会拒绝一些PUT和DELETE方法,因为一般通过浏览器访问静态资源是不会有这种方法的。

posted on 2020-01-02 18:34  还好可以改名字  阅读(490)  评论(0编辑  收藏  举报