When building a new project, you want to use the latest stable version of the SPRINGMVC, so choose the latest version
<dependency> <groupId> org.springframework</groupid> <artifactId>spring-webmvc</artifactId> <version>4.3.1.RELEASE</version> <exclusions> <exclusion> <groupid>commons-logging</groupid > <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
And then wrote a very simple controller method with previous experience.
@ResponseBody @RequestMapping (value = "/cates") public Object Cates (@PathVariable long pageId, @PathVariable long mo Duleid, String goodids, Goods Goods) {map<string,object> Map = new hashmap<string, Object> (); Map.put ("1", "1"); return map; }
However, strange things have happened.
Parameter: http://localhost:8088/1/2/cates.json?goodIds=2,3
The runtime goodids is always null, and if parsing with the bean attribute is normal, that is, goods.goodids can parse normally.
My first thought was to add requestparam annotations to Goodids.
@ResponseBody @RequestMapping (value = "/cates") public Object Cates (@PathVariable long pageId, @PathVariable long mo Duleid, @RequestParam (value = "Goodids", required = False) String Goodids, Goods Goods) {Ma p<string,object> map = new hashmap<string, object> (); Map.put ("1", "1"); return map; }
So try, or not, on-line simple search of information, and did not search this situation, can only break point to see where the problem.
Because spring-mvc.xml inside, I wrote dead. Use Requestmappinghandleradapter to handle method-level related operations. Into this class, there is an implementation of the spring initialization object interface
@Overridepublic void afterpropertiesset () {// do this first, it may add responsebody advice beansinitcontrolleradvicecache ();if (this.argumentResolvers == null) {List<HandlerMethodArgumentResolver> resolvers = Getdefaultargumentresolvers ();this.argumentresolvers = new Handlermethodargumentresolvercomposite (). Addresolvers (resolvers);} if (this.initbinderargumentresolvers == null) {List<HandlerMethodArgumentResolver> resolvers = getdefaultinitbinderargumentresolvers (); this.initbinderargumentresolvers = new handlermethodargumentresolvercomposite (). Addresolvers (resolvers);} if (this.returnvaluehandlers == null) {List<HandlerMethodReturnValueHandler> Handlers = getdefaultreturnvaluehandlers ();this.returnvaluehandlers = new Handlermethodreturnvaluehandlercomposite (). AddHandlers (handlers);}}
You can see clearly that the Getdefaultargumentresolvers () method is the default parameter parser.
/** * Return The list of argument resolvers to use including built-in resolvers * and custom resolvers provided via {@link #setCustomArgumentResolvers}. */private list
The entire code of the method is not truncated here, so we focus on
Requestparammethodargumentresolver
This parser, because the code level is too deep, interested students can break the point of their own step-by-step walk, in short, finally can come here to multipartresolutiondelegate.
Ispartcollection is a method parameter used to determine whether a parameter is associated with a file upload.
private static Boolean ispartcollection (Methodparameter methodparam) {return (Servletpartclass = = Getcollectionparametertype (Methodparam));}
private static class<?> Getcollectionparametertype (Methodparameter methodparam) {class<?> ParamType = Methodparam.getnestedparametertype (); if (Collection.class = = Paramtype | | List.class.isAssignableFrom (Paramtype)) {class<?> ValueType = Genericcollectiontyperesolver.getcollectionparametertype (Methodparam); if (valueType! = null) {return valueType;}} return null;}
Since Goodids is a string object, the return of the Getcollectionparametertype method is undoubtedly null, and the final Ispartcollection method returns True, which is no doubt unacceptable to us. For a fine reason, we will find that the Servletpartclass value is null and therefore returns TRUE.
And look at how it's initialized.
/** * a common delegate for {@code handlermethodargumentresolver} implementations * which need to resolve {@ link multipartfile} and {@link Part} arguments. * * @author juergen hoeller * @since 4.3 */public abstract class Multipartresolutiondelegate {public static final object unresolvable = new object ();p rivate static class<?> servletpartclass = null;static {try {servletpartclass = classutils.forname ("Javax.servlet.http.Part", MultipartResolutionDelegate.class.getClassLoader ());} catch (Classnotfoundexception ex) {// Servlet 3.0 javax.servlet.http.Part Type not available -// part references simply not supported then.}}
It should be noted that Multipartresolutiondelegate is spring-web in the 4.3 version, so in some of the lower version of the SPRINGMVC, we are not sure to be able to re-see the way the framework is implemented.
From here you can see that Servletpartclass is an object of type Javax.servlet.http.Part. And the catch block is clearly annotated.
Javax.servlet.http.Part is an object supported by Serlvet 3.0, so to Servletpartclass is not NULL, Should use serlvet3.0 version dependency, so my head is hot, right now SERLVET-API upgraded from 2.5 to 3.0.1
<dependency> <groupId>javax.servlet</groupId> <artifactid>javax.serv Let-api</artifactid> <version>3.0.1</version> <SCOPE>PROVIDED</SC Ope> </dependency>
Now, inside the IDE, you can search for the class Javax.servlet.http.Part and restart the project, however, Servletpartclass is still null and strong null.
Immediately, I remember, start the project with Tomcat6, rushed to think Tomcat6 might not support serlvet3.0 specification.
The TOMCAT7 description of the http://tomcat.apache.org/whichversion.html page of the Tomcat official website, there is a passage
apache tomcat 7.xapache tomcat 7.x builds upon the improvements Made intomcat 6.0.x and implements the servlet 3.0,jsp 2.2, el 2.2 andweb socket 1.1 specifications. in additionto that, it includes the following improvements:Web application memory leak Detection and preventionimproved security for the manager and host manager applicationsgeneric csrf protectionsupport for including external content directly in a web applicationRefactoring (connectors, Lifecycle) and lots of internal code clean-upapache tomcat 6.xapache tomcat 6.x builds upon the improvements made intomcat 5.5.x and implements the seRvlet 2.5 andjsp 2.1 specifications. in addition to that, it includes thefollowing improvements:
tomcat7.x Support serlvet3.0 specification, and TOMCAT6 does not support, download TOMCAT7, after the application, Servletpartclass is not NULL, finally oh, successfully acquired to Goodids
Summarize:
Many new classes are added to the 1.springmvc 4.3 version, such as Multipartresolutiondelegate, which are implemented based on the Servlet 3.0 specification. If you use the old serlvet2.5 specification, it doesn't work, and Tomcat needs to support serlvet3.0 at the same time, and the minimum version of Tomcat needs to be 7.x.
2. In fact, when looking at the MAVEN version of spring mvc 4.3 dependency, there is this dependency
<dependency> <groupId>javax.servlet</groupId> <artifactid>javax.servlet-api</artifact id> <version>3.0.1</version> <scope>provided</scope> </dependency>
It is not written to play, which means that, to use spring mvc 4.3, you should use the SERLVET3.0 specification, tomcat using at least 7.x
The 3.MultipartResolutionDelegate itself is an abstract class used to parse the method parameters that determine the Multipartfile and part types, and if you cannot get to the part type object, you cannot properly perform the functions it should have. In the use of new tools or versions, it is inevitable that there will be incomprehensible things, find the reason, the analysis of the solution will have a sense of the enlightened
This article is from the "Bathing Mood" blog, please be sure to keep this source http://lj3331.blog.51cto.com/5679179/1825283
SPRINGMVC 4.3,requestparammethodargumentresolver Unable to resolve string parameter problems correctly