Spring-mvc - Filter - HiddenHttpMethodFilter - 支持Rest
🌳 支持Rest - 配置HiddenHttpMethodFilter
spring-mvc默认不支持rest(只能处理get、post请求)。配置HiddenHttpMethodFilter以支持Rest,HiddenHttpMethodFilter原理是把HttpServletRequest包装成HttpServletRequestWrapper,重写(override)其getMethod()方法。
步骤如下
- 配置
HiddenHttpMethodFilter过滤器。 - 在
表单中添加name是_method的字段。
1️⃣ 配置HiddenHttpMethodFilter
<!-- hiddenHttpFilter - 支持PUT、DELETE请求 -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2️⃣ 表单中添加_method字段
<form id="mainForm" method="post" action="${basePath}/ad/edit" enctype="multipart/form-data">
<input type="hidden" name="_method" value="put" />
</form>
🌲 Rest文件上传 - PUT请求上传文件问题 - 无法解析multipart
出现原因
form表单的enctype是multipart/form-data,浏览器发请求报文到服务器服务器(tomcat)解析http请求报文成HttpServletRequest,默认不解析multipart段- 请求到
HiddenHttpMethodFilter,因为mulpart中的_method没解析,获取不到_method。
解决方法有两种
- 配置
multipart-config,支持解析multipart/form-data- StandardMultiPartResolver方式 - 配置
MultiPartFilter- CommonsMultiPartResolver方式
🅰️ 配置multipart-config
<!-- DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-web.xml</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--- ❤️ 这里的内容 - 解析后 - 解析成Part --->
<multipart-config>
<!-- 最大上传大小(-1表示不限制) - 10M -->
<max-file-size>10485760</max-file-size>
<!-- 请求报文最大大小(-1不限制) - 不限制 -->
<max-request-size>-1</max-request-size>
<!-- 文件超过多大,就会被临时存储在磁盘,而不是内存 - 10M -->
<file-size-threshold>10485760</file-size-threshold>
<!-- location - part.write()如果写的不是绝对路径,相对于location-->
</multipart-config>
</servlet>
🅱️ 配值MultipartFilter
<!-- multiPartFilter - 用于解析 MultiPart请求 -->
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<!-- 指定multipartResolver的beanName - 默认是fileMultipartResolver -->
<init-param>
<param-name>multipartResolverBeanName</param-name>
<param-value>filterMultipartResolver</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
你还需要把你的multipartResolver提取到RootApplicationContext
<!-- MultipartResolver -->
<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="#{5*1024*1024}" />
<property name="maxInMemorySize" value="#{5*1024*1024}" />
</bean>
🌾 JSP支持Rest - tomcat问题
在tomcat8之后,jsp不支持Rest,有如下解决方案
- 自定义
Filter,把HttpServletRequest封装成HttpServletRequestWrapper,重写getMethod方法,配置Filter的dispatcher为DORWARD - 在
jsp页面中Page指令(三大指令之一)的isErrorPage属性
🅰️ 自定义Filter封装Request为RequestWrapper
1️⃣ 自定义Filter封装HttpServletRequest为HttpServletRequestWrapper,重写getMethod()方法
public class JspSpringFilter extends HiddenHttpMethodFilter {
// ❤️ 实现HttpServvletRequestWrapper
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
// ❤️ 重写getMethod()
public String getMethod() {
return this.method;
}
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest requestToUse = request;
// 1. init method - 匹配delete和put
String method = requestToUse.getMethod();
if (method.equalsIgnoreCase("delete") || method.equalsIgnoreCase("put")) {
method = "POST";
}
// 2. init wrapper - 封装成HttpServletRequestWrapper
requestToUse = new HttpMethodRequestWrapper(request, method);
// 3. doFilter
filterChain.doFilter(requestToUse, response);
}
}
2️⃣ 配置Filter为FORWARD - 只在请求forwrad时候匹配
<!-- JspRestSupportFilter - JSP支持rest方式-->
<filter>
<filter-name>jspSpringFilter</filter-name>
<filter-class>com.yuki.dianping.filter.JspSpringFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>jspSpringFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
🅱️在Page指令中指定isErrorPage属性
<!-- 🟢 这里的isErrorPage设置成 true-->
<%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<!-- taglib -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

浙公网安备 33010602011771号