爲了迎合Restful風格,提供的接口可能會包含:put、delete提交方式。在springmvc中實現表單以put、delete方式提交時,須要使用HiddenHttpMethodFilter過濾器。該過濾器的實現原理,默認在form表單內部定義一個hidden隱藏的標籤,默認須要標籤名爲:_method,hidden標籤的value爲put或delete;過濾器會接收_method的hidden標籤的value,若是發現存在_method的標籤,而且value爲put或delete時,會從新包裝一個請求,請求類型會設置爲_method標籤的value值。進而實現將post方式提交表單轉化爲Delete或Put請求。html
實現form post表當以put或delete方式提交的步驟包含如下:前端
idea下建立一個pom.xml工程:java
建立完後,工程結構以下:c++
設置web.xml配置以下:web
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>springmvcdemo</display-name> <welcome-file-list> <welcome-file>/index</welcome-file> </welcome-file-list> <!--結束後端數據輸出到前端亂碼問題--> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> <!--能夠經過配置覆蓋默認'_method'值 --> <init-param> <param-name>methodParam</param-name> <param-value>_method</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>myAppServletName</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myAppServletName</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
此時在WEB-INF下還須要新建一個applicationContext.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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--掃描全部的 spring包下的文件;--> <!--固然須要在spring配置文件裏面配置一下自動掃描範圍 <context:component-scan base-package="*"/> *表明你想要掃描的那些包的目錄所在位置。Spring 在容器初始化時將自動掃描 base-package 指定的包及其子包下的全部的.class文件, 全部標註了 @Repository 的類都將被註冊爲 Spring Bean。 --> <context:component-scan base-package="com.dx.test"/> <!--新增長的兩個配置,這個是解決406問題的關鍵--> <!--mvc註解驅動(可代替註解適配器與註解映射器的配置),默認加載不少參數綁定方法(實際開發時使用)--> <context:annotation-config/> <mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> <property name="contentType" value="text/html;charset=UTF-8" /> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> </bean> <!--本身後加的,該BeanPostProcessor將自動對標註@Autowired的bean進行注入--> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <property name="messageConverters"> <list> <!--<ref bean="stringHttpMessageConverter"/>--> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"/> <!-- <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> --> </list> </property> </bean> </beans>
配置pom.xml引入依賴以下:spring
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.dx.test</groupId> 8 <artifactId>demo</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 <packaging>war</packaging> 11 12 <name>demo Maven Webapp</name> 13 <!-- FIXME change it to the project's website --> 14 <url>http://www.example.com</url> 15 16 <properties> 17 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 18 <maven.compiler.source>1.8</maven.compiler.source> 19 <maven.compiler.target>1.8</maven.compiler.target> 20 <!--Spring版本號--> 21 <spring.version>5.2.0.RELEASE</spring.version> 22 <!--jstl標籤庫--> 23 <jstl.version>1.2</jstl.version> 24 <standard.version>1.1.2</standard.version> 25 </properties> 26 27 <dependencies> 28 <!-- servlet相關 29 <dependency> 30 <groupId>javax.servlet</groupId> 31 <artifactId>servlet-api</artifactId> 32 <version>2.5</version> 33 <scope>provided</scope> 34 </dependency> 35 --> 36 <dependency> 37 <groupId>javax.servlet</groupId> 38 <artifactId>javax.servlet-api</artifactId> 39 <version>3.0.1</version> 40 <scope>provided</scope> 41 </dependency> 42 43 <!--form 設置爲enctype="multipart/form-data",多文件上傳,在applicationContext.xml中配置了bean multipartResolver時,須要依賴該包。--> 44 <dependency> 45 <groupId>commons-fileupload</groupId> 46 <artifactId>commons-fileupload</artifactId> 47 <version>1.4</version> 48 </dependency> 49 50 <dependency> 51 <groupId>commons-io</groupId> 52 <artifactId>commons-io</artifactId> 53 <version>2.5</version> 54 </dependency> 55 56 <!--spring單元測試依賴--> 57 <dependency> 58 <groupId>org.springframework</groupId> 59 <artifactId>spring-test</artifactId> 60 <version>${spring.version}</version> 61 <scope>test</scope> 62 </dependency> 63 64 <!--springMVC核心包--> 65 <dependency> 66 <groupId>org.springframework</groupId> 67 <artifactId>spring-webmvc</artifactId> 68 <version>${spring.version}</version> 69 </dependency> 70 71 <!--spring核心包--> 72 <dependency> 73 <groupId>org.springframework</groupId> 74 <artifactId>spring-core</artifactId> 75 <version>${spring.version}</version> 76 </dependency> 77 78 <dependency> 79 <groupId>org.springframework</groupId> 80 <artifactId>spring-beans</artifactId> 81 <version>${spring.version}</version> 82 </dependency> 83 84 <dependency> 85 <groupId>org.springframework</groupId> 86 <artifactId>spring-context</artifactId> 87 <version>${spring.version}</version> 88 </dependency> 89 90 <dependency> 91 <groupId>org.springframework</groupId> 92 <artifactId>spring-context-support</artifactId> 93 <version>${spring.version}</version> 94 </dependency> 95 96 <dependency> 97 <groupId>org.springframework</groupId> 98 <artifactId>spring-aop</artifactId> 99 <version>${spring.version}</version> 100 </dependency> 101 102 <dependency> 103 <groupId>org.springframework</groupId> 104 <artifactId>spring-aspects</artifactId> 105 <version>${spring.version}</version> 106 </dependency> 107 108 <dependency> 109 <groupId>org.springframework</groupId> 110 <artifactId>spring-tx</artifactId> 111 <version>${spring.version}</version> 112 </dependency> 113 114 <dependency> 115 <groupId>org.springframework</groupId> 116 <artifactId>spring-web</artifactId> 117 <version>${spring.version}</version> 118 </dependency> 119 120 <dependency> 121 <groupId>org.springframework</groupId> 122 <artifactId>spring-jdbc</artifactId> 123 <version>${spring.version}</version> 124 </dependency> 125 126 <!--AOP begin--> 127 <dependency> 128 <groupId>org.aspectj</groupId> 129 <artifactId>aspectjrt</artifactId> 130 <version>1.8.13</version> 131 </dependency> 132 133 <dependency> 134 <groupId>org.aspectj</groupId> 135 <artifactId>aspectjrt</artifactId> 136 <version>1.8.13</version> 137 </dependency> 138 139 <dependency> 140 <groupId>cglib</groupId> 141 <artifactId>cglib</artifactId> 142 <version>3.2.5</version> 143 </dependency> 144 <!--AOP end--> 145 146 <!--json依賴--> 147 <dependency> 148 <groupId>org.codehaus.jackson</groupId> 149 <artifactId>jackson-core-asl</artifactId> 150 <version>1.5.2</version> 151 </dependency> 152 <dependency> 153 <groupId>org.codehaus.jackson</groupId> 154 <artifactId>jackson-mapper-asl</artifactId> 155 <version>1.5.2</version> 156 </dependency> 157 158 <!--jstl庫--> 159 <dependency> 160 <groupId>javax.servlet</groupId> 161 <artifactId>jstl</artifactId> 162 <version>${jstl.version}</version> 163 <scope>runtime</scope> 164 </dependency> 165 <dependency> 166 <groupId>taglibs</groupId> 167 <artifactId>standard</artifactId> 168 <version>${standard.version}</version> 169 </dependency> 170 171 <dependency> 172 <groupId>junit</groupId> 173 <artifactId>junit</artifactId> 174 <version>4.11</version> 175 <scope>test</scope> 176 </dependency> 177 </dependencies> 178 179 <build> 180 <finalName>demo</finalName> 181 <plugins> 182 <!-- 配置Tomcat插件 --> 183 <plugin> 184 <groupId>org.apache.tomcat.maven</groupId> 185 <artifactId>tomcat7-maven-plugin</artifactId> 186 <version>2.2</version> 187 <configuration> 188 <port>9090</port> 189 <path>/</path> 190 <uriEncoding>UTF-8</uriEncoding> 191 <server>tomcat7</server> 192 </configuration> 193 </plugin> 194 </plugins> 195 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> 196 <plugins> 197 <plugin> 198 <artifactId>maven-clean-plugin</artifactId> 199 <version>3.1.0</version> 200 </plugin> 201 <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> 202 <plugin> 203 <artifactId>maven-resources-plugin</artifactId> 204 <version>3.0.2</version> 205 </plugin> 206 <plugin> 207 <artifactId>maven-compiler-plugin</artifactId> 208 <version>3.8.0</version> 209 </plugin> 210 <plugin> 211 <artifactId>maven-surefire-plugin</artifactId> 212 <version>2.22.1</version> 213 </plugin> 214 <plugin> 215 <artifactId>maven-war-plugin</artifactId> 216 <version>3.2.2</version> 217 </plugin> 218 <plugin> 219 <artifactId>maven-install-plugin</artifactId> 220 <version>2.5.2</version> 221 </plugin> 222 <plugin> 223 <artifactId>maven-deploy-plugin</artifactId> 224 <version>2.8.2</version> 225 </plugin> 226 </plugins> 227 </pluginManagement> 228 </build> 229 </project>
/WEB-INF/views/index.jsp內容以下:apache
<html> <body> <h2>Hello World!</h2> </body> </html>
/WEB-INF/views/article/list.jsp內容以下:json
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <!-- 屏蔽tomcat 自帶的 EL表達式 --> <%@ page isELIgnored="false" %> <html> <head> <meta charset="UTF-8"> <title>Spring MVC Demo</title> </head> <body> <h2>All Articles</h2> <table border="1"> <tr> <th>Article Id</th> <th>Article Name</th> </tr> <c:forEach items="${articles}" var="article"> <tr> <td>${article.id}</td> <td>${article.title}</td> </tr> </c:forEach> </table> </body> </html>
/WEB-INF/views/article/show.jsp內容以下:後端
<%@ page language="java" pageEncoding="UTF-8"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!-- 屏蔽tomcat 自帶的 EL表達式 --> <%@ page isELIgnored="false" %> <html> <head> <meta charset="UTF-8"> <title>Spring MVC Demo</title> </head> <body> <h2>Post方式提交:</h2> <form:form name="article" method="POST" action="update_with_post" modelAttribute="article"> Id:<form:hidden path="id"/> Title: <form:input path="title" style="width:200px;"/><br/> Content: <form:input path="content" style="width:200px;"/><br/> <input type="submit" value="Submit" /> </form:form> <form name="article" method="POST" action="update_with_post"> Id:<input name="id" id="id" value="${article.id}"/><br/> Title:<input name="title" id="title" value="${article.title}"/><br/> Content:<input name="content" id="content" value="${article.content}"/><br/> <input type="submit" value="Submit" /> </form> <h2>Post包含上傳文件提交:</h2> <form:form name="article" method="POST" action="update_with_post_file" modelAttribute="article" enctype="multipart/form-data"> Id:<form:hidden path="id"/> Title: <form:input path="title" style="width:200px;"/><br/> Content: <form:input path="content" style="width:200px;"/><br/> yourfile: <input type="file" name="file"/><br/> <input type="submit" value="Submit" /> </form:form> <form name="article" method="POST" action="update_with_post_file" enctype="multipart/form-data"> Id:<input name="id" id="id" value="${article.id}"/><br/> Title:<input name="title" id="title" value="${article.title}"/><br/> Content:<input name="content" id="content" value="${article.content}"/><br/> yourfile: <input type="file" name="file"/><br/> <input type="submit" value="Submit" /> </form> <h2>Put方式提交:</h2> <form:form name="article" method="POST" action="update_with_put" modelAttribute="article"> <input type="hidden" name="_method" value="PUT"/> Id:<form:hidden path="id"/> Title: <form:input path="title" style="width:200px;"/><br/> Content: <form:input path="content" style="width:200px;"/><br/> <input type="submit" value="Submit" /> </form:form> <form name="article" method="POST" action="update_with_put"> <input type="hidden" name="_method" value="PUT"/> Id:<input name="id" id="id" value="${article.id}"/><br/> Title:<input name="title" id="title" value="${article.title}"/><br/> Content:<input name="content" id="content" value="${article.content}"/><br/> <input type="submit" value="Submit" /> </form> <h2>Put包含上傳文件提交:</h2> <form:form name="article" method="POST" action="update_with_put_file" modelAttribute="article" enctype="multipart/form-data"> <input type="hidden" name="_method" value="PUT"/> Id:<form:hidden path="id"/> Title: <form:input path="title" style="width:200px;"/><br/> Content: <form:input path="content" style="width:200px;"/><br/> yourfile: <input type="file" name="file"/><br/> <input type="submit" value="Submit" /> </form:form> <form method="POST" name="article" action="update_with_put_file" enctype="multipart/form-data"> <input type="hidden" name="_method" value="PUT"/> Id:<input name="id" id="id" value="${article.id}"/><br/> Title:<input name="title" id="title" value="${article.title}"/><br/> Content:<input name="content" id="content" value="${article.content}"/><br/> yourfile: <input type="file" name="file"/><br/> <input type="submit" value="Submit" /> </form> </body> </html>
com.dx.test.model.ArticleModel.java
package com.dx.test.model; import java.io.Serializable; import java.util.Date; /** * 文章內容 */ public class ArticleModel implements Serializable { private Long id; private Long categoryId; private String title; private String content; private Date createTime; private String createUser; private String createUserId; private Date modifyTime; private String modifyUser; private String modifyUserId; public ArticleModel() { } public ArticleModel(Long id, Long categoryId, String title, String content) { this.id = id; this.categoryId = categoryId; this.title = title; this.content = content; } /** * @return the id */ public Long getId() { return id; } /** * @param id the id to set */ public void setId(Long id) { this.id = id; } /** * @return the categoryId */ public Long getCategoryId() { return categoryId; } /** * @param categoryId the categoryId to set */ public void setCategoryId(Long categoryId) { this.categoryId = categoryId; } /** * @return the title */ public String getTitle() { return title; } /** * @param title the title to set */ public void setTitle(String title) { this.title = title; } /** * @return the content */ public String getContent() { return content; } /** * @param content the content to set */ public void setContent(String content) { this.content = content; } /** * @return the createTime */ public Date getCreateTime() { return createTime; } /** * @param createTime the createTime to set */ public void setCreateTime(Date createTime) { this.createTime = createTime; } /** * @return the createUser */ public String getCreateUser() { return createUser; } /** * @param createUser the createUser to set */ public void setCreateUser(String createUser) { this.createUser = createUser; } /** * @return the createUserId */ public String getCreateUserId() { return createUserId; } /** * @param createUserId the createUserId to set */ public void setCreateUserId(String createUserId) { this.createUserId = createUserId; } /** * @return the modifyTime */ public Date getModifyTime() { return modifyTime; } /** * @param modifyTime the modifyTime to set */ public void setModifyTime(Date modifyTime) { this.modifyTime = modifyTime; } /** * @return the modifyUser */ public String getModifyUser() { return modifyUser; } /** * @param modifyUser the modifyUser to set */ public void setModifyUser(String modifyUser) { this.modifyUser = modifyUser; } /** * @return the modifyUserId */ public String getModifyUserId() { return modifyUserId; } /** * @param modifyUserId the modifyUserId to set */ public void setModifyUserId(String modifyUserId) { this.modifyUserId = modifyUserId; } @Override public String toString() { return "ArticleModel{" + "id=" + id + ", categoryId=" + categoryId + ", title='" + title + '\'' + ", content='" + content + '\'' + '}'; } }
com.dx.test.controller.HomeController.java
package com.dx.test.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class HomeController { @RequestMapping(value = "/", method = RequestMethod.GET) public String index() { return "index"; } }
com.dx.test.controller.ArticleController.java
1 package com.dx.test.controller; 2 3 import com.dx.test.model.ArticleModel; 4 import com.dx.test.service.IArticleService; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.http.MediaType; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.ui.Model; 9 import org.springframework.ui.ModelMap; 10 import org.springframework.web.bind.annotation.*; 11 import org.springframework.web.multipart.MultipartFile; 12 import org.springframework.web.multipart.MultipartHttpServletRequest; 13 import org.springframework.web.servlet.ModelAndView; 14 15 import javax.servlet.http.HttpServletRequest; 16 import javax.xml.ws.http.HTTPBinding; 17 import java.io.IOException; 18 import java.util.List; 19 import java.util.Map; 20 import java.util.Optional; 21 22 @Controller 23 @RequestMapping("/article") 24 public class ArticleController { 25 @Autowired 26 private IArticleService articleService; 27 28 @GetMapping("/list") 29 public String queryList(Model model, @RequestHeader(value = "userId", required = false) String userId) { 30 List<ArticleModel> articleModelList = articleService.queryList(); 31 model.addAttribute("articles", articleModelList); 32 return "article/list"; 33 } 34 35 @RequestMapping(value = "/{id}", method = RequestMethod.GET) 36 public ModelAndView queryById(@PathVariable(value = "id", required = true) Long id) { 37 ArticleModel articleModel = articleService.getById(id); 38 ModelAndView mv = new ModelAndView(); 39 mv.setViewName("article/show"); 40 mv.addObject("article", articleModel); 41 return mv; 42 } 43 44 @RequestMapping(value = "/update_with_post", method = RequestMethod.POST) 45 public String update_with_post(@ModelAttribute(value = "article") ArticleModel article) { 46 System.out.println(article); 47 return "index"; 48 } 49 50 @RequestMapping(value = "/update_with_post_file", method = RequestMethod.POST, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) 51 public String update_with_post_file(@ModelAttribute(value = "article") ArticleModel article, @RequestBody MultipartFile file, HttpServletRequest request) { 52 System.out.println(article); 53 System.out.println(file); 54 String id = request.getParameter("id"); 55 String title = request.getParameter("title"); 56 String content = request.getParameter("content"); 57 System.out.println(String.format("%s,%s,%s", id, title, content)); 58 59 return "index"; 60 } 61 62 @RequestMapping(value = "/update_with_put", method = RequestMethod.PUT) 63 public String update_with_put(@ModelAttribute(value = "article") ArticleModel article) { 64 System.out.println(article); 65 return "index"; 66 } 67 68 @RequestMapping(value = "/update_with_put_file", method = RequestMethod.PUT, consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) 69 public String update_with_put_file(@ModelAttribute(value = "article") ArticleModel article, @RequestBody MultipartFile file, HttpServletRequest request) { 70 System.out.println(article); 71 System.out.println(file); 72 String id = request.getParameter("id"); 73 String title = request.getParameter("title"); 74 String content = request.getParameter("content"); 75 System.out.println(String.format("%s,%s,%s", id, title, content)); 76 77 return "index"; 78 } 79 }
給demo工程配置tomcat:
以後啓動後能夠從Console上打印信息,查看到端口,我這裏端口是9090
在http://localhost:9090/article/1頁面中:
對應show.jsp上的內容:
按照上邊新建項目的web.xml、applicationContext.xml、ArticleController.java,提交'Post方式提交:,後臺就能正常接收到參數,此時後臺打印信息以下:
[DEBUG] POST "/article/update_with_post", parameters={masked} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post(ArticleModel) ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'} [DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK
[DEBUG] POST "/article/update_with_post", parameters={masked} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post(ArticleModel) ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'} [DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK
備註:
1)post不含上傳文件的意思是:form表單中不包含屬性enctype="multipart/form-data"設置。
2)上邊日誌包含兩次提交分別表明/WEB-INF/views/article/show.jsp頁面中「Post方式提交:」下邊的兩個表單提交:第一個表單是jst方式的表單,第二個表單是純html的表單。
在http://localhost:9090/article/1頁面中:
對應show.jsp中內容:
由於是上傳文件,並且handler方法使用HttpServletRequest參數,所以須要在pom.xml中引入上傳文件依賴包,和servlet包:
<!-- servlet相關,在handler參數中中包含:HttpServletRequest request參數時,須要引入javax.servlet依賴 <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <!--form 設置爲enctype="multipart/form-data",多文件上傳,在applicationContext.xml中配置了bean multipartResolver時,須要依賴該包。--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>
按照上邊新建項目的web.xml、applicationContext.xml、ArticleController.java,提交'Post包含上傳文件提交:',後臺不能正常接收到參數,此時後臺打印信息以下:
[DEBUG] POST "/article/update_with_post_file", parameters={} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post_file(ArticleModel, MultipartFile, HttpServletRequest) ArticleModel{id=null, categoryId=null, title='null', content='null', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'} null null,null,null [DEBUG] View name 'index', model {article=ArticleModel{id=null, categoryId=null, title='null', content='null', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK
[DEBUG] POST "/article/update_with_post_file", parameters={} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post_file(ArticleModel, MultipartFile, HttpServletRequest) ArticleModel{id=null, categoryId=null, title='null', content='null', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'} null null,null,null [DEBUG] View name 'index', model {article=ArticleModel{id=null, categoryId=null, title='null', content='null', createTime=null, createUser='null', createUserId='null', modifyTime=null, modifyUser='null', modifyUserId='null'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK
備註:
1)post包含上傳文件的意思是:form表單中包含屬性enctype="multipart/form-data"設置。
2)上邊日誌包含兩次提交分別表明/WEB-INF/views/article/show.jsp頁面中「Post包含上傳文件提交:」下邊的兩個表單提交:第一個表單是jst方式的表單,第二個表單是純html的表單。
從上邊日誌能夠看到,按照新建項目的方式提交「Post包含上傳文件」的表單,後臺是接收不到文件和article參數,並且request中也接收不到id,title,content參數。
此時,須要修改applicationContext.xml和web.xml才能實現後端接收到file和參數信息:
applicationContext.xml中須要註冊bean「multipartResolver」:
<!-- 配置文件上傳解析器 enctype="multipart/form-data" --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 指定所上傳文件的總大小不能超過20M。注意maxUploadSize屬性的限制不是針對單個文件,而是全部文件的容量之和 --> <property name="maxUploadSize" value="209715200"/> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean>
web.xml須要加入如下filter「MultipartFilter」和引入listener「ContextLoaderListener」:
<!-- 全局初始化數據,spring的監聽器讀取此配置文件,多個配置文件用分號分隔 若是在web.xml中不寫任何參數配置信息,默認的路徑是/WEB-INF/applicationContext.xml,在WEB-INF目錄下建立的xml文件的名稱必須是applicationContext.xml; 若是是要自定義文件名能夠在web.xml里加入contextConfigLocation這個context參數: --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 文件上傳與下載過濾器:form表單中存在文件時,該過濾器能夠處理http請求中的文件,被該過濾器過濾後會用post方法提交,form表單需設爲enctype="multipart/form-data"--> <!-- 注意:必須放在HiddenHttpMethodFilter過濾器以前 --> <filter> <filter-name>MultipartFilter</filter-name> <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> <init-param> <param-name>multipartResolverBeanName</param-name> <!--spring中配置的id爲multipartResolver的解析器--> <param-value>multipartResolver</param-value> </init-param> </filter> <filter-mapping> <filter-name>MultipartFilter</filter-name> <!--<servlet-name>myAppServletName</servlet-name>--> <url-pattern>/*</url-pattern> </filter-mapping>
此時從新提交兩個表單,後臺打印日誌以下:
[DEBUG] Using MultipartResolver 'multipartResolver' for MultipartFilter [DEBUG] Part 'file', size 9 bytes, filename='test.svg' [DEBUG] POST "/article/update_with_post_file", parameters={masked} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post_file(ArticleModel, MultipartFile, HttpServletRequest) ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'} org.springframework.web.multipart.commons.CommonsMultipartFile@7df79c2d 1,算法與數據結構--綜合提高篇(c++版),文章內容 [DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK [DEBUG] Cleaning up part 'file', filename 'test.svg'
[DEBUG] Using MultipartResolver 'multipartResolver' for MultipartFilter [DEBUG] Part 'file', size 20098 bytes, filename='試用期考覈報告-員工版.xlsx' [DEBUG] POST "/article/update_with_post_file", parameters={masked} [DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_post_file(ArticleModel, MultipartFile, HttpServletRequest) ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'} org.springframework.web.multipart.commons.CommonsMultipartFile@448bda6e 1,算法與數據結構--綜合提高篇(c++版),文章內容 [DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors} [DEBUG] Forwarding to [/WEB-INF/views/index.jsp] [DEBUG] Completed 200 OK [DEBUG] Cleaning up part 'file', filename '試用期考覈報告-員工版.xlsx'
在http://localhost:9090/article/1頁面中:
對應show.jsp中內容:
按照上邊新建項目的web.xml、applicationContext.xml、ArticleController.java,提交'Put方式提交:',後臺不能正常接收到參數,此時提交後頁面會跳轉到405錯誤頁面:
服務器打印日誌信息以下:
DEBUG] POST "/article/update_with_put", parameters={masked}
[WARNING] Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
[DEBUG] Completed 405 METHOD_NOT_ALLOWED
[DEBUG] POST "/article/update_with_put", parameters={masked}
[WARNING] Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
[DEBUG] Completed 405 METHOD_NOT_ALLOWED
備註:
1)post不含上傳文件的意思是:form表單中不包含屬性enctype="multipart/form-data"設置。
2)上邊日誌包含兩次提交分別表明/WEB-INF/views/article/show.jsp頁面中「Put方式提交:」下邊的兩個表單提交:第一個表單是jst方式的表單,第二個表單是純html的表單。
從錯誤頁面和日誌來查看,該錯誤緣由是,springmvc默認不能以form post+<input type="hidden" name="_method" value="put"/>方式實現put提交方式。
解決該錯誤的方案:
修改web.xml添加HiddenHtmlMethodFilter filter。
<!-- 注意:HiddenHttpMethodFilter必須做用於dispatcher前 請求method支持 put 和 delete 必須添加該過濾器 做用:能夠過濾全部請求,並能夠分爲四種 使用該過濾器須要在前端頁面加隱藏表單域 <input type="hidden" name="_method" value="請求方式(put/delete)"> post會尋找_method中的請求式是否是put 或者 delete,若是不是 則默認post請求 --> <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <!--servlet爲springMvc的servlet名 --> <servlet-name>myAppServletName</servlet-name> <!--<url-pattern>/*</url-pattern>--> </filter-mapping>
修改web.xml配置以後,從新提交兩個表單,後臺打印結果以下:
[DEBUG] PUT "/article/update_with_put", parameters={masked}
[DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_put(ArticleModel)
ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}
[DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
[DEBUG] Forwarding to [/WEB-INF/views/index.jsp]
[DEBUG] Completed 200 OK
[DEBUG] PUT "/article/update_with_put", parameters={masked}
[DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_put(ArticleModel)
ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}
[DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
[DEBUG] Forwarding to [/WEB-INF/views/index.jsp]
[DEBUG] Completed 200 OK
在http://localhost:9090/article/1頁面中:
對應show.jsp中內容:
由於是上傳文件,並且handler方法使用HttpServletRequest參數,所以須要在pom.xml中引入上傳文件依賴包,和servlet包:
<!-- servlet相關,在handler參數中中包含:HttpServletRequest request參數時,須要引入javax.servlet依賴 <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <!--form 設置爲enctype="multipart/form-data",多文件上傳,在applicationContext.xml中配置了bean multipartResolver時,須要依賴該包。--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>
按照上邊新建項目的web.xml、applicationContext.xml、ArticleController.java,提交'Put方式提交:',後臺不能正常接收到參數,此時提交後頁面會跳轉到405錯誤頁面:
服務器打印日誌信息以下:
DEBUG] POST "/article/update_with_put_file", parameters={masked}
[WARNING] Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
[DEBUG] Completed 405 METHOD_NOT_ALLOWED
[DEBUG] POST "/article/update_with_put_file", parameters={masked}
[WARNING] Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
[DEBUG] Completed 405 METHOD_NOT_ALLOWED
備註:
1)post不含上傳文件的意思是:form表單中不包含屬性enctype="multipart/form-data"設置。
2)上邊日誌包含兩次提交分別表明/WEB-INF/views/article/show.jsp頁面中「Put方式提交:」下邊的兩個表單提交:第一個表單是jst方式的表單,第二個表單是純html的表單。
從錯誤頁面和日誌來查看,該錯誤緣由是,springmvc默認不能以form post+<input type="hidden" name="_method" value="put"/>方式實現put提交方式。
解決該錯誤的方案:
1)爲了實現put方式提交修改web.xml,添加HiddenHtmlMethodFilter filter;
2)爲了實現上傳文件須要修改web.xml,添加filter「MultipartFilter」和引入listener「ContextLoaderListener」;
3)爲了實現上傳文件須要修改applicaitonContext.xml,註冊bean「multipartResolver」。
web.xml修改後內容爲:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>springmvcdemo</display-name> <welcome-file-list> <welcome-file>/index</welcome-file> </welcome-file-list> <!-- 全局初始化數據,spring的監聽器讀取此配置文件,多個配置文件用分號分隔 若是在web.xml中不寫任何參數配置信息,默認的路徑是/WEB-INF/applicationContext.xml,在WEB-INF目錄下建立的xml文件的名稱必須是applicationContext.xml; 若是是要自定義文件名能夠在web.xml里加入contextConfigLocation這個context參數: --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 文件上傳與下載過濾器:form表單中存在文件時,該過濾器能夠處理http請求中的文件,被該過濾器過濾後會用post方法提交,form表單需設爲enctype="multipart/form-data"--> <!-- 注意:必須放在HiddenHttpMethodFilter過濾器以前 --> <filter> <filter-name>MultipartFilter</filter-name> <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> <init-param> <param-name>multipartResolverBeanName</param-name> <!--spring中配置的id爲multipartResolver的解析器--> <param-value>multipartResolver</param-value> </init-param> </filter> <filter-mapping> <filter-name>MultipartFilter</filter-name> <!--<servlet-name>myAppServletName</servlet-name>--> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 注意:HiddenHttpMethodFilter必須做用於dispatcher前 請求method支持 put 和 delete 必須添加該過濾器 做用:能夠過濾全部請求,並能夠分爲四種 使用該過濾器須要在前端頁面加隱藏表單域 <input type="hidden" name="_method" value="請求方式(put/delete)"> post會尋找_method中的請求式是否是put 或者 delete,若是不是 則默認post請求 --> <filter> <filter-name>hiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenHttpMethodFilter</filter-name> <!--servlet爲springMvc的servlet名 --> <servlet-name>myAppServletName</servlet-name> <!--<url-pattern>/*</url-pattern>--> </filter-mapping> <!--結束後端數據輸出到前端亂碼問題--> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> <!--能夠經過配置覆蓋默認'_method'值 --> <init-param> <param-name>methodParam</param-name> <param-value>_method</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>myAppServletName</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>myAppServletName</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
applicationContext.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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--掃描全部的 spring包下的文件;--> <!--固然須要在spring配置文件裏面配置一下自動掃描範圍 <context:component-scan base-package="*"/> *表明你想要掃描的那些包的目錄所在位置。Spring 在容器初始化時將自動掃描 base-package 指定的包及其子包下的全部的.class文件, 全部標註了 @Repository 的類都將被註冊爲 Spring Bean。 --> <context:component-scan base-package="com.dx.test"/> <!--新增長的兩個配置,這個是解決406問題的關鍵--> <!--mvc註解驅動(可代替註解適配器與註解映射器的配置),默認加載不少參數綁定方法(實際開發時使用)--> <context:annotation-config/> <mvc:annotation-driven/> <!-- <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.dx.test.interceptors.LogInterceptor"/> </mvc:interceptor> </mvc:interceptors> --> <!--end--> <!-- <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> <property name="contentType" value="text/html;charset=UTF-8" /> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> </bean> <!-- 配置文件上傳解析器 enctype="multipart/form-data" --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 指定所上傳文件的總大小不能超過20M。注意maxUploadSize屬性的限制不是針對單個文件,而是全部文件的容量之和 --> <property name="maxUploadSize" value="209715200"/> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean> <!--本身後加的,該BeanPostProcessor將自動對標註@Autowired的bean進行注入--> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <property name="messageConverters"> <list> <!--<ref bean="stringHttpMessageConverter"/>--> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/> <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"/> <!-- <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> --> </list> </property> </bean> </beans>
修改後,從新提交兩個表單,此時服務端打印日誌以下:
[DEBUG] Using MultipartResolver 'multipartResolver' for MultipartFilter
[DEBUG] Part 'file', size 1181 bytes, filename='ImageVO.java'
[DEBUG] PUT "/article/update_with_put_file", parameters={masked}
[DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_put_file(ArticleModel, MultipartFile, HttpServletRequest)
ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}
org.springframework.web.multipart.commons.CommonsMultipartFile@62032272
1,算法與數據結構--綜合提高篇(c++版),文章內容
[DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
[DEBUG] Forwarding to [/WEB-INF/views/index.jsp]
[DEBUG] Completed 200 OK
[DEBUG] Cleaning up part 'file', filename 'ImageVO.java'
[DEBUG] Using MultipartResolver 'multipartResolver' for MultipartFilter
[DEBUG] Part 'file', size 1732 bytes, filename='UploadImgParam.java'
[DEBUG] PUT "/article/update_with_put_file", parameters={masked}
[DEBUG] Mapped to com.dx.test.controller.ArticleController#update_with_put_file(ArticleModel, MultipartFile, HttpServletRequest)
ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}
org.springframework.web.multipart.commons.CommonsMultipartFile@32d8a82d
1,算法與數據結構--綜合提高篇(c++版),文章內容
[DEBUG] View name 'index', model {article=ArticleModel{id=1, categoryId=null, title='算法與數據結構--綜合提高篇(c++版)', content='文章內容'}, org.springframework.validation.BindingResult.article=org.springframework.validation.BeanPropertyBindingResult: 0 errors}
[DEBUG] Forwarding to [/WEB-INF/views/index.jsp]
[DEBUG] Completed 200 OK
[DEBUG] Cleaning up part 'file', filename 'UploadImgParam.java'
備註:該web.xml和applicationContext.xml的配置方式,能夠支持post方式提交、post+上傳文件提交、put提交、put+上傳文件提交。所以,推薦使用該配置。
1)爲了實現put方式提交修改web.xml,添加HiddenHtmlMethodFilter filter;
2)爲了實現上傳文件須要修改web.xml,添加filter「MultipartFilter」和引入listener「ContextLoaderListener」;
3)爲了實現上傳文件須要修改applicaitonContext.xml,註冊bean「multipartResolver」。
備註:
1)若是multipartResolver bean配置的是org.springframework.web.multipart.commons.CommonsMultipartResolver,由於CommonsMultipartResolver依賴commons-fileupload.jar和commons-io.jar,因此須要pom.xml引入這兩個包。
2)handler方法使用HttpServletRequest request做爲參數,則須要在pom.xml中引入servlet包。
1)ContextLoaderListener在Web.xml中配置與不配置的區別:
爲何上邊上傳文件方式須要配置它,不配置會致使上傳文件後端接收不到;
它在上傳文件中是否是必須配置的嗎?
2)web.xml 中的 ContextLoaderListener 是幹什麼用的?
3)web.xml 中的 DispatcherServlet 是如何加載的,它其什麼做用?