moved multipart and bind to web project since independent of servlet and required by new native web request parameter map

This commit is contained in:
Keith Donald 2009-07-31 04:10:22 +00:00
parent 9eb85af234
commit d456a9326e
64 changed files with 63 additions and 7372 deletions

View File

@ -1,52 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.aop"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.context"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.context.support"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.orm"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.oxm"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web"/>
<classpathentry kind="var" path="IVY_CACHE/com.lowagie.text/com.springsource.com.lowagie.text/2.0.8/com.springsource.com.lowagie.text-2.0.8.jar" sourcepath="/IVY_CACHE/com.lowagie.text/com.springsource.com.lowagie.text/2.0.8/com.springsource.com.lowagie.text-sources-2.0.8.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.sun.syndication/com.springsource.com.sun.syndication/1.0.0/com.springsource.com.sun.syndication-1.0.0.jar" sourcepath="/IVY_CACHE/com.sun.syndication/com.springsource.com.sun.syndication/1.0.0/com.springsource.com.sun.syndication-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-1.1.0.jar" sourcepath="/IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-1.0.0.jar" sourcepath="/IVY_CACHE/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-sources-1.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-2.1.0.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-sources-2.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-2.5.0.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-sources-2.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.jasperreports/com.springsource.net.sf.jasperreports/2.0.5/com.springsource.net.sf.jasperreports-2.0.5.jar" sourcepath="/IVY_CACHE/net.sourceforge.jasperreports/com.springsource.net.sf.jasperreports/2.0.5/com.springsource.net.sf.jasperreports-sources-2.0.5.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.jexcelapi/com.springsource.jxl/2.6.6/com.springsource.jxl-2.6.6.jar" sourcepath="/IVY_CACHE/net.sourceforge.jexcelapi/com.springsource.jxl/2.6.6/com.springsource.jxl-sources-2.6.6.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.fileupload/1.2.0/com.springsource.org.apache.commons.fileupload-1.2.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.fileupload/1.2.0/com.springsource.org.apache.commons.fileupload-sources-1.2.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-2.1.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-sources-2.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.poi/com.springsource.org.apache.poi/3.0.2.FINAL/com.springsource.org.apache.poi-3.0.2.FINAL.jar" sourcepath="/IVY_CACHE/org.apache.poi/com.springsource.org.apache.poi/3.0.2.FINAL/com.springsource.org.apache.poi-sources-3.0.2.FINAL.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-1.1.2.jar" sourcepath="/IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-sources-1.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity.tools.view/1.4.0/com.springsource.org.apache.velocity.tools.view-1.4.0.jar" sourcepath="/IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity.tools.view/1.4.0/com.springsource.org.apache.velocity.tools.view-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity/1.5.0/com.springsource.org.apache.velocity-1.5.0.jar" sourcepath="/IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity/1.5.0/com.springsource.org.apache.velocity-sources-1.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.0.0/com.springsource.org.codehaus.jackson.mapper-1.0.0.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.0.0/com.springsource.org.codehaus.jackson.mapper-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.0.0/com.springsource.org.codehaus.jackson-1.0.0.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.0.0/com.springsource.org.codehaus.jackson-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-1.2.0.jar" sourcepath="/IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-sources-1.2.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-1.6.1.jar" sourcepath="/IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-sources-1.6.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.freemarker/com.springsource.freemarker/2.3.15/com.springsource.freemarker-2.3.15.jar" sourcepath="/IVY_CACHE/org.freemarker/com.springsource.freemarker/2.3.15/com.springsource.freemarker-sources-2.3.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jaxen/com.springsource.org.jaxen/1.1.1/com.springsource.org.jaxen-1.1.1.jar" sourcepath="/IVY_CACHE/org.jaxen/com.springsource.org.jaxen/1.1.1/com.springsource.org.jaxen-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jdom/com.springsource.org.jdom/1.0.0/com.springsource.org.jdom-1.0.0.jar" sourcepath="/IVY_CACHE/org.jdom/com.springsource.org.jdom/1.0.0/com.springsource.org.jdom-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.6.0/com.springsource.org.junit-4.6.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.6.0/com.springsource.org.junit-sources-4.6.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.mozilla.javascript/com.springsource.org.mozilla.javascript/1.7.0.R2/com.springsource.org.mozilla.javascript-1.7.0.R2.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.transaction"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.jdbc"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.3.1.GA/com.springsource.org.hibernate-3.3.1.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-1.1.0.jar" sourcepath="/IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles/2.1.2.osgi/com.springsource.org.apache.tiles-2.1.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.core/2.1.2.osgi/com.springsource.org.apache.tiles.core-2.1.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.jsp/2.1.2/com.springsource.org.apache.tiles.jsp-2.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.servlet/2.1.2/com.springsource.org.apache.tiles.servlet-2.1.2.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.aop"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.beans"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.context"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.context.support"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.core"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.jdbc"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.orm"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.oxm"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.transaction"/>
<classpathentry combineaccessrules="false" kind="src" path="/org.springframework.web"/>
<classpathentry kind="var" path="IVY_CACHE/com.lowagie.text/com.springsource.com.lowagie.text/2.0.8/com.springsource.com.lowagie.text-2.0.8.jar" sourcepath="/IVY_CACHE/com.lowagie.text/com.springsource.com.lowagie.text/2.0.8/com.springsource.com.lowagie.text-sources-2.0.8.jar"/>
<classpathentry kind="var" path="IVY_CACHE/com.sun.syndication/com.springsource.com.sun.syndication/1.0.0/com.springsource.com.sun.syndication-1.0.0.jar" sourcepath="/IVY_CACHE/com.sun.syndication/com.springsource.com.sun.syndication/1.0.0/com.springsource.com.sun.syndication-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-1.1.0.jar" sourcepath="/IVY_CACHE/javax.activation/com.springsource.javax.activation/1.1.0/com.springsource.javax.activation-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-1.0.0.jar" sourcepath="/IVY_CACHE/javax.el/com.springsource.javax.el/1.0.0/com.springsource.javax.el-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-sources-1.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-2.1.0.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-sources-2.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-2.5.0.jar" sourcepath="/IVY_CACHE/javax.servlet/com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-sources-2.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.jasperreports/com.springsource.net.sf.jasperreports/2.0.5/com.springsource.net.sf.jasperreports-2.0.5.jar" sourcepath="/IVY_CACHE/net.sourceforge.jasperreports/com.springsource.net.sf.jasperreports/2.0.5/com.springsource.net.sf.jasperreports-sources-2.0.5.jar"/>
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.jexcelapi/com.springsource.jxl/2.6.6/com.springsource.jxl-2.6.6.jar" sourcepath="/IVY_CACHE/net.sourceforge.jexcelapi/com.springsource.jxl/2.6.6/com.springsource.jxl-sources-2.6.6.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar" sourcepath="/IVY_CACHE/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.fileupload/1.2.0/com.springsource.org.apache.commons.fileupload-1.2.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.fileupload/1.2.0/com.springsource.org.apache.commons.fileupload-sources-1.2.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-2.1.0.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-sources-2.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar" sourcepath="/IVY_CACHE/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.poi/com.springsource.org.apache.poi/3.0.2.FINAL/com.springsource.org.apache.poi-3.0.2.FINAL.jar" sourcepath="/IVY_CACHE/org.apache.poi/com.springsource.org.apache.poi/3.0.2.FINAL/com.springsource.org.apache.poi-sources-3.0.2.FINAL.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-1.1.2.jar" sourcepath="/IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-sources-1.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity.tools.view/1.4.0/com.springsource.org.apache.velocity.tools.view-1.4.0.jar" sourcepath="/IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity.tools.view/1.4.0/com.springsource.org.apache.velocity.tools.view-sources-1.4.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity/1.5.0/com.springsource.org.apache.velocity-1.5.0.jar" sourcepath="/IVY_CACHE/org.apache.velocity/com.springsource.org.apache.velocity/1.5.0/com.springsource.org.apache.velocity-sources-1.5.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.0.0/com.springsource.org.codehaus.jackson.mapper-1.0.0.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.0.0/com.springsource.org.codehaus.jackson.mapper-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.0.0/com.springsource.org.codehaus.jackson-1.0.0.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.0.0/com.springsource.org.codehaus.jackson-sources-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-1.2.0.jar" sourcepath="/IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-sources-1.2.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-1.6.1.jar" sourcepath="/IVY_CACHE/org.dom4j/com.springsource.org.dom4j/1.6.1/com.springsource.org.dom4j-sources-1.6.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.freemarker/com.springsource.freemarker/2.3.15/com.springsource.freemarker-2.3.15.jar" sourcepath="/IVY_CACHE/org.freemarker/com.springsource.freemarker/2.3.15/com.springsource.freemarker-sources-2.3.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jaxen/com.springsource.org.jaxen/1.1.1/com.springsource.org.jaxen-1.1.1.jar" sourcepath="/IVY_CACHE/org.jaxen/com.springsource.org.jaxen/1.1.1/com.springsource.org.jaxen-sources-1.1.1.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jdom/com.springsource.org.jdom/1.0.0/com.springsource.org.jdom-1.0.0.jar" sourcepath="/IVY_CACHE/org.jdom/com.springsource.org.jdom/1.0.0/com.springsource.org.jdom-1.0.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.6.0/com.springsource.org.junit-4.6.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.6.0/com.springsource.org.junit-sources-4.6.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.mozilla.javascript/com.springsource.org.mozilla.javascript/1.7.0.R2/com.springsource.org.mozilla.javascript-1.7.0.R2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.3.1.GA/com.springsource.org.hibernate-3.3.1.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-1.1.0.jar" sourcepath="/IVY_CACHE/javax.transaction/com.springsource.javax.transaction/1.1.0/com.springsource.javax.transaction-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles/2.1.2.osgi/com.springsource.org.apache.tiles-2.1.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.core/2.1.2.osgi/com.springsource.org.apache.tiles.core-2.1.2.osgi.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.jsp/2.1.2/com.springsource.org.apache.tiles.jsp-2.1.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.tiles/com.springsource.org.apache.tiles.servlet/2.1.2/com.springsource.org.apache.tiles.servlet-2.1.2.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -12,7 +12,6 @@
<configurations>
<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
<conf name="commons-attributes" extends="runtime" description="JARs needed to run with Commons Attributes"/>
<conf name="commons-fileupload" extends="runtime" description="JARs needed to run with Commons Fileupload"/>
<conf name="feed" extends="runtime" description="JARs needed to create beans for Atom and RSS feeds"/>
<conf name="freemarker" extends="runtime" description="JARs needed to create beans for Freemarker"/>
<conf name="itext" extends="runtime" description="JARs needed to create beans for iText"/>
@ -47,8 +46,6 @@
conf="optional, jexcelapi->compile"/>
<dependency org="net.sourceforge.jasperreports" name="com.springsource.net.sf.jasperreports" rev="2.0.5"
conf="optional, jasper-reports->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.fileupload" rev="1.2.0"
conf="optional, commons-fileupload->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1"
conf="compile->compile"/>
<dependency org="org.apache.poi" name="com.springsource.org.apache.poi" rev="3.0.2.FINAL"
@ -79,9 +76,11 @@
conf="optional, oxm->compile"/>
<dependency org="org.springframework" name="org.springframework.web" rev="latest.integration"
conf="compile->compile"/>
<!-- test dependencies -->
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.6.0" conf="test->runtime"/>
<!-- test dependencies -->
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.6.0" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.fileupload" rev="1.2.0"
conf="test->compile"/>
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration"
conf="test->compile"/>
<dependency org="org.custommonkey.xmlunit" name="com.springsource.org.custommonkey.xmlunit" rev="1.2.0"

View File

@ -72,12 +72,6 @@
<version>2.0.5</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
@ -182,6 +176,12 @@
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>

View File

@ -1,211 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import java.util.ArrayList;
import java.util.List;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.util.HtmlUtils;
/**
* Errors wrapper that adds automatic HTML escaping to the wrapped instance,
* for convenient usage in HTML views. Can be retrieved easily via
* RequestContext's <code>getErrors</code> method.
*
* <p>Note that BindTag does <i>not</i> use this class to avoid unnecessary
* creation of ObjectError instances. It just escapes the messages and values
* that get copied into the respective BindStatus instance.
*
* @author Juergen Hoeller
* @since 01.03.2003
* @see org.springframework.web.servlet.support.RequestContext#getErrors
* @see org.springframework.web.servlet.tags.BindTag
*/
public class EscapedErrors implements Errors {
private final Errors source;
/**
* Create a new EscapedErrors instance for the given source instance.
*/
public EscapedErrors(Errors source) {
if (source == null) {
throw new IllegalArgumentException("Cannot wrap a null instance");
}
this.source = source;
}
public Errors getSource() {
return this.source;
}
public String getObjectName() {
return this.source.getObjectName();
}
public void setNestedPath(String nestedPath) {
this.source.setNestedPath(nestedPath);
}
public String getNestedPath() {
return this.source.getNestedPath();
}
public void pushNestedPath(String subPath) {
this.source.pushNestedPath(subPath);
}
public void popNestedPath() throws IllegalStateException {
this.source.popNestedPath();
}
public void reject(String errorCode) {
this.source.reject(errorCode);
}
public void reject(String errorCode, String defaultMessage) {
this.source.reject(errorCode, defaultMessage);
}
public void reject(String errorCode, Object[] errorArgs, String defaultMessage) {
this.source.reject(errorCode, errorArgs, defaultMessage);
}
public void rejectValue(String field, String errorCode) {
this.source.rejectValue(field, errorCode);
}
public void rejectValue(String field, String errorCode, String defaultMessage) {
this.source.rejectValue(field, errorCode, defaultMessage);
}
public void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage) {
this.source.rejectValue(field, errorCode, errorArgs, defaultMessage);
}
public void addAllErrors(Errors errors) {
this.source.addAllErrors(errors);
}
public boolean hasErrors() {
return this.source.hasErrors();
}
public int getErrorCount() {
return this.source.getErrorCount();
}
public List<ObjectError> getAllErrors() {
return escapeObjectErrors(this.source.getAllErrors());
}
public boolean hasGlobalErrors() {
return this.source.hasGlobalErrors();
}
public int getGlobalErrorCount() {
return this.source.getGlobalErrorCount();
}
public List<ObjectError> getGlobalErrors() {
return escapeObjectErrors(this.source.getGlobalErrors());
}
public ObjectError getGlobalError() {
return escapeObjectError(this.source.getGlobalError());
}
public boolean hasFieldErrors() {
return this.source.hasFieldErrors();
}
public int getFieldErrorCount() {
return this.source.getFieldErrorCount();
}
public List<FieldError> getFieldErrors() {
return this.source.getFieldErrors();
}
public FieldError getFieldError() {
return this.source.getFieldError();
}
public boolean hasFieldErrors(String field) {
return this.source.hasFieldErrors(field);
}
public int getFieldErrorCount(String field) {
return this.source.getFieldErrorCount(field);
}
public List<FieldError> getFieldErrors(String field) {
return escapeObjectErrors(this.source.getFieldErrors(field));
}
public FieldError getFieldError(String field) {
return escapeObjectError(this.source.getFieldError(field));
}
public Object getFieldValue(String field) {
Object value = this.source.getFieldValue(field);
return (value instanceof String ? HtmlUtils.htmlEscape((String) value) : value);
}
public Class getFieldType(String field) {
return this.source.getFieldType(field);
}
@SuppressWarnings("unchecked")
private <T extends ObjectError> T escapeObjectError(T source) {
if (source == null) {
return null;
}
if (source instanceof FieldError) {
FieldError fieldError = (FieldError) source;
Object value = fieldError.getRejectedValue();
if (value instanceof String) {
value = HtmlUtils.htmlEscape((String) value);
}
return (T) new FieldError(
fieldError.getObjectName(), fieldError.getField(), value,
fieldError.isBindingFailure(), fieldError.getCodes(),
fieldError.getArguments(), HtmlUtils.htmlEscape(fieldError.getDefaultMessage()));
}
else {
return (T) new ObjectError(
source.getObjectName(), source.getCodes(), source.getArguments(),
HtmlUtils.htmlEscape(source.getDefaultMessage()));
}
}
private <T extends ObjectError> List<T> escapeObjectErrors(List<T> source) {
List<T> escaped = new ArrayList<T>(source.size());
for (T objectError : source) {
escaped.add(escapeObjectError(objectError));
}
return escaped;
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
/**
* {@link ServletRequestBindingException} subclass that indicates a missing parameter.
*
* @author Juergen Hoeller
* @since 2.0.2
*/
public class MissingServletRequestParameterException extends ServletRequestBindingException {
private final String parameterName;
private final String parameterType;
/**
* Constructor for MissingServletRequestParameterException.
* @param parameterName the name of the missing parameter
* @param parameterType the expected type of the missing parameter
*/
public MissingServletRequestParameterException(String parameterName, String parameterType) {
super("");
this.parameterName = parameterName;
this.parameterType = parameterType;
}
@Override
public String getMessage() {
return "Required " + this.parameterType + " parameter '" + this.parameterName + "' is not present";
}
/**
* Return the name of the offending parameter.
*/
public final String getParameterName() {
return this.parameterName;
}
/**
* Return the expected type of the offending parameter.
*/
public final String getParameterType() {
return this.parameterType;
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import org.springframework.web.util.NestedServletException;
/**
* Fatal binding exception, thrown when we want to
* treat binding exceptions as unrecoverable.
*
* <p>Extends ServletException for convenient throwing in any Servlet resource
* (such as a Filter), and NestedServletException for proper root cause handling
* (as the plain ServletException doesn't expose its root cause at all).
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ServletRequestBindingException extends NestedServletException {
/**
* Constructor for ServletRequestBindingException.
* @param msg the detail message
*/
public ServletRequestBindingException(String msg) {
super(msg);
}
/**
* Constructor for ServletRequestBindingException.
* @param msg the detail message
* @param cause the root cause
*/
public ServletRequestBindingException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import javax.servlet.ServletRequest;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.validation.BindException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
* Special {@link org.springframework.validation.DataBinder} to perform data binding
* from servlet request parameters to JavaBeans, including support for multipart files.
*
* <p>See the DataBinder/WebDataBinder superclasses for customization options,
* which include specifying allowed/required fields, and registering custom
* property editors.
*
* <p>Used by Spring Web MVC's BaseCommandController and MultiActionController.
* Note that BaseCommandController and its subclasses allow for easy customization
* of the binder instances that they use through overriding <code>initBinder</code>.
*
* <p>Can also be used for manual data binding in custom web controllers:
* for example, in a plain Controller implementation or in a MultiActionController
* handler method. Simply instantiate a ServletRequestDataBinder for each binding
* process, and invoke <code>bind</code> with the current ServletRequest as argument:
*
* <pre class="code">
* MyBean myBean = new MyBean();
* // apply binder to custom target object
* ServletRequestDataBinder binder = new ServletRequestDataBinder(myBean);
* // register custom editors, if desired
* binder.registerCustomEditor(...);
* // trigger actual binding of request parameters
* binder.bind(request);
* // optionally evaluate binding errors
* Errors errors = binder.getErrors();
* ...</pre>
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see #bind(javax.servlet.ServletRequest)
* @see #registerCustomEditor
* @see #setAllowedFields
* @see #setRequiredFields
* @see #setFieldMarkerPrefix
* @see org.springframework.web.servlet.mvc.BaseCommandController#initBinder
*/
public class ServletRequestDataBinder extends WebDataBinder {
/**
* Create a new ServletRequestDataBinder instance, with default object name.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @see #DEFAULT_OBJECT_NAME
*/
public ServletRequestDataBinder(Object target) {
super(target);
}
/**
* Create a new ServletRequestDataBinder instance.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public ServletRequestDataBinder(Object target, String objectName) {
super(target, objectName);
}
/**
* Bind the parameters of the given request to this binder's target,
* also binding multipart files in case of a multipart request.
* <p>This call can create field errors, representing basic binding
* errors like a required field (code "required"), or type mismatch
* between value and bean property (code "typeMismatch").
* <p>Multipart files are bound via their parameter name, just like normal
* HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property,
* invoking a "setUploadedFile" setter method.
* <p>The type of the target property for a multipart file can be MultipartFile,
* byte[], or String. The latter two receive the contents of the uploaded file;
* all metadata like original file name, content type, etc are lost in those cases.
* @param request request with parameters to bind (can be multipart)
* @see org.springframework.web.multipart.MultipartHttpServletRequest
* @see org.springframework.web.multipart.MultipartFile
* @see #bindMultipartFiles
* @see #bind(org.springframework.beans.PropertyValues)
*/
public void bind(ServletRequest request) {
MutablePropertyValues mpvs = new ServletRequestParameterPropertyValues(request);
if (request instanceof MultipartHttpServletRequest) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
bindMultipartFiles(multipartRequest.getFileMap(), mpvs);
}
doBind(mpvs);
}
/**
* Treats errors as fatal.
* <p>Use this method only if it's an error if the input isn't valid.
* This might be appropriate if all input is from dropdowns, for example.
* @throws ServletRequestBindingException subclass of ServletException on any binding problem
*/
public void closeNoCatch() throws ServletRequestBindingException {
if (getBindingResult().hasErrors()) {
throw new ServletRequestBindingException(
"Errors binding onto object '" + getBindingResult().getObjectName() + "'",
new BindException(getBindingResult()));
}
}
}

View File

@ -1,80 +0,0 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import javax.servlet.ServletRequest;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.web.util.WebUtils;
/**
* PropertyValues implementation created from parameters in a ServletRequest.
* Can look for all property values beginning with a certain prefix and
* prefix separator (default is "_").
*
* <p>For example, with a prefix of "spring", "spring_param1" and
* "spring_param2" result in a Map with "param1" and "param2" as keys.
*
* <p>This class is not immutable to be able to efficiently remove property
* values that should be ignored for binding.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see org.springframework.web.util.WebUtils#getParametersStartingWith
*/
public class ServletRequestParameterPropertyValues extends MutablePropertyValues {
/** Default prefix separator */
public static final String DEFAULT_PREFIX_SEPARATOR = "_";
/**
* Create new ServletRequestPropertyValues using no prefix
* (and hence, no prefix separator).
* @param request HTTP request
*/
public ServletRequestParameterPropertyValues(ServletRequest request) {
this(request, null, null);
}
/**
* Create new ServletRequestPropertyValues using the given prefix and
* the default prefix separator (the underscore character "_").
* @param request HTTP request
* @param prefix the prefix for parameters (the full prefix will
* consist of this plus the separator)
* @see #DEFAULT_PREFIX_SEPARATOR
*/
public ServletRequestParameterPropertyValues(ServletRequest request, String prefix) {
this(request, prefix, DEFAULT_PREFIX_SEPARATOR);
}
/**
* Create new ServletRequestPropertyValues supplying both prefix and
* prefix separator.
* @param request HTTP request
* @param prefix the prefix for parameters (the full prefix will
* consist of this plus the separator)
* @param prefixSeparator separator delimiting prefix (e.g. "spring")
* and the rest of the parameter name ("param1", "param2")
*/
public ServletRequestParameterPropertyValues(ServletRequest request, String prefix, String prefixSeparator) {
super(WebUtils.getParametersStartingWith(
request, (prefix != null) ? prefix + prefixSeparator : null));
}
}

View File

@ -1,709 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import javax.servlet.ServletRequest;
/**
* Parameter extraction methods, for an approach distinct from data binding,
* in which parameters of specific types are required.
*
* <p>This approach is very useful for simple submissions, where binding
* request parameters to a command object would be overkill.
*
* @author Juergen Hoeller
* @author Keith Donald
* @since 2.0
*/
public abstract class ServletRequestUtils {
private static final IntParser INT_PARSER = new IntParser();
private static final LongParser LONG_PARSER = new LongParser();
private static final FloatParser FLOAT_PARSER = new FloatParser();
private static final DoubleParser DOUBLE_PARSER = new DoubleParser();
private static final BooleanParser BOOLEAN_PARSER = new BooleanParser();
private static final StringParser STRING_PARSER = new StringParser();
/**
* Get an Integer parameter, or <code>null</code> if not present.
* Throws an exception if it the parameter value isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @return the Integer value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static Integer getIntParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return getRequiredIntParameter(request, name);
}
/**
* Get an int parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value as default to enable checks of whether it was supplied.
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static int getIntParameter(ServletRequest request, String name, int defaultVal) {
if (request.getParameter(name) == null) {
return defaultVal;
}
try {
return getRequiredIntParameter(request, name);
}
catch (ServletRequestBindingException ex) {
return defaultVal;
}
}
/**
* Get an array of int parameters, return an empty array if not found.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static int[] getIntParameters(ServletRequest request, String name) {
try {
return getRequiredIntParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new int[0];
}
}
/**
* Get an int parameter, throwing an exception if it isn't found or isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static int getRequiredIntParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return INT_PARSER.parseInt(name, request.getParameter(name));
}
/**
* Get an array of int parameters, throwing an exception if not found or one is not a number..
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static int[] getRequiredIntParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return INT_PARSER.parseInts(name, request.getParameterValues(name));
}
/**
* Get a Long parameter, or <code>null</code> if not present.
* Throws an exception if it the parameter value isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @return the Long value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static Long getLongParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return getRequiredLongParameter(request, name);
}
/**
* Get a long parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value as default to enable checks of whether it was supplied.
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static long getLongParameter(ServletRequest request, String name, long defaultVal) {
if (request.getParameter(name) == null) {
return defaultVal;
}
try {
return getRequiredLongParameter(request, name);
}
catch (ServletRequestBindingException ex) {
return defaultVal;
}
}
/**
* Get an array of long parameters, return an empty array if not found.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static long[] getLongParameters(ServletRequest request, String name) {
try {
return getRequiredLongParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new long[0];
}
}
/**
* Get a long parameter, throwing an exception if it isn't found or isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static long getRequiredLongParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return LONG_PARSER.parseLong(name, request.getParameter(name));
}
/**
* Get an array of long parameters, throwing an exception if not found or one is not a number.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static long[] getRequiredLongParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return LONG_PARSER.parseLongs(name, request.getParameterValues(name));
}
/**
* Get a Float parameter, or <code>null</code> if not present.
* Throws an exception if it the parameter value isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @return the Float value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static Float getFloatParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return getRequiredFloatParameter(request, name);
}
/**
* Get a float parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value as default to enable checks of whether it was supplied.
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static float getFloatParameter(ServletRequest request, String name, float defaultVal) {
if (request.getParameter(name) == null) {
return defaultVal;
}
try {
return getRequiredFloatParameter(request, name);
}
catch (ServletRequestBindingException ex) {
return defaultVal;
}
}
/**
* Get an array of float parameters, return an empty array if not found.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static float[] getFloatParameters(ServletRequest request, String name) {
try {
return getRequiredFloatParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new float[0];
}
}
/**
* Get a float parameter, throwing an exception if it isn't found or isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static float getRequiredFloatParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return FLOAT_PARSER.parseFloat(name, request.getParameter(name));
}
/**
* Get an array of float parameters, throwing an exception if not found or one is not a number.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static float[] getRequiredFloatParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return FLOAT_PARSER.parseFloats(name, request.getParameterValues(name));
}
/**
* Get a Double parameter, or <code>null</code> if not present.
* Throws an exception if it the parameter value isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @return the Double value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static Double getDoubleParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return getRequiredDoubleParameter(request, name);
}
/**
* Get a double parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value as default to enable checks of whether it was supplied.
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static double getDoubleParameter(ServletRequest request, String name, double defaultVal) {
if (request.getParameter(name) == null) {
return defaultVal;
}
try {
return getRequiredDoubleParameter(request, name);
}
catch (ServletRequestBindingException ex) {
return defaultVal;
}
}
/**
* Get an array of double parameters, return an empty array if not found.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static double[] getDoubleParameters(ServletRequest request, String name) {
try {
return getRequiredDoubleParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new double[0];
}
}
/**
* Get a double parameter, throwing an exception if it isn't found or isn't a number.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static double getRequiredDoubleParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return DOUBLE_PARSER.parseDouble(name, request.getParameter(name));
}
/**
* Get an array of double parameters, throwing an exception if not found or one is not a number.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static double[] getRequiredDoubleParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return DOUBLE_PARSER.parseDoubles(name, request.getParameterValues(name));
}
/**
* Get a Boolean parameter, or <code>null</code> if not present.
* Throws an exception if it the parameter value isn't a boolean.
* <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
* treats every other non-empty value as false (i.e. parses leniently).
* @param request current HTTP request
* @param name the name of the parameter
* @return the Boolean value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static Boolean getBooleanParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return (getRequiredBooleanParameter(request, name));
}
/**
* Get a boolean parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value as default to enable checks of whether it was supplied.
* <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
* treats every other non-empty value as false (i.e. parses leniently).
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static boolean getBooleanParameter(ServletRequest request, String name, boolean defaultVal) {
if (request.getParameter(name) == null) {
return defaultVal;
}
try {
return getRequiredBooleanParameter(request, name);
}
catch (ServletRequestBindingException ex) {
return defaultVal;
}
}
/**
* Get an array of boolean parameters, return an empty array if not found.
* <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
* treats every other non-empty value as false (i.e. parses leniently).
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static boolean[] getBooleanParameters(ServletRequest request, String name) {
try {
return getRequiredBooleanParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new boolean[0];
}
}
/**
* Get a boolean parameter, throwing an exception if it isn't found
* or isn't a boolean.
* <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
* treats every other non-empty value as false (i.e. parses leniently).
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static boolean getRequiredBooleanParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return BOOLEAN_PARSER.parseBoolean(name, request.getParameter(name));
}
/**
* Get an array of boolean parameters, throwing an exception if not found
* or one isn't a boolean.
* <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
* treats every other non-empty value as false (i.e. parses leniently).
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static boolean[] getRequiredBooleanParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return BOOLEAN_PARSER.parseBooleans(name, request.getParameterValues(name));
}
/**
* Get a String parameter, or <code>null</code> if not present.
* @param request current HTTP request
* @param name the name of the parameter
* @return the String value, or <code>null</code> if not present
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static String getStringParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
if (request.getParameter(name) == null) {
return null;
}
return getRequiredStringParameter(request, name);
}
/**
* Get a String parameter, with a fallback value. Never throws an exception.
* Can pass a distinguished value to default to enable checks of whether it was supplied.
* @param request current HTTP request
* @param name the name of the parameter
* @param defaultVal the default value to use as fallback
*/
public static String getStringParameter(ServletRequest request, String name, String defaultVal) {
String val = request.getParameter(name);
return (val != null ? val : defaultVal);
}
/**
* Get an array of String parameters, return an empty array if not found.
* @param request current HTTP request
* @param name the name of the parameter with multiple possible values
*/
public static String[] getStringParameters(ServletRequest request, String name) {
try {
return getRequiredStringParameters(request, name);
}
catch (ServletRequestBindingException ex) {
return new String[0];
}
}
/**
* Get a String parameter, throwing an exception if it isn't found.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static String getRequiredStringParameter(ServletRequest request, String name)
throws ServletRequestBindingException {
return STRING_PARSER.validateRequiredString(name, request.getParameter(name));
}
/**
* Get an array of String parameters, throwing an exception if not found.
* @param request current HTTP request
* @param name the name of the parameter
* @throws ServletRequestBindingException a subclass of ServletException,
* so it doesn't need to be caught
*/
public static String[] getRequiredStringParameters(ServletRequest request, String name)
throws ServletRequestBindingException {
return STRING_PARSER.validateRequiredStrings(name, request.getParameterValues(name));
}
private abstract static class ParameterParser<T> {
protected final T parse(String name, String parameter) throws ServletRequestBindingException {
validateRequiredParameter(name, parameter);
try {
return doParse(parameter);
}
catch (NumberFormatException ex) {
throw new ServletRequestBindingException(
"Required " + getType() + " parameter '" + name + "' with value of '" +
parameter + "' is not a valid number", ex);
}
}
protected final void validateRequiredParameter(String name, Object parameter)
throws ServletRequestBindingException {
if (parameter == null) {
throw new MissingServletRequestParameterException(name, getType());
}
}
protected abstract String getType();
protected abstract T doParse(String parameter) throws NumberFormatException;
}
private static class IntParser extends ParameterParser<Integer> {
@Override
protected String getType() {
return "int";
}
@Override
protected Integer doParse(String s) throws NumberFormatException {
return Integer.valueOf(s);
}
public int parseInt(String name, String parameter) throws ServletRequestBindingException {
return parse(name, parameter);
}
public int[] parseInts(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
int[] parameters = new int[values.length];
for (int i = 0; i < values.length; i++) {
parameters[i] = parseInt(name, values[i]);
}
return parameters;
}
}
private static class LongParser extends ParameterParser<Long> {
@Override
protected String getType() {
return "long";
}
@Override
protected Long doParse(String parameter) throws NumberFormatException {
return Long.valueOf(parameter);
}
public long parseLong(String name, String parameter) throws ServletRequestBindingException {
return parse(name, parameter);
}
public long[] parseLongs(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
long[] parameters = new long[values.length];
for (int i = 0; i < values.length; i++) {
parameters[i] = parseLong(name, values[i]);
}
return parameters;
}
}
private static class FloatParser extends ParameterParser<Float> {
@Override
protected String getType() {
return "float";
}
@Override
protected Float doParse(String parameter) throws NumberFormatException {
return Float.valueOf(parameter);
}
public float parseFloat(String name, String parameter) throws ServletRequestBindingException {
return parse(name, parameter);
}
public float[] parseFloats(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
float[] parameters = new float[values.length];
for (int i = 0; i < values.length; i++) {
parameters[i] = parseFloat(name, values[i]);
}
return parameters;
}
}
private static class DoubleParser extends ParameterParser<Double> {
@Override
protected String getType() {
return "double";
}
@Override
protected Double doParse(String parameter) throws NumberFormatException {
return Double.valueOf(parameter);
}
public double parseDouble(String name, String parameter) throws ServletRequestBindingException {
return parse(name, parameter);
}
public double[] parseDoubles(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
double[] parameters = new double[values.length];
for (int i = 0; i < values.length; i++) {
parameters[i] = parseDouble(name, values[i]);
}
return parameters;
}
}
private static class BooleanParser extends ParameterParser<Boolean> {
@Override
protected String getType() {
return "boolean";
}
@Override
protected Boolean doParse(String parameter) throws NumberFormatException {
return (parameter.equalsIgnoreCase("true") || parameter.equalsIgnoreCase("on") ||
parameter.equalsIgnoreCase("yes") || parameter.equals("1"));
}
public boolean parseBoolean(String name, String parameter) throws ServletRequestBindingException {
return parse(name, parameter);
}
public boolean[] parseBooleans(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
boolean[] parameters = new boolean[values.length];
for (int i = 0; i < values.length; i++) {
parameters[i] = parseBoolean(name, values[i]);
}
return parameters;
}
}
private static class StringParser extends ParameterParser<String> {
@Override
protected String getType() {
return "string";
}
@Override
protected String doParse(String parameter) throws NumberFormatException {
return parameter;
}
public String validateRequiredString(String name, String value) throws ServletRequestBindingException {
validateRequiredParameter(name, value);
return value;
}
public String[] validateRequiredStrings(String name, String[] values) throws ServletRequestBindingException {
validateRequiredParameter(name, values);
for (String value : values) {
validateRequiredParameter(name, value);
}
return values;
}
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import java.util.Iterator;
import java.util.Map;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* {@link ServletRequestBindingException} subclass that indicates an unsatisfied
* parameter condition, as typically expressed using an <code>@RequestMapping</code>
* annotation at the <code>@Controller</code> type level.
*
* @author Juergen Hoeller
* @since 3.0
* @see org.springframework.web.bind.annotation.RequestMapping#params()
*/
public class UnsatisfiedServletRequestParameterException extends ServletRequestBindingException {
private final String[] paramConditions;
private final Map<String, String[]> actualParams;
/**
* Create a new UnsatisfiedServletRequestParameterException.
* @param paramConditions the parameter conditions that have been violated
* @param actualParams the actual parameter Map associated with the ServletRequest
*/
@SuppressWarnings("unchecked")
public UnsatisfiedServletRequestParameterException(String[] paramConditions, Map actualParams) {
super("");
this.paramConditions = paramConditions;
this.actualParams = (Map<String, String[]>) actualParams;
}
@Override
public String getMessage() {
return "Parameter conditions \"" + StringUtils.arrayToDelimitedString(this.paramConditions, ", ") +
"\" not met for actual request parameters: " + requestParameterMapToString(this.actualParams);
}
private static String requestParameterMapToString(Map<String, String[]> actualParams) {
StringBuilder result = new StringBuilder();
for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String[]> entry = it.next();
result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue()));
if (it.hasNext()) {
result.append(", ");
}
}
return result.toString();
}
/**
* Return the parameter conditions that have been violated.
* @see org.springframework.web.bind.annotation.RequestMapping#params()
*/
public final String[] getParamConditions() {
return this.paramConditions;
}
/**
* Return the actual parameter Map associated with the ServletRequest.
* @see javax.servlet.ServletRequest#getParameterMap()
*/
public final Map<String, String[]> getActualParams() {
return this.actualParams;
}
}

View File

@ -1,290 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import java.lang.reflect.Array;
import java.util.Map;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.validation.DataBinder;
import org.springframework.web.multipart.MultipartFile;
/**
* Special {@link DataBinder} for data binding from web request parameters
* to JavaBean objects. Designed for web environments, but not dependent on
* the Servlet API; serves as base class for more specific DataBinder variants,
* such as {@link org.springframework.web.bind.ServletRequestDataBinder}.
*
* <p>Includes support for field markers which address a common problem with
* HTML checkboxes and select options: detecting that a field was part of
* the form, but did not generate a request parameter because it was empty.
* A field marker allows to detect that state and reset the corresponding
* bean property accordingly. Default values, for parameters that are otherwise
* not present, can specify a value for the field other then empty.
*
* @author Juergen Hoeller
* @author Scott Andrews
* @since 1.2
* @see #registerCustomEditor
* @see #setAllowedFields
* @see #setRequiredFields
* @see #setFieldMarkerPrefix
* @see #setFieldDefaultPrefix
* @see ServletRequestDataBinder
*/
public class WebDataBinder extends DataBinder {
/**
* Default prefix that field marker parameters start with, followed by the field
* name: e.g. "_subscribeToNewsletter" for a field "subscribeToNewsletter".
* <p>Such a marker parameter indicates that the field was visible, that is,
* existed in the form that caused the submission. If no corresponding field
* value parameter was found, the field will be reset. The value of the field
* marker parameter does not matter in this case; an arbitrary value can be used.
* This is particularly useful for HTML checkboxes and select options.
* @see #setFieldMarkerPrefix
*/
public static final String DEFAULT_FIELD_MARKER_PREFIX = "_";
/**
* Default prefix that field default parameters start with, followed by the field
* name: e.g. "!subscribeToNewsletter" for a field "subscribeToNewsletter".
* <p>Default parameters differ from field markers in that they provide a default
* value instead of an empty value.
* @see #setFieldDefaultPrefix
*/
public static final String DEFAULT_FIELD_DEFAULT_PREFIX = "!";
private String fieldMarkerPrefix = DEFAULT_FIELD_MARKER_PREFIX;
private String fieldDefaultPrefix = DEFAULT_FIELD_DEFAULT_PREFIX;
private boolean bindEmptyMultipartFiles = true;
/**
* Create a new WebDataBinder instance, with default object name.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @see #DEFAULT_OBJECT_NAME
*/
public WebDataBinder(Object target) {
super(target);
}
/**
* Create a new WebDataBinder instance.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public WebDataBinder(Object target, String objectName) {
super(target, objectName);
}
/**
* Specify a prefix that can be used for parameters that mark potentially
* empty fields, having "prefix + field" as name. Such a marker parameter is
* checked by existence: You can send any value for it, for example "visible".
* This is particularly useful for HTML checkboxes and select options.
* <p>Default is "_", for "_FIELD" parameters (e.g. "_subscribeToNewsletter").
* Set this to null if you want to turn off the empty field check completely.
* <p>HTML checkboxes only send a value when they're checked, so it is not
* possible to detect that a formerly checked box has just been unchecked,
* at least not with standard HTML means.
* <p>One way to address this is to look for a checkbox parameter value if
* you know that the checkbox has been visible in the form, resetting the
* checkbox if no value found. In Spring web MVC, this typically happens
* in a custom <code>onBind</code> implementation.
* <p>This auto-reset mechanism addresses this deficiency, provided
* that a marker parameter is sent for each checkbox field, like
* "_subscribeToNewsletter" for a "subscribeToNewsletter" field.
* As the marker parameter is sent in any case, the data binder can
* detect an empty field and automatically reset its value.
* @see #DEFAULT_FIELD_MARKER_PREFIX
* @see org.springframework.web.servlet.mvc.BaseCommandController#onBind
*/
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
this.fieldMarkerPrefix = fieldMarkerPrefix;
}
/**
* Return the prefix for parameters that mark potentially empty fields.
*/
public String getFieldMarkerPrefix() {
return this.fieldMarkerPrefix;
}
/**
* Specify a prefix that can be used for parameters that indicate default
* value fields, having "prefix + field" as name. The value of the default
* field is used when the field is not provided.
* <p>Default is "!", for "!FIELD" parameters (e.g. "!subscribeToNewsletter").
* Set this to null if you want to turn off the field defaults completely.
* <p>HTML checkboxes only send a value when they're checked, so it is not
* possible to detect that a formerly checked box has just been unchecked,
* at least not with standard HTML means. A default field is especially
* useful when a checkbox represents a non-boolean value.
* <p>The presence of a default parameter preempts the behavior of a field
* marker for the given field.
* @see #DEFAULT_FIELD_DEFAULT_PREFIX
* @see org.springframework.web.servlet.mvc.BaseCommandController#onBind
*/
public void setFieldDefaultPrefix(String fieldDefaultPrefix) {
this.fieldDefaultPrefix = fieldDefaultPrefix;
}
/**
* Return the prefix for parameters that mark default fields.
*/
public String getFieldDefaultPrefix() {
return this.fieldDefaultPrefix;
}
/**
* Set whether to bind empty MultipartFile parameters. Default is "true".
* <p>Turn this off if you want to keep an already bound MultipartFile
* when the user resubmits the form without choosing a different file.
* Else, the already bound MultipartFile will be replaced by an empty
* MultipartFile holder.
* @see org.springframework.web.multipart.MultipartFile
*/
public void setBindEmptyMultipartFiles(boolean bindEmptyMultipartFiles) {
this.bindEmptyMultipartFiles = bindEmptyMultipartFiles;
}
/**
* Return whether to bind empty MultipartFile parameters.
*/
public boolean isBindEmptyMultipartFiles() {
return this.bindEmptyMultipartFiles;
}
/**
* This implementation performs a field default and marker check
* before delegating to the superclass binding process.
* @see #checkFieldDefaults
* @see #checkFieldMarkers
*/
@Override
protected void doBind(MutablePropertyValues mpvs) {
checkFieldDefaults(mpvs);
checkFieldMarkers(mpvs);
super.doBind(mpvs);
}
/**
* Check the given property values for field defaults,
* i.e. for fields that start with the field default prefix.
* <p>The existence of a field defaults indicates that the specified
* value should be used if the field is otherwise not present.
* @param mpvs the property values to be bound (can be modified)
* @see #getFieldDefaultPrefix
*/
protected void checkFieldDefaults(MutablePropertyValues mpvs) {
if (getFieldDefaultPrefix() != null) {
String fieldDefaultPrefix = getFieldDefaultPrefix();
PropertyValue[] pvArray = mpvs.getPropertyValues();
for (PropertyValue pv : pvArray) {
if (pv.getName().startsWith(fieldDefaultPrefix)) {
String field = pv.getName().substring(fieldDefaultPrefix.length());
if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {
mpvs.addPropertyValue(field, pv.getValue());
}
mpvs.removePropertyValue(pv);
}
}
}
}
/**
* Check the given property values for field markers,
* i.e. for fields that start with the field marker prefix.
* <p>The existence of a field marker indicates that the specified
* field existed in the form. If the property values do not contain
* a corresponding field value, the field will be considered as empty
* and will be reset appropriately.
* @param mpvs the property values to be bound (can be modified)
* @see #getFieldMarkerPrefix
* @see #getEmptyValue(String, Class)
*/
protected void checkFieldMarkers(MutablePropertyValues mpvs) {
if (getFieldMarkerPrefix() != null) {
String fieldMarkerPrefix = getFieldMarkerPrefix();
PropertyValue[] pvArray = mpvs.getPropertyValues();
for (PropertyValue pv : pvArray) {
if (pv.getName().startsWith(fieldMarkerPrefix)) {
String field = pv.getName().substring(fieldMarkerPrefix.length());
if (getPropertyAccessor().isWritableProperty(field) && !mpvs.contains(field)) {
Class fieldType = getPropertyAccessor().getPropertyType(field);
mpvs.addPropertyValue(field, getEmptyValue(field, fieldType));
}
mpvs.removePropertyValue(pv);
}
}
}
}
/**
* Determine an empty value for the specified field.
* <p>Default implementation returns <code>Boolean.FALSE</code>
* for boolean fields and an empty array of array types.
* Else, <code>null</code> is used as default.
* @param field the name of the field
* @param fieldType the type of the field
* @return the empty value (for most fields: null)
*/
protected Object getEmptyValue(String field, Class fieldType) {
if (fieldType != null && boolean.class.equals(fieldType) || Boolean.class.equals(fieldType)) {
// Special handling of boolean property.
return Boolean.FALSE;
}
else if (fieldType != null && fieldType.isArray()) {
// Special handling of array property.
return Array.newInstance(fieldType.getComponentType(), 0);
}
else {
// Default value: try null.
return null;
}
}
/**
* Bind the multipart files contained in the given request, if any
* (in case of a multipart request).
* <p>Multipart files will only be added to the property values if they
* are not empty or if we're configured to bind empty multipart files too.
* @param multipartFiles Map of field name String to MultipartFile object
* @param mpvs the property values to be bound (can be modified)
* @see org.springframework.web.multipart.MultipartFile
* @see #setBindEmptyMultipartFiles
*/
protected void bindMultipartFiles(Map<String, MultipartFile> multipartFiles, MutablePropertyValues mpvs) {
for (Map.Entry<String, MultipartFile> entry : multipartFiles.entrySet()) {
String key = entry.getKey();
MultipartFile value = entry.getValue();
if (isBindEmptyMultipartFiles() || !value.isEmpty()) {
mpvs.addPropertyValue(key, value);
}
}
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method parameter should be bound to an HTTP cookie.
* Supported for annotated handler methods in Servlet and Portlet environments.
*
* <p>The method parameter may be declared as type {@link javax.servlet.http.Cookie}
* or as cookie value type (String, int, etc).
*
* @author Juergen Hoeller
* @since 3.0
* @see RequestMapping
* @see RequestParam
* @see RequestHeader
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {
/**
* The name of the cookie to bind to.
*/
String value() default "";
/**
* Whether the header is required.
* <p>Default is <code>true</code>, leading to an exception thrown in case
* of the header missing in the request. Switch this to <code>false</code>
* if you prefer a <code>null</value> in case of the header missing.
* <p>Alternatively, provide a {@link #defaultValue() defaultValue},
* which implicitely sets this flag to <code>false</code>.
*/
boolean required() default true;
/**
* The default value to use as a fallback. Supplying a default value implicitely
* sets {@link #required()} to false.
*/
String defaultValue() default "";
}

View File

@ -1,113 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation for handling exceptions in specific handler classes and/or
* handler methods. Provides consistent style between Servlet and Portlet
* environments, with the semantics adapting to the concrete environment.
*
* <p>Handler methods which are annotated with this annotation are allowed
* to have very flexible signatures. They may have arguments of the following
* types, in arbitrary order:
* <ul>
* <li>Request and/or response objects (Servlet API or Portlet API).
* You may choose any specific request/response type, e.g.
* {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}
* or {@link javax.portlet.PortletRequest} / {@link javax.portlet.ActionRequest} /
* {@link javax.portlet.RenderRequest}. Note that in the Portlet case,
* an explicitly declared action/render argument is also used for mapping
* specific request types onto a handler method (in case of no other
* information given that differentiates between action and render requests).
* <li>Session object (Servlet API or Portlet API): either
* {@link javax.servlet.http.HttpSession} or {@link javax.portlet.PortletSession}.
* An argument of this type will enforce the presence of a corresponding session.
* As a consequence, such an argument will never be <code>null</code>.
* <i>Note that session access may not be thread-safe, in particular in a
* Servlet environment: Consider switching the
* {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#setSynchronizeOnSession "synchronizeOnSession"}
* flag to "true" if multiple requests are allowed to access a session concurrently.</i>
* <li>{@link org.springframework.web.context.request.WebRequest} or
* {@link org.springframework.web.context.request.NativeWebRequest}.
* Allows for generic request parameter access as well as request/session
* attribute access, without ties to the native Servlet/Portlet API.
* <li>{@link java.util.Locale} for the current request locale
* (determined by the most specific locale resolver available,
* i.e. the configured {@link org.springframework.web.servlet.LocaleResolver}
* in a Servlet environment and the portal locale in a Portlet environment).
* <li>{@link java.io.InputStream} / {@link java.io.Reader} for access
* to the request's content. This will be the raw InputStream/Reader as
* exposed by the Servlet/Portlet API.
* <li>{@link java.io.OutputStream} / {@link java.io.Writer} for generating
* the response's content. This will be the raw OutputStream/Writer as
* exposed by the Servlet/Portlet API.
* </ul>
*
* <p>The following return types are supported for handler methods:
* <ul>
* <li>A <code>ModelAndView</code> object (Servlet MVC or Portlet MVC).
* <li>A {@link org.springframework.ui.Model Model} object, with the view name
* implicitly determined through a {@link org.springframework.web.servlet.RequestToViewNameTranslator}.
* <li>A {@link java.util.Map} object for exposing a model,
* with the view name implicitly determined through a
* {@link org.springframework.web.servlet.RequestToViewNameTranslator}.
* <li>A {@link org.springframework.web.servlet.View} object.
* <li>A {@link java.lang.String} value which is interpreted as view name.
* <li><code>void</code> if the method handles the response itself (by
* writing the response content directly, declaring an argument of type
* {@link javax.servlet.ServletResponse} / {@link javax.servlet.http.HttpServletResponse}
* / {@link javax.portlet.RenderResponse} for that purpose)
* or if the view name is supposed to be implicitly determined through a
* {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* (not declaring a response argument in the handler method signature;
* only applicable in a Servlet environment).
* </ul>
*
* <p><b>NOTE: <code>@RequestMapping</code> will only be processed if a
* corresponding <code>HandlerMapping</code> (for type level annotations)
* and/or <code>HandlerAdapter</code> (for method level annotations) is
* present in the dispatcher.</b> This is the case by default in both
* <code>DispatcherServlet</code> and <code>DispatcherPortlet</code>.
* However, if you are defining custom <code>HandlerMappings</code> or
* <code>HandlerAdapters</code>, then you need to make sure that a
* corresponding custom <code>DefaultAnnotationHandlerMapping</code>
* and/or <code>AnnotationMethodHandlerAdapter</code> is defined as well
* - provided that you intend to use <code>@RequestMapping</code>.
*
* @author Arjen Poutsma
* @see org.springframework.web.context.request.WebRequest
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver
* @since 3.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* Exceptions handled by the annotation method. If empty, will default to any exceptions listed in the method
* argument list.
*/
Class<? extends Throwable>[] value() default {};
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that identifies methods which initialize the
* {@link org.springframework.web.bind.WebDataBinder} which
* will be used for populating command and form object arguments
* of annotated handler methods.
*
* <p>Such init-binder methods support all arguments that {@link RequestMapping}
* supports, except for command/form objects and corresponding validation result
* objects. Init-binder methods must not have a return value; they are usually
* declared as <code>void</code>.
*
* <p>Typical arguments are {@link org.springframework.web.bind.WebDataBinder}
* in combination with {@link org.springframework.web.context.request.WebRequest}
* or {@link java.util.Locale}, allowing to register context-specific editors.
*
* @author Juergen Hoeller
* @since 2.5
* @see org.springframework.web.bind.WebDataBinder
* @see org.springframework.web.context.request.WebRequest
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {
/**
* The names of command/form attributes and/or request parameters
* that this init-binder method is supposed to apply to.
* <p>Default is to apply to all command/form attributes and all request parameters
* processed by the annotated handler class. Specifying model attribute names or
* request parameter names here restricts the init-binder method to those specific
* attributes/parameters, with different init-binder methods typically applying to
* different groups of attributes or parameters.
*/
String[] value() default {};
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Meta annotation that indicates a web mapping annotation.
*
* @author Juergen Hoeller
* @since 3.0
* @see RequestMapping
*/
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that binds a method parameter or method return value
* to a named model attribute, exposed to a web view. Supported
* for {@link RequestMapping} annotated handler classes.
*
* <p>Can be used to expose command objects to a web view, using
* specific attribute names, through annotating corresponding
* parameters of a {@link RequestMapping} annotated handler method).
*
* <p>Can also be used to expose reference data to a web view
* through annotating accessor methods in a controller class which
* is based on {@link RequestMapping} annotated handler methods,
* with such accessor methods allowed to have any arguments that
* {@link RequestMapping} supports for handler methods, returning
* the model attribute value to expose.
*
* @author Juergen Hoeller
* @since 2.5
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
/**
* The name of the model attribute to bind to.
* <p>The default model attribute name is inferred from the declared
* attribute type (i.e. the method parameter type or method return type),
* based on the non-qualified class name:
* e.g. "orderAddress" for class "mypackage.OrderAddress",
* or "orderAddressList" for "List&lt;mypackage.OrderAddress&gt;".
*/
String value() default "";
}

View File

@ -1,26 +0,0 @@
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method parameter should be bound to a URI template variable. Supported for {@link
* RequestMapping} annotated handler methods in Servlet environments.
*
* @author Arjen Poutsma
* @see RequestMapping
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @since 3.0
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
/** The URI template variable to bind to. */
String value() default "";
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method parameter should be bound to the web request body. Supported for annotated
* handler methods in Servlet environments.
*
* @author Arjen Poutsma
* @see RequestHeader
* @see ResponseBody
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @since 3.0
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method parameter should be bound to a web request header.
* Supported for annotated handler methods in Servlet and Portlet environments.
*
* @author Juergen Hoeller
* @since 3.0
* @see RequestMapping
* @see RequestParam
* @see CookieValue
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {
/**
* The name of the request header to bind to.
*/
String value() default "";
/**
* Whether the header is required.
* <p>Default is <code>true</code>, leading to an exception thrown in case
* of the header missing in the request. Switch this to <code>false</code>
* if you prefer a <code>null</value> in case of the header missing.
* <p>Alternatively, provide a {@link #defaultValue() defaultValue},
* which implicitely sets this flag to <code>false</code>.
*/
boolean required() default true;
/**
* The default value to use as a fallback. Supplying a default value implicitely
* sets {@link #required()} to false.
*/
String defaultValue() default "";
}

View File

@ -1,262 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation for mapping web requests onto specific handler classes and/or
* handler methods. Provides consistent style between Servlet and Portlet
* environments, with the semantics adapting to the concrete environment.
*
* <p><b>NOTE:</b> Method-level mappings are only allowed to narrow the mapping
* expressed at the class level (if any). HTTP paths / portlet modes need to
* uniquely map onto specific handler beans, with any given path / mode only
* allowed to be mapped onto one specific handler bean (not spread across
* multiple handler beans). It is strongly recommended to co-locate related
* handler methods into the same bean.
*
* <p>Handler methods which are annotated with this annotation are allowed
* to have very flexible signatures. They may have arguments of the following
* types, in arbitrary order (except for validation results, which need to
* follow right after the corresponding command object, if desired):
* <ul>
* <li>Request and/or response objects (Servlet API or Portlet API).
* You may choose any specific request/response type, e.g.
* {@link javax.servlet.ServletRequest} / {@link javax.servlet.http.HttpServletRequest}
* or {@link javax.portlet.PortletRequest} / {@link javax.portlet.ActionRequest} /
* {@link javax.portlet.RenderRequest}. Note that in the Portlet case,
* an explicitly declared action/render argument is also used for mapping
* specific request types onto a handler method (in case of no other
* information given that differentiates between action and render requests).
* <li>Session object (Servlet API or Portlet API): either
* {@link javax.servlet.http.HttpSession} or {@link javax.portlet.PortletSession}.
* An argument of this type will enforce the presence of a corresponding session.
* As a consequence, such an argument will never be <code>null</code>.
* <i>Note that session access may not be thread-safe, in particular in a
* Servlet environment: Consider switching the
* {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#setSynchronizeOnSession "synchronizeOnSession"}
* flag to "true" if multiple requests are allowed to access a session concurrently.</i>
* <li>{@link org.springframework.web.context.request.WebRequest} or
* {@link org.springframework.web.context.request.NativeWebRequest}.
* Allows for generic request parameter access as well as request/session
* attribute access, without ties to the native Servlet/Portlet API.
* <li>{@link java.util.Locale} for the current request locale
* (determined by the most specific locale resolver available,
* i.e. the configured {@link org.springframework.web.servlet.LocaleResolver}
* in a Servlet environment and the portal locale in a Portlet environment).
* <li>{@link java.io.InputStream} / {@link java.io.Reader} for access
* to the request's content. This will be the raw InputStream/Reader as
* exposed by the Servlet/Portlet API.
* <li>{@link java.io.OutputStream} / {@link java.io.Writer} for generating
* the response's content. This will be the raw OutputStream/Writer as
* exposed by the Servlet/Portlet API.
* <li>{@link PathVariable @PathVariable} annotated parameters for access to
* URI template values (i.e. /hotels/{hotel}). Variable values will be
* converted to the declared method argument type.
* <li>{@link RequestParam @RequestParam} annotated parameters for access to
* specific Servlet/Portlet request parameters. Parameter values will be
* converted to the declared method argument type.
* <li>{@link RequestHeader @RequestHeader} annotated parameters for access to
* specific Servlet/Portlet request HTTP headers. Parameter values will be
* converted to the declared method argument type.
* <li>{@link RequestBody @RequestBody} annotated parameters for access to
* the Servlet request HTTP contents. Parameter values will be
* converted to the declared method argument type using
* {@linkplain org.springframework.http.converter.HttpMessageConverter message
* converters}.
* <li>{@link java.util.Map} / {@link org.springframework.ui.Model} /
* {@link org.springframework.ui.ModelMap} for enriching the implicit model
* that will be exposed to the web view.
* <li>Command/form objects to bind parameters to: as bean properties or fields,
* with customizable type conversion, depending on {@link InitBinder} methods
* and/or the HandlerAdapter configuration - see the "webBindingInitializer"
* property on AnnotationMethodHandlerAdapter.
* Such command objects along with their validation results will be exposed
* as model attributes, by default using the non-qualified command class name
* in property notation (e.g. "orderAddress" for type "mypackage.OrderAddress").
* Specify a parameter-level {@link ModelAttribute} annotation for declaring
* a specific model attribute name.
* <li>{@link org.springframework.validation.Errors} /
* {@link org.springframework.validation.BindingResult} validation results
* for a preceding command/form object (the immediate preceding argument).
* <li>{@link org.springframework.web.bind.support.SessionStatus} status handle
* for marking form processing as complete (triggering the cleanup of session
* attributes that have been indicated by the {@link SessionAttributes} annotation
* at the handler type level).
* </ul>
*
* <p>The following return types are supported for handler methods:
* <ul>
* <li>A <code>ModelAndView</code> object (Servlet MVC or Portlet MVC),
* with the model implicitly enriched with command objects and the results
* of {@link ModelAttribute} annotated reference data accessor methods.
* <li>A {@link org.springframework.ui.Model Model} object, with the view name
* implicitly determined through a {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* and the model implicitly enriched with command objects and the results
* of {@link ModelAttribute} annotated reference data accessor methods.
* <li>A {@link java.util.Map} object for exposing a model,
* with the view name implicitly determined through a
* {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* and the model implicitly enriched with command objects and the results
* of {@link ModelAttribute} annotated reference data accessor methods.
* <li>A {@link org.springframework.web.servlet.View} object, with the
* model implicitly determined through command objects and
* {@link ModelAttribute} annotated reference data accessor methods.
* The handler method may also programmatically enrich the model by
* declaring a {@link org.springframework.ui.Model} argument (see above).
* <li>A {@link java.lang.String} value which is interpreted as view name,
* with the model implicitly determined through command objects and
* {@link ModelAttribute} annotated reference data accessor methods.
* The handler method may also programmatically enrich the model by
* declaring a {@link org.springframework.ui.ModelMap} argument
* (see above).
* <li><code>void</code> if the method handles the response itself (by
* writing the response content directly, declaring an argument of type
* {@link javax.servlet.ServletResponse} / {@link javax.servlet.http.HttpServletResponse}
* / {@link javax.portlet.RenderResponse} for that purpose)
* or if the view name is supposed to be implicitly determined through a
* {@link org.springframework.web.servlet.RequestToViewNameTranslator}
* (not declaring a response argument in the handler method signature;
* only applicable in a Servlet environment).
* <li>Any other return type will be considered as single model attribute
* to be exposed to the view, using the attribute name specified through
* {@link ModelAttribute} at the method level (or the default attribute name
* based on the return type's class name otherwise). The model will be
* implicitly enriched with command objects and the results of
* {@link ModelAttribute} annotated reference data accessor methods.
* </ul>
*
* <p><b>NOTE: <code>@RequestMapping</code> will only be processed if a
* corresponding <code>HandlerMapping</code> (for type level annotations)
* and/or <code>HandlerAdapter</code> (for method level annotations) is
* present in the dispatcher.</b> This is the case by default in both
* <code>DispatcherServlet</code> and <code>DispatcherPortlet</code>.
* However, if you are defining custom <code>HandlerMappings</code> or
* <code>HandlerAdapters</code>, then you need to make sure that a
* corresponding custom <code>DefaultAnnotationHandlerMapping</code>
* and/or <code>AnnotationMethodHandlerAdapter</code> is defined as well
* - provided that you intend to use <code>@RequestMapping</code>.
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5
* @see RequestParam
* @see ModelAttribute
* @see SessionAttributes
* @see InitBinder
* @see org.springframework.web.context.request.WebRequest
* @see org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @see org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping
* @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
/**
* The primary mapping expressed by this annotation.
* <p>In a Servlet environment: the path mapping URIs (e.g. "/myPath.do").
* Ant-style path patterns are also supported (e.g. "/myPath/*.do").
* At the method level, relative paths (e.g. "edit.do") are supported
* within the primary mapping expressed at the type level.
* <p>In a Portlet environment: the mapped portlet modes
* (i.e. "EDIT", "VIEW", "HELP" or any custom modes).
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this primary mapping, narrowing it for a specific handler method.
* <p>In case of Servlet-based handler methods, the method names are
* taken into account for narrowing if no path was specified explicitly,
* according to the specified
* {@link org.springframework.web.servlet.mvc.multiaction.MethodNameResolver}
* (by default an
* {@link org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver}).
* Note that this only applies in case of ambiguous annotation mappings
* that do not specify a path mapping explicitly. In other words,
* the method name is only used for narrowing among a set of matching
* methods; it does not constitute a primary path mapping itself.
* <p>If you have a single default method (without explicit path mapping),
* then all requests without a more specific mapped method found will
* be dispatched to it. If you have multiple such default methods, then
* the method name will be taken into account for choosing between them.
*/
String[] value() default {};
/**
* The HTTP request methods to map to, narrowing the primary mapping:
* GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this HTTP method restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
* <p>Supported for Servlet environments as well as Portlet 2.0 environments.
*/
RequestMethod[] method() default {};
/**
* The parameters of the mapped request, narrowing the primary mapping.
* <p>Same format for any environment: a sequence of "myParam=myValue" style
* expressions, with a request only mapped if each such parameter is found
* to have the given value. "myParam" style expressions are also supported,
* with such parameters having to be present in the request (allowed to have
* any value). Finally, "!myParam" style expressions indicate that the
* specified parameter is <i>not</i> supposed to be present in the request.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this parameter restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
* <p>In a Servlet environment, parameter mappings are considered as restrictions
* that are enforced at the type level. The primary path mapping (i.e. the
* specified URI value) still has to uniquely identify the target handler, with
* parameter mappings simply expressing preconditions for invoking the handler.
* <p>In a Portlet environment, parameters are taken into account as mapping
* differentiators, i.e. the primary portlet mode mapping plus the parameter
* conditions uniquely identify the target handler. Different handlers may be
* mapped onto the same portlet mode, as long as their parameter mappings differ.
*/
String[] params() default {};
/**
* The headers of the mapped request, narrowing the primary mapping.
* <p>Same format for any environment: a sequence of "My-Header=myValue" style
* expressions, with a request only mapped if each such header is found
* to have the given value. "My-Header" style expressions are also supported,
* with such headers having to be present in the request (allowed to have
* any value). Finally, "!My-Header" style expressions indicate that the
* specified header is <i>not</i> supposed to be present in the request.
* <p>Also supports media type wildcards (*), for headers such as Accept
* and Content-Type. For instance,
* <pre>
* &#064;RequestMapping(value = "/something", headers = "content-type=text/*")
* </pre>
* will match requests with a Content-Type of "text/html", "text/plain", etc.
* <p><b>Supported at the type level as well as at the method level!</b>
* When used at the type level, all method-level mappings inherit
* this header restriction (i.e. the type-level restriction
* gets checked before the handler method is even resolved).
* @see org.springframework.http.MediaType
*/
String[] headers() default {};
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
/**
* Java 5 enumeration of HTTP request methods. Intended for use
* with the {@link RequestMapping#method()} attribute of the
* {@link RequestMapping} annotation.
*
* <p>Note that, by default, {@link org.springframework.web.servlet.DispatcherServlet}
* supports GET, HEAD, POST, PUT and DELETE only. DispatcherServlet will
* process TRACE and OPTIONS with the default HttpServlet behavior unless
* explicitly told to dispatch those request types as well: Check out
* the "dispatchOptionsRequest" and "dispatchTraceRequest" properties,
* switching them to "true" if necessary.
*
* @author Juergen Hoeller
* @since 2.5
* @see RequestMapping
* @see org.springframework.web.servlet.DispatcherServlet#setDispatchOptionsRequest
* @see org.springframework.web.servlet.DispatcherServlet#setDispatchTraceRequest
*/
public enum RequestMethod {
GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method parameter should be bound to a web request parameter.
* Supported for annotated handler methods in Servlet and Portlet environments.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 2.5
* @see RequestMapping
* @see RequestHeader
* @see CookieValue
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
/**
* The name of the request parameter to bind to.
*/
String value() default "";
/**
* Whether the parameter is required.
* <p>Default is <code>true</code>, leading to an exception thrown in case
* of the parameter missing in the request. Switch this to <code>false</code>
* if you prefer a <code>null</value> in case of the parameter missing.
* <p>Alternatively, provide a {@link #defaultValue() defaultValue},
* which implicitely sets this flag to <code>false</code>.
*/
boolean required() default true;
/**
* The default value to use as a fallback. Supplying a default value implicitely
* sets {@link #required()} to false.
*/
String defaultValue() default "";
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a method return value should be bound to the web response body. Supported for annotated
* handler methods in Servlet environments.
*
* @author Arjen Poutsma
* @see RequestBody
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
* @since 3.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}

View File

@ -1,55 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.http.HttpStatus;
/**
* Marks a method or exception class with the status code and reason that should be returned. The status code is applied
* to the HTTP response when the handler method is invoked, or whenever said exception is thrown.
*
* @author Arjen Poutsma
* @see org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
* @since 3.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseStatus {
/**
* The status code to use for the response.
*
* @see javax.servlet.http.HttpServletResponse#setStatus(int)
*/
HttpStatus value();
/**
* The reason to be used for the response. <p>If this element is not set, it will default to the standard status
* message for the status code.
*
* @see javax.servlet.http.HttpServletResponse#sendError(int, String)
*/
String reason() default "";
}

View File

@ -1,71 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that indicates the session attributes that a specific handler
* uses. This will typically list the names of model attributes which should be
* transparently stored in the session or some conversational storage,
* serving as form-backing beans. <b>Declared at the type level,</b> applying
* to the model attributes that the annotated handler class operates on.
*
* <p><b>NOTE:</b> Session attributes as indicated using this annotation
* correspond to a specific handler's model attributes, getting transparently
* stored in a conversational session. Those attributes will be removed once
* the handler indicates completion of its conversational session. Therefore,
* use this facility for such conversational attributes which are supposed
* to be stored in the session <i>temporarily</i> during the course of a
* specific handler's conversation.
*
* <p>For permanent session attributes, e.g. a user authentication object,
* use the traditional <code>session.setAttribute</code> method instead.
* Alternatively, consider using the attribute management capabilities of the
* generic {@link org.springframework.web.context.request.WebRequest} interface.
*
* @author Juergen Hoeller
* @since 2.5
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
/**
* The names of session attributes in the model, to be stored in the
* session or some conversational storage.
* <p>Note: This indicates the model attribute names. The session attribute
* names may or may not match the model attribute names; applications should
* not rely on the session attribute names but rather operate on the model only.
*/
String[] value() default {};
/**
* The types of session attributes in the model, to be stored in the
* session or some conversational storage. All model attributes of this
* type will be stored in the session, regardless of attribute name.
*/
Class[] types() default {};
}

View File

@ -1,9 +0,0 @@
/**
*
* Annotations for binding requests to controllers and handler methods
* as well as for binding request parameters to method arguments.
*
*/
package org.springframework.web.bind.annotation;

View File

@ -1,41 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation.support;
import java.lang.reflect.Method;
import org.springframework.core.NestedRuntimeException;
/**
* Exception indicating that the execution of an annotated MVC handler method failed.
*
* @author Juergen Hoeller
* @since 2.5.6
* @see HandlerMethodInvoker#invokeHandlerMethod
*/
public class HandlerMethodInvocationException extends NestedRuntimeException {
/**
* Create a new HandlerMethodInvocationException for the given Method handle and cause.
* @param handlerMethod the handler method handle
* @param cause the cause of the invocation failure
*/
public HandlerMethodInvocationException(Method handlerMethod, Throwable cause) {
super("Failed to invoke handler method [" + handlerMethod + "]", cause);
}
}

View File

@ -1,745 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.Conventions;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.model.ui.PresentationModelFactory;
import org.springframework.model.ui.config.BindingLifecycle;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.ui.MvcBindingLifecycle;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.DefaultSessionAttributeStore;
import org.springframework.web.bind.support.SessionAttributeStore;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.bind.support.SimpleSessionStatus;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.bind.support.WebRequestDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.NativeWebRequestParameterMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.servlet.support.PresentationModelUtils;
/**
* Support class for invoking an annotated handler method. Operates on the introspection results of a {@link
* HandlerMethodResolver} for a specific handler type.
*
* <p>Used by {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter} and {@link
* org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter}.
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @see #invokeHandlerMethod
* @since 2.5.2
*/
public class HandlerMethodInvoker {
/** We'll create a lot of these objects, so we don't want a new logger every time. */
private static final Log logger = LogFactory.getLog(HandlerMethodInvoker.class);
private final HandlerMethodResolver methodResolver;
private final WebBindingInitializer bindingInitializer;
private final SessionAttributeStore sessionAttributeStore;
private final ParameterNameDiscoverer parameterNameDiscoverer;
private final WebArgumentResolver[] customArgumentResolvers;
private final SimpleSessionStatus sessionStatus = new SimpleSessionStatus();
private final HttpMessageConverter[] messageConverters;
public HandlerMethodInvoker(HandlerMethodResolver methodResolver) {
this(methodResolver, null);
}
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer) {
this(methodResolver, bindingInitializer, new DefaultSessionAttributeStore(), null, new WebArgumentResolver[0],
new HttpMessageConverter[0]);
}
public HandlerMethodInvoker(HandlerMethodResolver methodResolver, WebBindingInitializer bindingInitializer,
SessionAttributeStore sessionAttributeStore, ParameterNameDiscoverer parameterNameDiscoverer,
WebArgumentResolver[] customArgumentResolvers, HttpMessageConverter[] messageConverters) {
this.methodResolver = methodResolver;
this.bindingInitializer = bindingInitializer;
this.sessionAttributeStore = sessionAttributeStore;
this.parameterNameDiscoverer = parameterNameDiscoverer;
this.customArgumentResolvers = customArgumentResolvers;
this.messageConverters = messageConverters;
}
public final Object invokeHandlerMethod(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
Method handlerMethodToInvoke = BridgeMethodResolver.findBridgedMethod(handlerMethod);
try {
boolean debug = logger.isDebugEnabled();
for (Method attributeMethod : this.methodResolver.getModelAttributeMethods()) {
Method attributeMethodToInvoke = BridgeMethodResolver.findBridgedMethod(attributeMethod);
Object[] args = resolveHandlerArguments(attributeMethodToInvoke, handler, webRequest, implicitModel);
if (debug) {
logger.debug("Invoking model attribute method: " + attributeMethodToInvoke);
}
Object attrValue = doInvokeMethod(attributeMethodToInvoke, handler, args);
String attrName = AnnotationUtils.findAnnotation(attributeMethodToInvoke, ModelAttribute.class).value();
if ("".equals(attrName)) {
Class resolvedType = GenericTypeResolver.resolveReturnType(
attributeMethodToInvoke, handler.getClass());
attrName = Conventions.getVariableNameForReturnType(
attributeMethodToInvoke, resolvedType, attrValue);
}
implicitModel.addAttribute(attrName, attrValue);
}
Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
if (debug) {
logger.debug("Invoking request handler method: " + handlerMethodToInvoke);
}
return doInvokeMethod(handlerMethodToInvoke, handler, args);
}
catch (IllegalStateException ex) {
// Throw exception with full handler method context...
throw new HandlerMethodInvocationException(handlerMethodToInvoke, ex);
}
}
@SuppressWarnings("unchecked")
private Object[] resolveHandlerArguments(Method handlerMethod, Object handler,
NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception {
Class[] paramTypes = handlerMethod.getParameterTypes();
Object[] args = new Object[paramTypes.length];
for (int i = 0; i < args.length; i++) {
MethodParameter methodParam = new MethodParameter(handlerMethod, i);
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
String paramName = null;
String headerName = null;
boolean requestBodyFound = false;
String cookieName = null;
String pathVarName = null;
String attrName = null;
boolean required = false;
String defaultValue = null;
int found = 0;
Annotation[] paramAnns = methodParam.getParameterAnnotations();
for (Annotation paramAnn : paramAnns) {
if (RequestParam.class.isInstance(paramAnn)) {
RequestParam requestParam = (RequestParam) paramAnn;
paramName = requestParam.value();
required = requestParam.required();
defaultValue = requestParam.defaultValue();
found++;
}
else if (RequestHeader.class.isInstance(paramAnn)) {
RequestHeader requestHeader = (RequestHeader) paramAnn;
headerName = requestHeader.value();
required = requestHeader.required();
defaultValue = requestHeader.defaultValue();
found++;
}
else if (RequestBody.class.isInstance(paramAnn)) {
requestBodyFound = true;
found++;
}
else if (CookieValue.class.isInstance(paramAnn)) {
CookieValue cookieValue = (CookieValue) paramAnn;
cookieName = cookieValue.value();
required = cookieValue.required();
defaultValue = cookieValue.defaultValue();
found++;
}
else if (PathVariable.class.isInstance(paramAnn)) {
PathVariable pathVar = (PathVariable) paramAnn;
pathVarName = pathVar.value();
found++;
}
else if (ModelAttribute.class.isInstance(paramAnn)) {
ModelAttribute attr = (ModelAttribute) paramAnn;
attrName = attr.value();
found++;
}
}
if (found > 1) {
throw new IllegalStateException("Handler parameter annotations are exclusive choices - " +
"do not specify more than one such annotation on the same parameter: " + handlerMethod);
}
if (found == 0) {
Object argValue = resolveCommonArgument(methodParam, webRequest);
if (argValue != WebArgumentResolver.UNRESOLVED) {
args[i] = argValue;
}
else {
Class paramType = methodParam.getParameterType();
if (Model.class.isAssignableFrom(paramType) || Map.class.isAssignableFrom(paramType)) {
args[i] = implicitModel;
}
else if (SessionStatus.class.isAssignableFrom(paramType)) {
args[i] = this.sessionStatus;
}
else if (Errors.class.isAssignableFrom(paramType)) {
throw new IllegalStateException("Errors/BindingResult argument declared " +
"without preceding model attribute. Check your handler method signature!");
}
// TODO - Code Review - NEW BINDING LIFECYCLE RESOLVABLE ARG
else if (BindingLifecycle.class.isAssignableFrom(paramType)) {
Class<?> modelType = resolveBindingLifecycleModelType(methodParam);
PresentationModelFactory factory = PresentationModelUtils.getPresentationModelFactory(webRequest);
Map<String, Object> fieldValues = new NativeWebRequestParameterMap(webRequest);
args[i] = new MvcBindingLifecycle(modelType, factory, implicitModel, fieldValues);
}
else if (BeanUtils.isSimpleProperty(paramType)) {
paramName = "";
}
else {
attrName = "";
}
}
}
if (paramName != null) {
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
}
else if (headerName != null) {
args[i] = resolveRequestHeader(headerName, required, defaultValue, methodParam, webRequest, handler);
}
else if (requestBodyFound) {
args[i] = resolveRequestBody(methodParam, webRequest, handler);
}
else if (cookieName != null) {
args[i] = resolveCookieValue(cookieName, required, defaultValue, methodParam, webRequest, handler);
}
else if (pathVarName != null) {
args[i] = resolvePathVariable(pathVarName, methodParam, webRequest, handler);
}
else if (attrName != null) {
WebDataBinder binder = resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);
boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));
if (binder.getTarget() != null) {
doBind(webRequest, binder, !assignBindingResult);
}
args[i] = binder.getTarget();
if (assignBindingResult) {
args[i + 1] = binder.getBindingResult();
i++;
}
implicitModel.putAll(binder.getBindingResult().getModel());
}
}
return args;
}
protected void initBinder(Object handler, String attrName, WebDataBinder binder, NativeWebRequest webRequest)
throws Exception {
if (this.bindingInitializer != null) {
this.bindingInitializer.initBinder(binder, webRequest);
}
if (handler != null) {
Set<Method> initBinderMethods = this.methodResolver.getInitBinderMethods();
if (!initBinderMethods.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (Method initBinderMethod : initBinderMethods) {
Method methodToInvoke = BridgeMethodResolver.findBridgedMethod(initBinderMethod);
String[] targetNames = AnnotationUtils.findAnnotation(methodToInvoke, InitBinder.class).value();
if (targetNames.length == 0 || Arrays.asList(targetNames).contains(attrName)) {
Object[] initBinderArgs =
resolveInitBinderArguments(handler, methodToInvoke, binder, webRequest);
if (debug) {
logger.debug("Invoking init-binder method: " + methodToInvoke);
}
Object returnValue = doInvokeMethod(methodToInvoke, handler, initBinderArgs);
if (returnValue != null) {
throw new IllegalStateException(
"InitBinder methods must not have a return value: " + methodToInvoke);
}
}
}
}
}
}
private Object[] resolveInitBinderArguments(Object handler, Method initBinderMethod,
WebDataBinder binder, NativeWebRequest webRequest) throws Exception {
Class[] initBinderParams = initBinderMethod.getParameterTypes();
Object[] initBinderArgs = new Object[initBinderParams.length];
for (int i = 0; i < initBinderArgs.length; i++) {
MethodParameter methodParam = new MethodParameter(initBinderMethod, i);
methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer);
GenericTypeResolver.resolveParameterType(methodParam, handler.getClass());
String paramName = null;
boolean paramRequired = false;
String paramDefaultValue = null;
String pathVarName = null;
Annotation[] paramAnns = methodParam.getParameterAnnotations();
for (Annotation paramAnn : paramAnns) {
if (RequestParam.class.isInstance(paramAnn)) {
RequestParam requestParam = (RequestParam) paramAnn;
paramName = requestParam.value();
paramRequired = requestParam.required();
paramDefaultValue = requestParam.defaultValue();
break;
}
else if (ModelAttribute.class.isInstance(paramAnn)) {
throw new IllegalStateException(
"@ModelAttribute is not supported on @InitBinder methods: " + initBinderMethod);
}
else if (PathVariable.class.isInstance(paramAnn)) {
PathVariable pathVar = (PathVariable) paramAnn;
pathVarName = pathVar.value();
}
}
if (paramName == null && pathVarName == null) {
Object argValue = resolveCommonArgument(methodParam, webRequest);
if (argValue != WebArgumentResolver.UNRESOLVED) {
initBinderArgs[i] = argValue;
}
else {
Class paramType = initBinderParams[i];
if (paramType.isInstance(binder)) {
initBinderArgs[i] = binder;
}
else if (BeanUtils.isSimpleProperty(paramType)) {
paramName = "";
}
else {
throw new IllegalStateException(
"Unsupported argument [" + paramType.getName() + "] for @InitBinder method: " +
initBinderMethod);
}
}
}
if (paramName != null) {
initBinderArgs[i] = resolveRequestParam(
paramName, paramRequired, paramDefaultValue, methodParam, webRequest, null);
}
else if (pathVarName != null) {
initBinderArgs[i] = resolvePathVariable(pathVarName, methodParam, webRequest, null);
}
}
return initBinderArgs;
}
private Object resolveRequestParam(String paramName, boolean required, String defaultValue,
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
Class paramType = methodParam.getParameterType();
if (paramName.length() == 0) {
paramName = getRequiredParameterName(methodParam);
}
Object paramValue = null;
if (webRequest.getNativeRequest() instanceof MultipartRequest) {
paramValue = ((MultipartRequest) webRequest.getNativeRequest()).getFile(paramName);
}
if (paramValue == null) {
String[] paramValues = webRequest.getParameterValues(paramName);
if (paramValues != null) {
paramValue = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
}
if (paramValue == null) {
if (StringUtils.hasText(defaultValue)) {
paramValue = defaultValue;
}
else if (required) {
raiseMissingParameterException(paramName, paramType);
}
paramValue = checkValue(paramName, paramValue, paramType);
}
WebDataBinder binder = createBinder(webRequest, null, paramName);
initBinder(handlerForInitBinderCall, paramName, binder, webRequest);
return binder.convertIfNecessary(paramValue, paramType, methodParam);
}
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue,
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
Class paramType = methodParam.getParameterType();
if (headerName.length() == 0) {
headerName = getRequiredParameterName(methodParam);
}
Object headerValue = null;
String[] headerValues = webRequest.getHeaderValues(headerName);
if (headerValues != null) {
headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues);
}
if (headerValue == null) {
if (StringUtils.hasText(defaultValue)) {
headerValue = defaultValue;
}
else if (required) {
raiseMissingHeaderException(headerName, paramType);
}
headerValue = checkValue(headerName, headerValue, paramType);
}
WebDataBinder binder = createBinder(webRequest, null, headerName);
initBinder(handlerForInitBinderCall, headerName, binder, webRequest);
return binder.convertIfNecessary(headerValue, paramType, methodParam);
}
/**
* Resolves the given {@link RequestBody @RequestBody} annotation.
*/
@SuppressWarnings("unchecked")
protected Object resolveRequestBody(MethodParameter methodParam, NativeWebRequest webRequest, Object handler)
throws Exception {
HttpInputMessage inputMessage = createHttpInputMessage(webRequest);
Class paramType = methodParam.getParameterType();
MediaType contentType = inputMessage.getHeaders().getContentType();
if (contentType == null) {
StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
String paramName = methodParam.getParameterName();
if (paramName != null) {
builder.append(' ');
builder.append(paramName);
}
throw new HttpMediaTypeNotSupportedException(
"Cannot extract @RequestBody parameter (" + builder.toString() + "): no Content-Type found");
}
List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
for (HttpMessageConverter<?> messageConverter : messageConverters) {
allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
if (messageConverter.supports(paramType)) {
for (MediaType supportedMediaType : messageConverter.getSupportedMediaTypes()) {
if (supportedMediaType.includes(contentType)) {
return messageConverter.read(paramType, inputMessage);
}
}
}
}
throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
}
/**
* Return a {@link HttpInputMessage} for the given {@link NativeWebRequest}.
* Throws an UnsupportedOperationException by default.
*/
protected HttpInputMessage createHttpInputMessage(NativeWebRequest webRequest) throws Exception {
throw new UnsupportedOperationException("@RequestBody not supported");
}
private Object resolveCookieValue(String cookieName, boolean required, String defaultValue,
MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall)
throws Exception {
Class paramType = methodParam.getParameterType();
if (cookieName.length() == 0) {
cookieName = getRequiredParameterName(methodParam);
}
Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest);
if (cookieValue == null) {
if (StringUtils.hasText(defaultValue)) {
cookieValue = defaultValue;
}
else if (required) {
raiseMissingCookieException(cookieName, paramType);
}
cookieValue = checkValue(cookieName, cookieValue, paramType);
}
WebDataBinder binder = createBinder(webRequest, null, cookieName);
initBinder(handlerForInitBinderCall, cookieName, binder, webRequest);
return binder.convertIfNecessary(cookieValue, paramType, methodParam);
}
/**
* Resolves the given {@link CookieValue @CookieValue} annotation.
* Throws an UnsupportedOperationException by default.
*/
protected Object resolveCookieValue(String cookieName, Class paramType, NativeWebRequest webRequest)
throws Exception {
throw new UnsupportedOperationException("@CookieValue not supported");
}
private Object resolvePathVariable(String pathVarName, MethodParameter methodParam,
NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception {
Class paramType = methodParam.getParameterType();
if (pathVarName.length() == 0) {
pathVarName = getRequiredParameterName(methodParam);
}
String pathVarValue = resolvePathVariable(pathVarName, paramType, webRequest);
WebDataBinder binder = createBinder(webRequest, null, pathVarName);
initBinder(handlerForInitBinderCall, pathVarName, binder, webRequest);
return binder.convertIfNecessary(pathVarValue, paramType, methodParam);
}
/**
* Resolves the given {@link PathVariable @PathVariable} annotation.
* Throws an UnsupportedOperationException by default.
*/
protected String resolvePathVariable(String pathVarName, Class paramType, NativeWebRequest webRequest)
throws Exception {
throw new UnsupportedOperationException("@PathVariable not supported");
}
private String getRequiredParameterName(MethodParameter methodParam) {
String name = methodParam.getParameterName();
if (name == null) {
throw new IllegalStateException("No parameter name specified for argument of type [" +
methodParam.getParameterType().getName() +
"], and no parameter name information found in class file either.");
}
return name;
}
private Object checkValue(String name, Object value, Class paramType) {
if (value == null) {
if (boolean.class.equals(paramType)) {
return Boolean.FALSE;
}
else if (paramType.isPrimitive()) {
throw new IllegalStateException("Optional " + paramType + " parameter '" + name +
"' is not present but cannot be translated into a null value due to being declared as a " +
"primitive type. Consider declaring it as object wrapper for the corresponding primitive type.");
}
}
return value;
}
private WebDataBinder resolveModelAttribute(String attrName, MethodParameter methodParam,
ExtendedModelMap implicitModel, NativeWebRequest webRequest, Object handler)
throws Exception {
// Bind request parameter onto object...
String name = attrName;
if ("".equals(name)) {
name = Conventions.getVariableNameForParameter(methodParam);
}
Class paramType = methodParam.getParameterType();
Object bindObject = null;
if (implicitModel.containsKey(name)) {
bindObject = implicitModel.get(name);
}
else if (this.methodResolver.isSessionAttribute(name, paramType)) {
bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name);
if (bindObject == null) {
raiseSessionRequiredException("Session attribute '" + name + "' required - not found in session");
}
}
else {
bindObject = BeanUtils.instantiateClass(paramType);
}
WebDataBinder binder = createBinder(webRequest, bindObject, name);
initBinder(handler, name, binder, webRequest);
return binder;
}
@SuppressWarnings("unchecked")
public final void updateModelAttributes(Object handler, Map<String, Object> mavModel,
ExtendedModelMap implicitModel, NativeWebRequest webRequest) throws Exception {
if (this.methodResolver.hasSessionAttributes() && this.sessionStatus.isComplete()) {
for (String attrName : this.methodResolver.getActualSessionAttributeNames()) {
this.sessionAttributeStore.cleanupAttribute(webRequest, attrName);
}
}
// Expose model attributes as session attributes, if required.
// Expose BindingResults for all attributes, making custom editors available.
Map<String, Object> model = (mavModel != null ? mavModel : implicitModel);
for (String attrName : new HashSet<String>(model.keySet())) {
Object attrValue = model.get(attrName);
boolean isSessionAttr =
this.methodResolver.isSessionAttribute(attrName, (attrValue != null ? attrValue.getClass() : null));
if (isSessionAttr && !this.sessionStatus.isComplete()) {
this.sessionAttributeStore.storeAttribute(webRequest, attrName, attrValue);
}
if (!attrName.startsWith(BindingResult.MODEL_KEY_PREFIX) &&
(isSessionAttr || isBindingCandidate(attrValue))) {
String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + attrName;
if (mavModel != null && !model.containsKey(bindingResultKey)) {
WebDataBinder binder = createBinder(webRequest, attrValue, attrName);
initBinder(handler, attrName, binder, webRequest);
mavModel.put(bindingResultKey, binder.getBindingResult());
}
}
}
}
/**
* Determine whether the given value qualifies as a "binding candidate", i.e. might potentially be subject to
* bean-style data binding later on.
*/
protected boolean isBindingCandidate(Object value) {
return (value != null && !value.getClass().isArray() && !(value instanceof Collection) &&
!(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass()));
}
private Object doInvokeMethod(Method method, Object target, Object[] args) throws Exception {
ReflectionUtils.makeAccessible(method);
try {
return method.invoke(target, args);
}
catch (InvocationTargetException ex) {
ReflectionUtils.rethrowException(ex.getTargetException());
}
throw new IllegalStateException("Should never get here");
}
protected void raiseMissingParameterException(String paramName, Class paramType) throws Exception {
throw new IllegalStateException("Missing parameter '" + paramName + "' of type [" + paramType.getName() + "]");
}
protected void raiseMissingHeaderException(String headerName, Class paramType) throws Exception {
throw new IllegalStateException("Missing header '" + headerName + "' of type [" + paramType.getName() + "]");
}
protected void raiseMissingCookieException(String cookieName, Class paramType) throws Exception {
throw new IllegalStateException("Missing cookie value '" + cookieName + "' of type [" + paramType.getName() + "]");
}
protected void raiseSessionRequiredException(String message) throws Exception {
throw new IllegalStateException(message);
}
protected WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception {
return new WebRequestDataBinder(target, objectName);
}
protected void doBind(NativeWebRequest webRequest, WebDataBinder binder, boolean failOnErrors) throws Exception {
WebRequestDataBinder requestBinder = (WebRequestDataBinder) binder;
requestBinder.bind(webRequest);
if (failOnErrors) {
requestBinder.closeNoCatch();
}
}
protected Object resolveCommonArgument(MethodParameter methodParameter, NativeWebRequest webRequest)
throws Exception {
// Invoke custom argument resolvers if present...
if (this.customArgumentResolvers != null) {
for (WebArgumentResolver argumentResolver : this.customArgumentResolvers) {
Object value = argumentResolver.resolveArgument(methodParameter, webRequest);
if (value != WebArgumentResolver.UNRESOLVED) {
return value;
}
}
}
// Resolution of standard parameter types...
Class paramType = methodParameter.getParameterType();
Object value = resolveStandardArgument(paramType, webRequest);
if (value != WebArgumentResolver.UNRESOLVED && !ClassUtils.isAssignableValue(paramType, value)) {
throw new IllegalStateException(
"Standard argument type [" + paramType.getName() + "] resolved to incompatible value of type [" +
(value != null ? value.getClass() : null) +
"]. Consider declaring the argument type in a less specific fashion.");
}
return value;
}
protected Object resolveStandardArgument(Class parameterType, NativeWebRequest webRequest) throws Exception {
if (WebRequest.class.isAssignableFrom(parameterType)) {
return webRequest;
}
return WebArgumentResolver.UNRESOLVED;
}
protected final void addReturnValueAsModelAttribute(
Method handlerMethod, Class handlerType, Object returnValue, ExtendedModelMap implicitModel) {
ModelAttribute attr = AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class);
String attrName = (attr != null ? attr.value() : "");
if ("".equals(attrName)) {
Class resolvedType = GenericTypeResolver.resolveReturnType(handlerMethod, handlerType);
attrName = Conventions.getVariableNameForReturnType(handlerMethod, resolvedType, returnValue);
}
implicitModel.addAttribute(attrName, returnValue);
}
// TODO - Code Review - BINDING LIFECYCLE RELATED INTERNAL HELPERS
// TODO - this generic arg identification looping code is duplicated in several places now...
private Class<?> resolveBindingLifecycleModelType(MethodParameter methodParam) {
Type type = GenericTypeResolver.getTargetType(methodParam);
if (type instanceof ParameterizedType) {
ParameterizedType paramType = (ParameterizedType) type;
Type rawType = paramType.getRawType();
Type arg = paramType.getActualTypeArguments()[0];
if (arg instanceof TypeVariable) {
arg = GenericTypeResolver.resolveTypeVariable((TypeVariable) arg, BindingLifecycle.class);
}
if (arg instanceof Class) {
return (Class) arg;
}
}
return null;
}
}

View File

@ -1,141 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation.support;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
/**
* Support class for resolving web method annotations in a handler type.
* Processes <code>@RequestMapping</code>, <code>@InitBinder</code>,
* <code>@ModelAttribute</code> and <code>@SessionAttributes</code>.
*
* <p>Used by {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter}
* and {@link org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter}.
*
* @author Juergen Hoeller
* @since 2.5.2
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.web.bind.annotation.InitBinder
* @see org.springframework.web.bind.annotation.ModelAttribute
* @see org.springframework.web.bind.annotation.SessionAttributes
*/
public class HandlerMethodResolver {
private final Set<Method> handlerMethods = new LinkedHashSet<Method>();
private final Set<Method> initBinderMethods = new LinkedHashSet<Method>();
private final Set<Method> modelAttributeMethods = new LinkedHashSet<Method>();
private RequestMapping typeLevelMapping;
private boolean sessionAttributesFound;
private final Set<String> sessionAttributeNames = new HashSet<String>();
private final Set<Class> sessionAttributeTypes = new HashSet<Class>();
private final Set<String> actualSessionAttributeNames = Collections.synchronizedSet(new HashSet<String>(4));
/**
* Initialize a new HandlerMethodResolver for the specified handler type.
* @param handlerType the handler class to introspect
*/
public void init(final Class<?> handlerType) {
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) {
if (isHandlerMethod(method)) {
handlerMethods.add(ClassUtils.getMostSpecificMethod(method, handlerType));
}
else if (method.isAnnotationPresent(InitBinder.class)) {
initBinderMethods.add(ClassUtils.getMostSpecificMethod(method, handlerType));
}
else if (method.isAnnotationPresent(ModelAttribute.class)) {
modelAttributeMethods.add(ClassUtils.getMostSpecificMethod(method, handlerType));
}
}
});
this.typeLevelMapping = handlerType.getAnnotation(RequestMapping.class);
SessionAttributes sessionAttributes = handlerType.getAnnotation(SessionAttributes.class);
this.sessionAttributesFound = (sessionAttributes != null);
if (this.sessionAttributesFound) {
this.sessionAttributeNames.addAll(Arrays.asList(sessionAttributes.value()));
this.sessionAttributeTypes.addAll(Arrays.asList(sessionAttributes.types()));
}
}
protected boolean isHandlerMethod(Method method) {
return method.isAnnotationPresent(RequestMapping.class);
}
public final boolean hasHandlerMethods() {
return !this.handlerMethods.isEmpty();
}
public final Set<Method> getHandlerMethods() {
return this.handlerMethods;
}
public final Set<Method> getInitBinderMethods() {
return this.initBinderMethods;
}
public final Set<Method> getModelAttributeMethods() {
return this.modelAttributeMethods;
}
public boolean hasTypeLevelMapping() {
return (this.typeLevelMapping != null);
}
public RequestMapping getTypeLevelMapping() {
return this.typeLevelMapping;
}
public boolean hasSessionAttributes() {
return this.sessionAttributesFound;
}
public boolean isSessionAttribute(String attrName, Class attrType) {
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
this.actualSessionAttributeNames.add(attrName);
return true;
}
else {
return false;
}
}
public Set<String> getActualSessionAttributeNames() {
return this.actualSessionAttributeNames;
}
}

View File

@ -1,8 +0,0 @@
/**
*
* Support classes for web annotation processing.
*
*/
package org.springframework.web.bind.annotation.support;

View File

@ -1,8 +0,0 @@
/**
*
* Provides web-specific data binding functionality.
*
*/
package org.springframework.web.bind;

View File

@ -1,135 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.validation.BindingErrorProcessor;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.WebRequest;
/**
* Convenient {@link WebBindingInitializer} for declarative configuration
* in a Spring application context. Allows for reusing pre-configured
* initializers with multiple controller/handlers.
*
* @author Juergen Hoeller
* @since 2.5
* @see #setDirectFieldAccess
* @see #setMessageCodesResolver
* @see #setBindingErrorProcessor
* @see #setPropertyEditorRegistrar
*/
public class ConfigurableWebBindingInitializer implements WebBindingInitializer {
private boolean directFieldAccess = false;
private MessageCodesResolver messageCodesResolver;
private BindingErrorProcessor bindingErrorProcessor;
private PropertyEditorRegistrar[] propertyEditorRegistrars;
/**
* Set whether to use direct field access instead of bean property access.
* <p>Default is <code>false</code>, using bean property access.
* Switch this to <code>true</code> for enforcing direct field access.
*/
public final void setDirectFieldAccess(boolean directFieldAccess) {
this.directFieldAccess = directFieldAccess;
}
/**
* Set the strategy to use for resolving errors into message codes.
* Applies the given strategy to all data binders used by this controller.
* <p>Default is <code>null</code>, i.e. using the default strategy of
* the data binder.
* @see org.springframework.validation.DataBinder#setMessageCodesResolver
*/
public final void setMessageCodesResolver(MessageCodesResolver messageCodesResolver) {
this.messageCodesResolver = messageCodesResolver;
}
/**
* Return the strategy to use for resolving errors into message codes.
*/
public final MessageCodesResolver getMessageCodesResolver() {
return this.messageCodesResolver;
}
/**
* Set the strategy to use for processing binding errors, that is,
* required field errors and <code>PropertyAccessException</code>s.
* <p>Default is <code>null</code>, that is, using the default strategy
* of the data binder.
* @see org.springframework.validation.DataBinder#setBindingErrorProcessor
*/
public final void setBindingErrorProcessor(BindingErrorProcessor bindingErrorProcessor) {
this.bindingErrorProcessor = bindingErrorProcessor;
}
/**
* Return the strategy to use for processing binding errors.
*/
public final BindingErrorProcessor getBindingErrorProcessor() {
return this.bindingErrorProcessor;
}
/**
* Specify a single PropertyEditorRegistrar to be applied
* to every DataBinder that this controller uses.
*/
public final void setPropertyEditorRegistrar(PropertyEditorRegistrar propertyEditorRegistrar) {
this.propertyEditorRegistrars = new PropertyEditorRegistrar[] {propertyEditorRegistrar};
}
/**
* Specify multiple PropertyEditorRegistrars to be applied
* to every DataBinder that this controller uses.
*/
public final void setPropertyEditorRegistrars(PropertyEditorRegistrar[] propertyEditorRegistrars) {
this.propertyEditorRegistrars = propertyEditorRegistrars;
}
/**
* Return the PropertyEditorRegistrars to be applied
* to every DataBinder that this controller uses.
*/
public final PropertyEditorRegistrar[] getPropertyEditorRegistrars() {
return this.propertyEditorRegistrars;
}
public void initBinder(WebDataBinder binder, WebRequest request) {
if (this.directFieldAccess) {
binder.initDirectFieldAccess();
}
if (this.messageCodesResolver != null) {
binder.setMessageCodesResolver(this.messageCodesResolver);
}
if (this.bindingErrorProcessor != null) {
binder.setBindingErrorProcessor(this.bindingErrorProcessor);
}
if (this.propertyEditorRegistrars != null) {
for (int i = 0; i < this.propertyEditorRegistrars.length; i++) {
this.propertyEditorRegistrars[i].registerCustomEditors(binder);
}
}
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.util.Assert;
import org.springframework.web.context.request.WebRequest;
/**
* Default implementation of the {@link SessionAttributeStore} interface,
* storing the attributes in the WebRequest session (i.e. HttpSession
* or PortletSession).
*
* @author Juergen Hoeller
* @since 2.5
* @see #setAttributeNamePrefix
* @see org.springframework.web.context.request.WebRequest#setAttribute
* @see org.springframework.web.context.request.WebRequest#getAttribute
* @see org.springframework.web.context.request.WebRequest#removeAttribute
*/
public class DefaultSessionAttributeStore implements SessionAttributeStore {
private String attributeNamePrefix = "";
/**
* Specify a prefix to use for the attribute names in the backend session.
* <p>Default is to use no prefix, storing the session attributes with the
* same name as in the model.
*/
public void setAttributeNamePrefix(String attributeNamePrefix) {
this.attributeNamePrefix = (attributeNamePrefix != null ? attributeNamePrefix : "");
}
public void storeAttribute(WebRequest request, String attributeName, Object attributeValue) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
Assert.notNull(attributeValue, "Attribute value must not be null");
String storeAttributeName = getAttributeNameInSession(request, attributeName);
request.setAttribute(storeAttributeName, attributeValue, WebRequest.SCOPE_SESSION);
}
public Object retrieveAttribute(WebRequest request, String attributeName) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
String storeAttributeName = getAttributeNameInSession(request, attributeName);
return request.getAttribute(storeAttributeName, WebRequest.SCOPE_SESSION);
}
public void cleanupAttribute(WebRequest request, String attributeName) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
String storeAttributeName = getAttributeNameInSession(request, attributeName);
request.removeAttribute(storeAttributeName, WebRequest.SCOPE_SESSION);
}
/**
* Calculate the attribute name in the backend session.
* <p>The default implementation simply prepends the configured
* {@link #setAttributeNamePrefix "attributeNamePrefix"}, if any.
* @param request the current request
* @param attributeName the name of the attribute
* @return the attribute name in the backend session
*/
protected String getAttributeNameInSession(WebRequest request, String attributeName) {
return this.attributeNamePrefix + attributeName;
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.web.context.request.WebRequest;
/**
* Strategy interface for storing model attributes in a backend session.
*
* @author Juergen Hoeller
* @since 2.5
* @see org.springframework.web.bind.annotation.SessionAttributes
*/
public interface SessionAttributeStore {
/**
* Store the supplied attribute in the backend session.
* <p>Can be called for new attributes as well as for existing attributes.
* In the latter case, this signals that the attribute value may have been modified.
* @param request the current request
* @param attributeName the name of the attribute
* @param attributeValue the attribute value to store
*/
void storeAttribute(WebRequest request, String attributeName, Object attributeValue);
/**
* Retrieve the specified attribute from the backend session.
* <p>This will typically be called with the expectation that the
* attribute is already present, with an exception to be thrown
* if this method returns <code>null</code>.
* @param request the current request
* @param attributeName the name of the attribute
* @return the current attribute value, or <code>null</code> if none
*/
Object retrieveAttribute(WebRequest request, String attributeName);
/**
* Clean up the specified attribute in the backend session.
* <p>Indicates that the attribute name will not be used anymore.
* @param request the current request
* @param attributeName the name of the attribute
*/
void cleanupAttribute(WebRequest request, String attributeName);
}

View File

@ -1,47 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
/**
* Simple interface that can be injected into handler methods, allowing them to
* signal that their session processing is complete. The handler invoker may
* then follow up with appropriate cleanup, e.g. of session attributes which
* have been implicitly created during this handler's processing (according to
* the
* {@link org.springframework.web.bind.annotation.SessionAttributes @SessionAttributes}
* annotation).
*
* @author Juergen Hoeller
* @since 2.5
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.web.bind.annotation.SessionAttributes
*/
public interface SessionStatus {
/**
* Mark the current handler's session processing as complete, allowing for
* cleanup of session attributes.
*/
void setComplete();
/**
* Return whether the current handler's session processing has been marked
* as complete.
*/
boolean isComplete();
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
/**
* Simple implementation of the {@link SessionStatus} interface,
* keeping the <code>complete</code> flag as an instance variable.
*
* @author Juergen Hoeller
* @since 2.5
*/
public class SimpleSessionStatus implements SessionStatus {
private boolean complete = false;
public void setComplete() {
this.complete = true;
}
public boolean isComplete() {
return this.complete;
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
/**
* SPI for resolving custom arguments for a specific handler method parameter.
* Typically implemented to detect special parameter types, resolving
* well-known argument values for them.
*
* <p>A typical implementation could look like as follows:
*
* <pre class="code">
* public class MySpecialArgumentResolver implements WebArgumentResolver {
*
* public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) {
* if (methodParameter.getParameterType().equals(MySpecialArg.class)) {
* return new MySpecialArg("myValue");
* }
* return UNRESOLVED;
* }
* }</pre>
*
* @author Juergen Hoeller
* @since 2.5.2
* @see org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#setCustomArgumentResolvers
* @see org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter#setCustomArgumentResolvers
*/
public interface WebArgumentResolver {
/**
* Marker to be returned when the resolver does not know how to
* handle the given method parameter.
*/
Object UNRESOLVED = new Object();
/**
* Resolve an argument for the given handler method parameter within the given web request.
* @param methodParameter the handler method parameter to resolve
* @param webRequest the current web request, allowing access to the native request as well
* @return the argument value, or <code>UNRESOLVED</code> if not resolvable
* @throws Exception in case of resolution failure
*/
Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception;
}

View File

@ -1,38 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.WebRequest;
/**
* Callback interface for initializing a {@link org.springframework.web.bind.WebDataBinder}
* for performing data binding in the context of a specific web request.
*
* @author Juergen Hoeller
* @since 2.5
*/
public interface WebBindingInitializer {
/**
* Initialize the given DataBinder for the given request.
* @param binder the DataBinder to initialize
* @param request the web request that the data binding happens within
*/
void initBinder(WebDataBinder binder, WebRequest request);
}

View File

@ -1,125 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.support;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.validation.BindException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartRequest;
/**
* Special {@link org.springframework.validation.DataBinder} to perform data binding
* from web request parameters to JavaBeans, including support for multipart files.
*
* <p>See the DataBinder/WebDataBinder superclasses for customization options,
* which include specifying allowed/required fields, and registering custom
* property editors.
*
* <p>Can also used for manual data binding in custom web controllers or interceptors
* that build on Spring's {@link org.springframework.web.context.request.WebRequest}
* abstraction: e.g. in a {@link org.springframework.web.context.request.WebRequestInterceptor}
* implementation. Simply instantiate a WebRequestDataBinder for each binding
* process, and invoke <code>bind</code> with the current WebRequest as argument:
*
* <pre class="code">
* MyBean myBean = new MyBean();
* // apply binder to custom target object
* WebRequestDataBinder binder = new WebRequestDataBinder(myBean);
* // register custom editors, if desired
* binder.registerCustomEditor(...);
* // trigger actual binding of request parameters
* binder.bind(request);
* // optionally evaluate binding errors
* Errors errors = binder.getErrors();
* ...</pre>
*
* @author Juergen Hoeller
* @since 2.5.2
* @see #bind(org.springframework.web.context.request.WebRequest)
* @see #registerCustomEditor
* @see #setAllowedFields
* @see #setRequiredFields
* @see #setFieldMarkerPrefix
*/
public class WebRequestDataBinder extends WebDataBinder {
/**
* Create a new WebRequestDataBinder instance, with default object name.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @see #DEFAULT_OBJECT_NAME
*/
public WebRequestDataBinder(Object target) {
super(target);
}
/**
* Create a new WebRequestDataBinder instance.
* @param target the target object to bind onto (or <code>null</code>
* if the binder is just used to convert a plain parameter value)
* @param objectName the name of the target object
*/
public WebRequestDataBinder(Object target, String objectName) {
super(target, objectName);
}
/**
* Bind the parameters of the given request to this binder's target,
* also binding multipart files in case of a multipart request.
* <p>This call can create field errors, representing basic binding
* errors like a required field (code "required"), or type mismatch
* between value and bean property (code "typeMismatch").
* <p>Multipart files are bound via their parameter name, just like normal
* HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property,
* invoking a "setUploadedFile" setter method.
* <p>The type of the target property for a multipart file can be MultipartFile,
* byte[], or String. The latter two receive the contents of the uploaded file;
* all metadata like original file name, content type, etc are lost in those cases.
* @param request request with parameters to bind (can be multipart)
* @see org.springframework.web.multipart.MultipartRequest
* @see org.springframework.web.multipart.MultipartFile
* @see #bindMultipartFiles
* @see #bind(org.springframework.beans.PropertyValues)
*/
public void bind(WebRequest request) {
MutablePropertyValues mpvs = new MutablePropertyValues(request.getParameterMap());
if (request instanceof NativeWebRequest) {
Object nativeRequest = ((NativeWebRequest) request).getNativeRequest();
if (nativeRequest instanceof MultipartRequest) {
MultipartRequest multipartRequest = (MultipartRequest) request;
bindMultipartFiles(multipartRequest.getFileMap(), mpvs);
}
}
doBind(mpvs);
}
/**
* Treats errors as fatal.
* <p>Use this method only if it's an error if the input isn't valid.
* This might be appropriate if all input is from dropdowns, for example.
* @throws BindException if binding errors have been encountered
*/
public void closeNoCatch() throws BindException {
if (getBindingResult().hasErrors()) {
throw new BindException(getBindingResult());
}
}
}

View File

@ -1,8 +0,0 @@
/**
*
* Support classes for web data binding.
*
*/
package org.springframework.web.bind.support;

View File

@ -1,57 +0,0 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
/**
* MultipartException subclass thrown when an upload exceeds the
* maximum upload size allowed.
*
* @author Juergen Hoeller
* @since 1.0.1
*/
public class MaxUploadSizeExceededException extends MultipartException {
private final long maxUploadSize;
/**
* Constructor for MaxUploadSizeExceededException.
* @param maxUploadSize the maximum upload size allowed
*/
public MaxUploadSizeExceededException(long maxUploadSize) {
this(maxUploadSize, null);
}
/**
* Constructor for MaxUploadSizeExceededException.
* @param maxUploadSize the maximum upload size allowed
* @param ex root cause from multipart parsing API in use
*/
public MaxUploadSizeExceededException(long maxUploadSize, Throwable ex) {
super("Maximum upload size of " + maxUploadSize + " bytes exceeded", ex);
this.maxUploadSize = maxUploadSize;
}
/**
* Return the maximum upload size allowed.
*/
public long getMaxUploadSize() {
return maxUploadSize;
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
import org.springframework.core.NestedRuntimeException;
/**
* Exception thrown when multipart resolution fails.
*
* @author Trevor D. Cook
* @author Juergen Hoeller
* @since 29.09.2003
* @see MultipartResolver#resolveMultipart
* @see org.springframework.web.multipart.support.MultipartFilter
*/
public class MultipartException extends NestedRuntimeException {
/**
* Constructor for MultipartException.
* @param msg the detail message
*/
public MultipartException(String msg) {
super(msg);
}
/**
* Constructor for MultipartException.
* @param msg the detail message
* @param cause the root cause from the multipart parsing API in use
*/
public MultipartException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@ -1,103 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* A representation of an uploaded file received in a multipart request.
*
* <p>The file contents are either stored in memory or temporarily on disk.
* In either case, the user is responsible for copying file contents to a
* session-level or persistent store as and if desired. The temporary storages
* will be cleared at the end of request processing.
*
* @author Juergen Hoeller
* @author Trevor D. Cook
* @since 29.09.2003
* @see org.springframework.web.multipart.MultipartHttpServletRequest
* @see org.springframework.web.multipart.MultipartResolver
*/
public interface MultipartFile {
/**
* Return the name of the parameter in the multipart form.
* @return the name of the parameter (never <code>null</code> or empty)
*/
String getName();
/**
* Return the original filename in the client's filesystem.
* <p>This may contain path information depending on the browser used,
* but it typically will not with any other than Opera.
* @return the original filename, or the empty String if no file
* has been chosen in the multipart form
*/
String getOriginalFilename();
/**
* Return the content type of the file.
* @return the content type, or <code>null</code> if not defined
* (or no file has been chosen in the multipart form)
*/
String getContentType();
/**
* Return whether the uploaded file is empty, that is, either no file has
* been chosen in the multipart form or the chosen file has no content.
*/
boolean isEmpty();
/**
* Return the size of the file in bytes.
* @return the size of the file, or 0 if empty
*/
long getSize();
/**
* Return the contents of the file as an array of bytes.
* @return the contents of the file as bytes, or an empty byte array if empty
* @throws IOException in case of access errors (if the temporary store fails)
*/
byte[] getBytes() throws IOException;
/**
* Return an InputStream to read the contents of the file from.
* The user is responsible for closing the stream.
* @return the contents of the file as stream, or an empty stream if empty
* @throws IOException in case of access errors (if the temporary store fails)
*/
InputStream getInputStream() throws IOException;
/**
* Transfer the received file to the given destination file.
* <p>This may either move the file in the filesystem, copy the file in the
* filesystem, or save memory-held contents to the destination file.
* If the destination file already exists, it will be deleted first.
* <p>If the file has been moved in the filesystem, this operation cannot
* be invoked again. Therefore, call this method just once to be able to
* work with any storage mechanism.
* @param dest the destination file
* @throws IOException in case of reading or writing errors
* @throws IllegalStateException if the file has already been moved
* in the filesystem and is not available anymore for another transfer
*/
void transferTo(File dest) throws IOException, IllegalStateException;
}

View File

@ -1,47 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
import javax.servlet.http.HttpServletRequest;
/**
* Provides additional methods for dealing with multipart content within a
* servlet request, allowing to access uploaded files.
* Implementations also need to override the standard
* {@link javax.servlet.ServletRequest} methods for parameter access, making
* multipart parameters available.
*
* <p>A concrete implementation is
* {@link org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest}.
* As an intermediate step,
* {@link org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest}
* can be subclassed.
*
* @author Juergen Hoeller
* @author Trevor D. Cook
* @since 29.09.2003
* @see MultipartResolver
* @see MultipartFile
* @see javax.servlet.http.HttpServletRequest#getParameter
* @see javax.servlet.http.HttpServletRequest#getParameterNames
* @see javax.servlet.http.HttpServletRequest#getParameterMap
* @see org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest
* @see org.springframework.web.multipart.support.AbstractMultipartHttpServletRequest
*/
public interface MultipartHttpServletRequest extends HttpServletRequest, MultipartRequest {
}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
import java.util.Iterator;
import java.util.Map;
/**
* This interface defines the multipart request access operations
* that are exposed for actual multipart requests. It is extended
* by {@link MultipartHttpServletRequest} and the Portlet
* {@link org.springframework.web.portlet.multipart.MultipartActionRequest}.
*
* @author Juergen Hoeller
* @since 2.5.2
*/
public interface MultipartRequest {
/**
* Return an {@link java.util.Iterator} of String objects containing the
* parameter names of the multipart files contained in this request. These
* are the field names of the form (like with normal parameters), not the
* original file names.
* @return the names of the files
*/
Iterator<String> getFileNames();
/**
* Return the contents plus description of an uploaded file in this request,
* or <code>null</code> if it does not exist.
* @param name a String specifying the parameter name of the multipart file
* @return the uploaded content in the form of a {@link org.springframework.web.multipart.MultipartFile} object
*/
MultipartFile getFile(String name);
/**
* Return a {@link java.util.Map} of the multipart files contained in this request.
* @return a map containing the parameter names as keys, and the
* {@link org.springframework.web.multipart.MultipartFile} objects as values
* @see MultipartFile
*/
Map<String, MultipartFile> getFileMap();
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart;
import javax.servlet.http.HttpServletRequest;
/**
* A strategy interface for multipart file upload resolution in accordance
* with <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>.
* Implementations are typically usable both within an application context
* and standalone.
*
* <p>There is only one concrete implementation included in Spring,
* as of Spring 2.5:
* <ul>
* <li>{@link org.springframework.web.multipart.commons.CommonsMultipartResolver} for Jakarta Commons FileUpload
* </ul>
*
* <p>There is no default resolver implementation used for Spring
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlets},
* as an application might choose to parse its multipart requests itself. To define
* an implementation, create a bean with the id "multipartResolver" in a
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet's}
* application context. Such a resolver gets applied to all requests handled
* by that {@link org.springframework.web.servlet.DispatcherServlet}.
*
* <p>If a {@link org.springframework.web.servlet.DispatcherServlet} detects
* a multipart request, it will resolve it via the configured
* {@link org.springframework.web.multipart.MultipartResolver} and pass on a
* wrapped {@link javax.servlet.http.HttpServletRequest}.
* Controllers can then cast their given request to the
* {@link org.springframework.web.multipart.MultipartHttpServletRequest}
* interface, which permits access to any
* {@link org.springframework.web.multipart.MultipartFile MultipartFiles}.
* Note that this cast is only supported in case of an actual multipart request.
*
* <pre class="code">
* public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
* MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
* MultipartFile multipartFile = multipartRequest.getFile("image");
* ...
* }</pre>
*
* Instead of direct access, command or form controllers can register a
* {@link org.springframework.web.multipart.support.ByteArrayMultipartFileEditor}
* or {@link org.springframework.web.multipart.support.StringMultipartFileEditor}
* with their data binder, to automatically apply multipart content to command
* bean properties.
*
* <p>As an alternative to using a
* {@link org.springframework.web.multipart.MultipartResolver} with a
* {@link org.springframework.web.servlet.DispatcherServlet},
* a {@link org.springframework.web.multipart.support.MultipartFilter} can be
* registered in <code>web.xml</code>. It will delegate to a corresponding
* {@link org.springframework.web.multipart.MultipartResolver} bean in the root
* application context. This is mainly intended for applications that do not
* use Spring's own web MVC framework.
*
* <p>Note: There is hardly ever a need to access the
* {@link org.springframework.web.multipart.MultipartResolver} itself
* from application code. It will simply do its work behind the scenes,
* making
* {@link org.springframework.web.multipart.MultipartHttpServletRequest MultipartHttpServletRequests}
* available to controllers.
*
* @author Juergen Hoeller
* @author Trevor D. Cook
* @since 29.09.2003
* @see MultipartHttpServletRequest
* @see MultipartFile
* @see org.springframework.web.multipart.commons.CommonsMultipartResolver
* @see org.springframework.web.multipart.support.ByteArrayMultipartFileEditor
* @see org.springframework.web.multipart.support.StringMultipartFileEditor
* @see org.springframework.web.servlet.DispatcherServlet
*/
public interface MultipartResolver {
/**
* Determine if the given request contains multipart content.
* <p>Will typically check for content type "multipart/form-data", but the actually
* accepted requests might depend on the capabilities of the resolver implementation.
* @param request the servlet request to be evaluated
* @return whether the request contains multipart content
*/
boolean isMultipart(HttpServletRequest request);
/**
* Parse the given HTTP request into multipart files and parameters,
* and wrap the request inside a
* {@link org.springframework.web.multipart.MultipartHttpServletRequest} object
* that provides access to file descriptors and makes contained
* parameters accessible via the standard ServletRequest methods.
* @param request the servlet request to wrap (must be of a multipart content type)
* @return the wrapped servlet request
* @throws MultipartException if the servlet request is not multipart, or if
* implementation-specific problems are encountered (such as exceeding file size limits)
* @see MultipartHttpServletRequest#getFile
* @see MultipartHttpServletRequest#getFileNames
* @see MultipartHttpServletRequest#getFileMap
* @see javax.servlet.http.HttpServletRequest#getParameter
* @see javax.servlet.http.HttpServletRequest#getParameterNames
* @see javax.servlet.http.HttpServletRequest#getParameterMap
*/
MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
/**
* Cleanup any resources used for the multipart handling,
* like a storage for the uploaded files.
* @param request the request to cleanup resources for
*/
void cleanupMultipart(MultipartHttpServletRequest request);
}

View File

@ -1,322 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.commons;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.WebUtils;
/**
* Base class for multipart resolvers that use Jakarta Commons FileUpload
* 1.1 or higher.
*
* <p>Provides common configuration properties and parsing functionality
* for multipart requests, using a Map of Spring CommonsMultipartFile instances
* as representation of uploaded files and a String-based parameter Map as
* representation of uploaded form fields.
*
* <p>Subclasses implement concrete resolution strategies for Servlet or Portlet
* environments: see CommonsMultipartResolver and CommonsPortletMultipartResolver,
* respectively. This base class is not tied to either of those APIs, factoring
* out common functionality.
*
* @author Juergen Hoeller
* @since 2.0
* @see CommonsMultipartFile
* @see CommonsMultipartResolver
* @see org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver
*/
public abstract class CommonsFileUploadSupport {
protected final Log logger = LogFactory.getLog(getClass());
private final DiskFileItemFactory fileItemFactory;
private final FileUpload fileUpload;
private boolean uploadTempDirSpecified = false;
/**
* Instantiate a new CommonsFileUploadSupport with its
* corresponding FileItemFactory and FileUpload instances.
* @see #newFileItemFactory
* @see #newFileUpload
*/
public CommonsFileUploadSupport() {
this.fileItemFactory = newFileItemFactory();
this.fileUpload = newFileUpload(getFileItemFactory());
}
/**
* Return the underlying <code>org.apache.commons.fileupload.disk.DiskFileItemFactory</code>
* instance. There is hardly any need to access this.
* @return the underlying DiskFileItemFactory instance
*/
public DiskFileItemFactory getFileItemFactory() {
return this.fileItemFactory;
}
/**
* Return the underlying <code>org.apache.commons.fileupload.FileUpload</code>
* instance. There is hardly any need to access this.
* @return the underlying FileUpload instance
*/
public FileUpload getFileUpload() {
return this.fileUpload;
}
/**
* Set the maximum allowed size (in bytes) before uploads are refused.
* -1 indicates no limit (the default).
* @param maxUploadSize the maximum upload size allowed
* @see org.apache.commons.fileupload.FileUploadBase#setSizeMax
*/
public void setMaxUploadSize(long maxUploadSize) {
this.fileUpload.setSizeMax(maxUploadSize);
}
/**
* Set the maximum allowed size (in bytes) before uploads are written to disk.
* Uploaded files will still be received past this amount, but they will not be
* stored in memory. Default is 10240, according to Commons FileUpload.
* @param maxInMemorySize the maximum in memory size allowed
* @see org.apache.commons.fileupload.disk.DiskFileItemFactory#setSizeThreshold
*/
public void setMaxInMemorySize(int maxInMemorySize) {
this.fileItemFactory.setSizeThreshold(maxInMemorySize);
}
/**
* Set the default character encoding to use for parsing requests,
* to be applied to headers of individual parts and to form fields.
* Default is ISO-8859-1, according to the Servlet spec.
* <p>If the request specifies a character encoding itself, the request
* encoding will override this setting. This also allows for generically
* overriding the character encoding in a filter that invokes the
* <code>ServletRequest.setCharacterEncoding</code> method.
* @param defaultEncoding the character encoding to use
* @see javax.servlet.ServletRequest#getCharacterEncoding
* @see javax.servlet.ServletRequest#setCharacterEncoding
* @see WebUtils#DEFAULT_CHARACTER_ENCODING
* @see org.apache.commons.fileupload.FileUploadBase#setHeaderEncoding
*/
public void setDefaultEncoding(String defaultEncoding) {
this.fileUpload.setHeaderEncoding(defaultEncoding);
}
protected String getDefaultEncoding() {
String encoding = getFileUpload().getHeaderEncoding();
if (encoding == null) {
encoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
}
return encoding;
}
/**
* Set the temporary directory where uploaded files get stored.
* Default is the servlet container's temporary directory for the web application.
* @see org.springframework.web.util.WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE
*/
public void setUploadTempDir(Resource uploadTempDir) throws IOException {
if (!uploadTempDir.exists() && !uploadTempDir.getFile().mkdirs()) {
throw new IllegalArgumentException("Given uploadTempDir [" + uploadTempDir + "] could not be created");
}
this.fileItemFactory.setRepository(uploadTempDir.getFile());
this.uploadTempDirSpecified = true;
}
protected boolean isUploadTempDirSpecified() {
return this.uploadTempDirSpecified;
}
/**
* Factory method for a Commons DiskFileItemFactory instance.
* <p>Default implementation returns a standard DiskFileItemFactory.
* Can be overridden to use a custom subclass, e.g. for testing purposes.
* @return the new DiskFileItemFactory instance
*/
protected DiskFileItemFactory newFileItemFactory() {
return new DiskFileItemFactory();
}
/**
* Factory method for a Commons FileUpload instance.
* <p><b>To be implemented by subclasses.</b>
* @param fileItemFactory the Commons FileItemFactory to build upon
* @return the Commons FileUpload instance
*/
protected abstract FileUpload newFileUpload(FileItemFactory fileItemFactory);
/**
* Determine an appropriate FileUpload instance for the given encoding.
* <p>Default implementation returns the shared FileUpload instance
* if the encoding matches, else creates a new FileUpload instance
* with the same configuration other than the desired encoding.
* @param encoding the character encoding to use
* @return an appropriate FileUpload instance.
*/
protected FileUpload prepareFileUpload(String encoding) {
FileUpload fileUpload = getFileUpload();
FileUpload actualFileUpload = fileUpload;
// Use new temporary FileUpload instance if the request specifies
// its own encoding that does not match the default encoding.
if (encoding != null && !encoding.equals(fileUpload.getHeaderEncoding())) {
actualFileUpload = newFileUpload(getFileItemFactory());
actualFileUpload.setSizeMax(fileUpload.getSizeMax());
actualFileUpload.setHeaderEncoding(encoding);
}
return actualFileUpload;
}
/**
* Parse the given List of Commons FileItems into a Spring MultipartParsingResult,
* containing Spring MultipartFile instances and a Map of multipart parameter.
* @param fileItems the Commons FileIterms to parse
* @param encoding the encoding to use for form fields
* @return the Spring MultipartParsingResult
* @see CommonsMultipartFile#CommonsMultipartFile(org.apache.commons.fileupload.FileItem)
*/
protected MultipartParsingResult parseFileItems(List<FileItem> fileItems, String encoding) {
Map<String, MultipartFile> multipartFiles = new HashMap<String, MultipartFile>();
Map<String, String[]> multipartParameters = new HashMap<String, String[]>();
// Extract multipart files and multipart parameters.
for (FileItem fileItem : fileItems) {
if (fileItem.isFormField()) {
String value = null;
if (encoding != null) {
try {
value = fileItem.getString(encoding);
}
catch (UnsupportedEncodingException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Could not decode multipart item '" + fileItem.getFieldName() +
"' with encoding '" + encoding + "': using platform default");
}
value = fileItem.getString();
}
}
else {
value = fileItem.getString();
}
String[] curParam = multipartParameters.get(fileItem.getFieldName());
if (curParam == null) {
// simple form field
multipartParameters.put(fileItem.getFieldName(), new String[] {value});
}
else {
// array of simple form fields
String[] newParam = StringUtils.addStringToArray(curParam, value);
multipartParameters.put(fileItem.getFieldName(), newParam);
}
}
else {
// multipart file field
CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
if (multipartFiles.put(file.getName(), file) != null) {
throw new MultipartException("Multiple files for field name [" + file.getName() +
"] found - not supported by MultipartResolver");
}
if (logger.isDebugEnabled()) {
logger.debug("Found multipart file [" + file.getName() + "] of size " + file.getSize() +
" bytes with original filename [" + file.getOriginalFilename() + "], stored " +
file.getStorageDescription());
}
}
}
return new MultipartParsingResult(multipartFiles, multipartParameters);
}
/**
* Cleanup the Spring MultipartFiles created during multipart parsing,
* potentially holding temporary data on disk.
* <p>Deletes the underlying Commons FileItem instances.
* @param multipartFiles Collection of MultipartFile instances
* @see org.apache.commons.fileupload.FileItem#delete()
*/
protected void cleanupFileItems(Collection<MultipartFile> multipartFiles) {
for (MultipartFile file : multipartFiles) {
if (file instanceof CommonsMultipartFile) {
CommonsMultipartFile cmf = (CommonsMultipartFile) file;
cmf.getFileItem().delete();
if (logger.isDebugEnabled()) {
logger.debug("Cleaning up multipart file [" + cmf.getName() + "] with original filename [" +
cmf.getOriginalFilename() + "], stored " + cmf.getStorageDescription());
}
}
}
}
/**
* Holder for a Map of Spring MultipartFiles and a Map of
* multipart parameters.
*/
protected static class MultipartParsingResult {
private final Map<String, MultipartFile> multipartFiles;
private final Map<String, String[]> multipartParameters;
/**
* Create a new MultipartParsingResult.
* @param mpFiles Map of field name to MultipartFile instance
* @param mpParams Map of field name to form field String value
*/
public MultipartParsingResult(Map<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
this.multipartFiles = mpFiles;
this.multipartParameters = mpParams;
}
/**
* Return the multipart files as Map of field name to MultipartFile instance.
*/
public Map<String, MultipartFile> getMultipartFiles() {
return this.multipartFiles;
}
/**
* Return the multipart parameters as Map of field name to form field String value.
*/
public Map<String, String[]> getMultipartParameters() {
return this.multipartParameters;
}
}
}

View File

@ -1,194 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.commons;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.multipart.MultipartFile;
/**
* MultipartFile implementation for Jakarta Commons FileUpload.
*
* <p><b>NOTE:</b> As of Spring 2.0, this class requires Commons FileUpload 1.1
* or higher. The implementation does not use any deprecated FileUpload 1.0 API
* anymore, to be compatible with future Commons FileUpload releases.
*
* @author Trevor D. Cook
* @author Juergen Hoeller
* @since 29.09.2003
* @see CommonsMultipartResolver
*/
public class CommonsMultipartFile implements MultipartFile, Serializable {
protected static final Log logger = LogFactory.getLog(CommonsMultipartFile.class);
private final FileItem fileItem;
private final long size;
/**
* Create an instance wrapping the given FileItem.
* @param fileItem the FileItem to wrap
*/
public CommonsMultipartFile(FileItem fileItem) {
this.fileItem = fileItem;
this.size = this.fileItem.getSize();
}
/**
* Return the underlying <code>org.apache.commons.fileupload.FileItem</code>
* instance. There is hardly any need to access this.
*/
public final FileItem getFileItem() {
return this.fileItem;
}
public String getName() {
return this.fileItem.getFieldName();
}
public String getOriginalFilename() {
String filename = this.fileItem.getName();
if (filename == null) {
// Should never happen.
return "";
}
// check for Unix-style path
int pos = filename.lastIndexOf("/");
if (pos == -1) {
// check for Windows-style path
pos = filename.lastIndexOf("\\");
}
if (pos != -1) {
// any sort of path separator found
return filename.substring(pos + 1);
}
else {
// plain name
return filename;
}
}
public String getContentType() {
return this.fileItem.getContentType();
}
public boolean isEmpty() {
return (this.size == 0);
}
public long getSize() {
return this.size;
}
public byte[] getBytes() {
if (!isAvailable()) {
throw new IllegalStateException("File has been moved - cannot be read again");
}
byte[] bytes = this.fileItem.get();
return (bytes != null ? bytes : new byte[0]);
}
public InputStream getInputStream() throws IOException {
if (!isAvailable()) {
throw new IllegalStateException("File has been moved - cannot be read again");
}
InputStream inputStream = this.fileItem.getInputStream();
return (inputStream != null ? inputStream : new ByteArrayInputStream(new byte[0]));
}
public void transferTo(File dest) throws IOException, IllegalStateException {
if (!isAvailable()) {
throw new IllegalStateException("File has already been moved - cannot be transferred again");
}
if (dest.exists() && !dest.delete()) {
throw new IOException(
"Destination file [" + dest.getAbsolutePath() + "] already exists and could not be deleted");
}
try {
this.fileItem.write(dest);
if (logger.isDebugEnabled()) {
String action = "transferred";
if (!this.fileItem.isInMemory()) {
action = isAvailable() ? "copied" : "moved";
}
logger.debug("Multipart file '" + getName() + "' with original filename [" +
getOriginalFilename() + "], stored " + getStorageDescription() + ": " +
action + " to [" + dest.getAbsolutePath() + "]");
}
}
catch (FileUploadException ex) {
throw new IllegalStateException(ex.getMessage());
}
catch (IOException ex) {
throw ex;
}
catch (Exception ex) {
logger.error("Could not transfer to file", ex);
throw new IOException("Could not transfer to file: " + ex.getMessage());
}
}
/**
* Determine whether the multipart content is still available.
* If a temporary file has been moved, the content is no longer available.
*/
protected boolean isAvailable() {
// If in memory, it's available.
if (this.fileItem.isInMemory()) {
return true;
}
// Check actual existence of temporary file.
if (this.fileItem instanceof DiskFileItem) {
return ((DiskFileItem) this.fileItem).getStoreLocation().exists();
}
// Check whether current file size is different than original one.
return (this.fileItem.getSize() == this.size);
}
/**
* Return a description for the storage location of the multipart content.
* Tries to be as specific as possible: mentions the file location in case
* of a temporary file.
*/
public String getStorageDescription() {
if (this.fileItem.isInMemory()) {
return "in memory";
}
else if (this.fileItem instanceof DiskFileItem) {
return "at [" + ((DiskFileItem) this.fileItem).getStoreLocation().getAbsolutePath() + "]";
}
else {
return "on disk";
}
}
}

View File

@ -1,195 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.commons;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.util.Assert;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest;
import org.springframework.web.util.WebUtils;
/**
* Servlet-based {@link org.springframework.web.multipart.MultipartResolver} implementation
* for <a href="http://jakarta.apache.org/commons/fileupload">Jakarta Commons FileUpload</a>
* 1.2 or above.
*
* <p>Provides "maxUploadSize", "maxInMemorySize" and "defaultEncoding" settings as
* bean properties (inherited from {@link CommonsFileUploadSupport}). See corresponding
* ServletFileUpload / DiskFileItemFactory properties ("sizeMax", "sizeThreshold",
* "headerEncoding") for details in terms of defaults and accepted values.
*
* <p>Saves temporary files to the servlet container's temporary directory.
* Needs to be initialized <i>either</i> by an application context <i>or</i>
* via the constructor that takes a ServletContext (for standalone usage).
*
* @author Trevor D. Cook
* @author Juergen Hoeller
* @since 29.09.2003
* @see #CommonsMultipartResolver(ServletContext)
* @see #setResolveLazily
* @see org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver
* @see org.apache.commons.fileupload.servlet.ServletFileUpload
* @see org.apache.commons.fileupload.disk.DiskFileItemFactory
*/
public class CommonsMultipartResolver extends CommonsFileUploadSupport
implements MultipartResolver, ServletContextAware {
private boolean resolveLazily = false;
/**
* Constructor for use as bean. Determines the servlet container's
* temporary directory via the ServletContext passed in as through the
* ServletContextAware interface (typically by a WebApplicationContext).
* @see #setServletContext
* @see org.springframework.web.context.ServletContextAware
* @see org.springframework.web.context.WebApplicationContext
*/
public CommonsMultipartResolver() {
super();
}
/**
* Constructor for standalone usage. Determines the servlet container's
* temporary directory via the given ServletContext.
* @param servletContext the ServletContext to use
*/
public CommonsMultipartResolver(ServletContext servletContext) {
this();
setServletContext(servletContext);
}
/**
* Set whether to resolve the multipart request lazily at the time of
* file or parameter access.
* <p>Default is "false", resolving the multipart elements immediately, throwing
* corresponding exceptions at the time of the {@link #resolveMultipart} call.
* Switch this to "true" for lazy multipart parsing, throwing parse exceptions
* once the application attempts to obtain multipart files or parameters.
*/
public void setResolveLazily(boolean resolveLazily) {
this.resolveLazily = resolveLazily;
}
/**
* Initialize the underlying <code>org.apache.commons.fileupload.servlet.ServletFileUpload</code>
* instance. Can be overridden to use a custom subclass, e.g. for testing purposes.
* @param fileItemFactory the Commons FileItemFactory to use
* @return the new ServletFileUpload instance
*/
@Override
protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
return new ServletFileUpload(fileItemFactory);
}
public void setServletContext(ServletContext servletContext) {
if (!isUploadTempDirSpecified()) {
getFileItemFactory().setRepository(WebUtils.getTempDir(servletContext));
}
}
public boolean isMultipart(HttpServletRequest request) {
return (request != null && ServletFileUpload.isMultipartContent(request));
}
public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
Assert.notNull(request, "Request must not be null");
if (this.resolveLazily) {
return new DefaultMultipartHttpServletRequest(request) {
@Override
protected void initializeMultipart() {
MultipartParsingResult parsingResult = parseRequest(request);
setMultipartFiles(parsingResult.getMultipartFiles());
setMultipartParameters(parsingResult.getMultipartParameters());
}
};
}
else {
MultipartParsingResult parsingResult = parseRequest(request);
return new DefaultMultipartHttpServletRequest(
request, parsingResult.getMultipartFiles(), parsingResult.getMultipartParameters());
}
}
/**
* Parse the given servlet request, resolving its multipart elements.
* @param request the request to parse
* @return the parsing result
* @throws MultipartException if multipart resolution failed.
*/
@SuppressWarnings("unchecked")
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
try {
List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
return parseFileItems(fileItems, encoding);
}
catch (FileUploadBase.SizeLimitExceededException ex) {
throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
}
catch (FileUploadException ex) {
throw new MultipartException("Could not parse multipart servlet request", ex);
}
}
/**
* Determine the encoding for the given request.
* Can be overridden in subclasses.
* <p>The default implementation checks the request encoding,
* falling back to the default encoding specified for this resolver.
* @param request current HTTP request
* @return the encoding for the request (never <code>null</code>)
* @see javax.servlet.ServletRequest#getCharacterEncoding
* @see #setDefaultEncoding
*/
protected String determineEncoding(HttpServletRequest request) {
String encoding = request.getCharacterEncoding();
if (encoding == null) {
encoding = getDefaultEncoding();
}
return encoding;
}
public void cleanupMultipart(MultipartHttpServletRequest request) {
if (request != null) {
try {
cleanupFileItems(request.getFileMap().values());
}
catch (Throwable ex) {
logger.warn("Failed to perform multipart cleanup for servlet request", ex);
}
}
}
}

View File

@ -1,9 +0,0 @@
/**
*
* MultipartResolver implementation for
* <a href="http://jakarta.apache.org/commons/fileupload">Jakarta Commons FileUpload</a>.
*
*/
package org.springframework.web.multipart.commons;

View File

@ -1,11 +0,0 @@
/**
*
* Multipart resolution framework for handling file uploads.
* Provides a MultipartResolver strategy interface,
* and a generic extension of the HttpServletRequest interface
* for accessing multipart files in web application code.
*
*/
package org.springframework.web.multipart;

View File

@ -1,92 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
* Abstract base implementation of the MultipartHttpServletRequest interface.
* Provides management of pre-generated MultipartFile instances.
*
* @author Juergen Hoeller
* @since 06.10.2003
*/
public abstract class AbstractMultipartHttpServletRequest extends HttpServletRequestWrapper
implements MultipartHttpServletRequest {
private Map<String, MultipartFile> multipartFiles;
/**
* Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
* @param request the request to wrap
*/
protected AbstractMultipartHttpServletRequest(HttpServletRequest request) {
super(request);
}
public Iterator<String> getFileNames() {
return getMultipartFiles().keySet().iterator();
}
public MultipartFile getFile(String name) {
return getMultipartFiles().get(name);
}
public Map<String, MultipartFile> getFileMap() {
return getMultipartFiles();
}
/**
* Set a Map with parameter names as keys and MultipartFile objects as values.
* To be invoked by subclasses on initialization.
*/
protected final void setMultipartFiles(Map<String, MultipartFile> multipartFiles) {
this.multipartFiles = Collections.unmodifiableMap(multipartFiles);
}
/**
* Obtain the MultipartFile Map for retrieval,
* lazily initializing it if necessary.
* @see #initializeMultipart()
*/
protected Map<String, MultipartFile> getMultipartFiles() {
if (this.multipartFiles == null) {
initializeMultipart();
}
return this.multipartFiles;
}
/**
* Lazily initialize the multipart request, if possible.
* Only called if not already eagerly initialized.
*/
protected void initializeMultipart() {
throw new IllegalStateException("Multipart request not initialized");
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.io.IOException;
import org.springframework.beans.propertyeditors.ByteArrayPropertyEditor;
import org.springframework.web.multipart.MultipartFile;
/**
* Custom {@link java.beans.PropertyEditor} for converting
* {@link MultipartFile MultipartFiles} to byte arrays.
*
* @author Juergen Hoeller
* @since 13.10.2003
*/
public class ByteArrayMultipartFileEditor extends ByteArrayPropertyEditor {
@Override
public void setValue(Object value) {
if (value instanceof MultipartFile) {
MultipartFile multipartFile = (MultipartFile) value;
try {
super.setValue(multipartFile.getBytes());
}
catch (IOException ex) {
throw new IllegalArgumentException("Cannot read contents of multipart file", ex);
}
}
else if (value instanceof byte[]) {
super.setValue(value);
}
else {
super.setValue(value != null ? value.toString().getBytes() : null);
}
}
@Override
public String getAsText() {
byte[] value = (byte[]) getValue();
return (value != null ? new String(value) : "");
}
}

View File

@ -1,127 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.multipart.MultipartFile;
/**
* Default implementation of the
* {@link org.springframework.web.multipart.MultipartHttpServletRequest}
* interface. Provides management of pre-generated parameter values.
*
* @author Trevor D. Cook
* @author Juergen Hoeller
* @since 29.09.2003
* @see org.springframework.web.multipart.MultipartResolver
*/
public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
private Map<String, String[]> multipartParameters;
/**
* Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
* @param request the servlet request to wrap
* @param mpFiles a map of the multipart files
* @param mpParams a map of the parameters to expose,
* with Strings as keys and String arrays as values
*/
public DefaultMultipartHttpServletRequest(
HttpServletRequest request, Map<String, MultipartFile> mpFiles, Map<String, String[]> mpParams) {
super(request);
setMultipartFiles(mpFiles);
setMultipartParameters(mpParams);
}
/**
* Wrap the given HttpServletRequest in a MultipartHttpServletRequest.
* @param request the servlet request to wrap
*/
public DefaultMultipartHttpServletRequest(HttpServletRequest request) {
super(request);
}
@Override
public Enumeration<String> getParameterNames() {
Set<String> paramNames = new HashSet<String>();
Enumeration paramEnum = super.getParameterNames();
while (paramEnum.hasMoreElements()) {
paramNames.add((String) paramEnum.nextElement());
}
paramNames.addAll(getMultipartParameters().keySet());
return Collections.enumeration(paramNames);
}
@Override
public String getParameter(String name) {
String[] values = getMultipartParameters().get(name);
if (values != null) {
return (values.length > 0 ? values[0] : null);
}
return super.getParameter(name);
}
@Override
public String[] getParameterValues(String name) {
String[] values = getMultipartParameters().get(name);
if (values != null) {
return values;
}
return super.getParameterValues(name);
}
@Override
@SuppressWarnings("unchecked")
public Map<String, String[]> getParameterMap() {
Map<String, String[]> paramMap = new HashMap<String, String[]>();
paramMap.putAll(super.getParameterMap());
paramMap.putAll(getMultipartParameters());
return paramMap;
}
/**
* Set a Map with parameter names as keys and String array objects as values.
* To be invoked by subclasses on initialization.
*/
protected final void setMultipartParameters(Map<String, String[]> multipartParameters) {
this.multipartParameters = multipartParameters;
}
/**
* Obtain the multipart parameter Map for retrieval,
* lazily initializing it if necessary.
* @see #initializeMultipart()
*/
protected Map<String, String[]> getMultipartParameters() {
if (this.multipartParameters == null) {
initializeMultipart();
}
return this.multipartParameters;
}
}

View File

@ -1,151 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
/**
* Servlet 2.3 Filter that resolves multipart requests via a MultipartResolver.
* in the root web application context.
*
* <p>Looks up the MultipartResolver in Spring's root web application context.
* Supports a "multipartResolverBeanName" filter init-param in <code>web.xml</code>;
* the default bean name is "filterMultipartResolver". Looks up the MultipartResolver
* on each request, to avoid initialization order issues (when using ContextLoaderServlet,
* the root application context will get initialized <i>after</i> this filter).
*
* <p>MultipartResolver lookup is customizable: Override this filter's
* <code>lookupMultipartResolver</code> method to use a custom MultipartResolver
* instance, for example if not using a Spring web application context.
* Note that the lookup method should not create a new MultipartResolver instance
* for each call but rather return a reference to a pre-built instance.
*
* <p>Note: This filter is an <b>alternative</b> to using DispatcherServlet's
* MultipartResolver support, for example for web applications with custom
* web views that do not use Spring's web MVC. It should not be combined with
* servlet-specific multipart resolution.
*
* @author Juergen Hoeller
* @since 08.10.2003
* @see #setMultipartResolverBeanName
* @see #lookupMultipartResolver
* @see org.springframework.web.multipart.MultipartResolver
* @see org.springframework.web.servlet.DispatcherServlet
*/
public class MultipartFilter extends OncePerRequestFilter {
public static final String DEFAULT_MULTIPART_RESOLVER_BEAN_NAME = "filterMultipartResolver";
private String multipartResolverBeanName = DEFAULT_MULTIPART_RESOLVER_BEAN_NAME;
/**
* Set the bean name of the MultipartResolver to fetch from Spring's
* root application context. Default is "filterMultipartResolver".
*/
public void setMultipartResolverBeanName(String multipartResolverBeanName) {
this.multipartResolverBeanName = multipartResolverBeanName;
}
/**
* Return the bean name of the MultipartResolver to fetch from Spring's
* root application context.
*/
protected String getMultipartResolverBeanName() {
return multipartResolverBeanName;
}
/**
* Check for a multipart request via this filter's MultipartResolver,
* and wrap the original request with a MultipartHttpServletRequest if appropriate.
* <p>All later elements in the filter chain, most importantly servlets, benefit
* from proper parameter extraction in the multipart case, and are able to cast to
* MultipartHttpServletRequest if they need to.
*/
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
MultipartResolver multipartResolver = lookupMultipartResolver(request);
HttpServletRequest processedRequest = request;
if (multipartResolver.isMultipart(processedRequest)) {
if (logger.isDebugEnabled()) {
logger.debug("Resolving multipart request [" + processedRequest.getRequestURI() +
"] with MultipartFilter");
}
processedRequest = multipartResolver.resolveMultipart(processedRequest);
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Request [" + processedRequest.getRequestURI() + "] is not a multipart request");
}
}
try {
filterChain.doFilter(processedRequest, response);
}
finally {
if (processedRequest instanceof MultipartHttpServletRequest) {
multipartResolver.cleanupMultipart((MultipartHttpServletRequest) processedRequest);
}
}
}
/**
* Look up the MultipartResolver that this filter should use,
* taking the current HTTP request as argument.
* <p>Default implementation delegates to the <code>lookupMultipartResolver</code>
* without arguments.
* @return the MultipartResolver to use
* @see #lookupMultipartResolver()
*/
protected MultipartResolver lookupMultipartResolver(HttpServletRequest request) {
return lookupMultipartResolver();
}
/**
* Look for a MultipartResolver bean in the root web application context.
* Supports a "multipartResolverBeanName" filter init param; the default
* bean name is "filterMultipartResolver".
* <p>This can be overridden to use a custom MultipartResolver instance,
* for example if not using a Spring web application context.
* @return the MultipartResolver instance, or <code>null</code> if none found
*/
protected MultipartResolver lookupMultipartResolver() {
if (logger.isDebugEnabled()) {
logger.debug("Using MultipartResolver '" + getMultipartResolverBeanName() + "' for MultipartFilter");
}
WebApplicationContext wac =
WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
return (MultipartResolver) wac.getBean(getMultipartResolverBeanName(), MultipartResolver.class);
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.beans.PropertyEditorSupport;
import java.io.IOException;
import org.springframework.web.multipart.MultipartFile;
/**
* Custom {@link java.beans.PropertyEditor} for converting
* {@link MultipartFile MultipartFiles} to Strings.
*
* <p>Allows one to specify the charset to use.
*
* @author Juergen Hoeller
* @since 13.10.2003
*/
public class StringMultipartFileEditor extends PropertyEditorSupport {
private final String charsetName;
/**
* Create a new {@link StringMultipartFileEditor}, using the default charset.
*/
public StringMultipartFileEditor() {
this.charsetName = null;
}
/**
* Create a new {@link StringMultipartFileEditor}, using the given charset.
* @param charsetName valid charset name
* @see java.lang.String#String(byte[],String)
*/
public StringMultipartFileEditor(String charsetName) {
this.charsetName = charsetName;
}
@Override
public void setAsText(String text) {
setValue(text);
}
@Override
public void setValue(Object value) {
if (value instanceof MultipartFile) {
MultipartFile multipartFile = (MultipartFile) value;
try {
super.setValue(this.charsetName != null ?
new String(multipartFile.getBytes(), this.charsetName) :
new String(multipartFile.getBytes()));
}
catch (IOException ex) {
throw new IllegalArgumentException("Cannot read contents of multipart file", ex);
}
}
else {
super.setValue(value);
}
}
}

View File

@ -1,10 +0,0 @@
/**
*
* Support classes for the multipart resolution framework.
* Contains property editors for multipart files, and a
* servlet filter for multipart handling without Spring's web MVC.
*
*/
package org.springframework.web.multipart.support;

View File

@ -1,65 +0,0 @@
/*
* Copyright 2004-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.support;
import javax.servlet.ServletRequest;
import org.springframework.model.ui.PresentationModelFactory;
import org.springframework.model.ui.support.DefaultPresentationModelFactory;
import org.springframework.web.context.request.WebRequest;
/**
* Utilities for working with the <code>model.ui</code> PresentationModel system.
* @author Keith Donald
*/
public final class PresentationModelUtils {
private static final String PRESENTATION_MODEL_FACTORY_ATTRIBUTE = "presentationModelFactory";
private PresentationModelUtils() {
}
/**
* Get the PresentationModelFactory for the current web request.
* Will create a new one and cache it as a request attribute if one does not exist.
* @param request the web request
* @return the presentation model factory
*/
public static PresentationModelFactory getPresentationModelFactory(WebRequest request) {
PresentationModelFactory factory = (PresentationModelFactory) request.getAttribute(PRESENTATION_MODEL_FACTORY_ATTRIBUTE, WebRequest.SCOPE_REQUEST);
if (factory == null) {
factory = new DefaultPresentationModelFactory();
request.setAttribute(PRESENTATION_MODEL_FACTORY_ATTRIBUTE, factory, WebRequest.SCOPE_REQUEST);
}
return factory;
}
/**
* Get the PresentationModelFactory for the current servlet request.
* Will create a new one and cache it as a request attribute if one does not exist.
* @param request the servlet
* @return the presentation model factory
*/
public static PresentationModelFactory getPresentationModelFactory(ServletRequest request) {
PresentationModelFactory factory = (PresentationModelFactory) request.getAttribute(PRESENTATION_MODEL_FACTORY_ATTRIBUTE);
if (factory == null) {
factory = new DefaultPresentationModelFactory();
request.setAttribute(PRESENTATION_MODEL_FACTORY_ATTRIBUTE, factory);
}
return factory;
}
}

View File

@ -1,90 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import junit.framework.TestCase;
import org.springframework.beans.TestBean;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
/**
* @author Juergen Hoeller
* @since 02.05.2003
*/
public class EscapedErrorsTests extends TestCase {
public void testEscapedErrors() {
TestBean tb = new TestBean();
tb.setName("empty &");
Errors errors = new EscapedErrors(new BindException(tb, "tb"));
errors.rejectValue("name", "NAME_EMPTY &", null, "message: &");
errors.rejectValue("age", "AGE_NOT_SET <tag>", null, "message: <tag>");
errors.rejectValue("age", "AGE_NOT_32 <tag>", null, "message: <tag>");
errors.reject("GENERAL_ERROR \" '", null, "message: \" '");
assertTrue("Correct errors flag", errors.hasErrors());
assertTrue("Correct number of errors", errors.getErrorCount() == 4);
assertTrue("Correct object name", "tb".equals(errors.getObjectName()));
assertTrue("Correct global errors flag", errors.hasGlobalErrors());
assertTrue("Correct number of global errors", errors.getGlobalErrorCount() == 1);
ObjectError globalError = errors.getGlobalError();
assertTrue("Global error message escaped", "message: &quot; '".equals(globalError.getDefaultMessage()));
assertTrue("Global error code not escaped", "GENERAL_ERROR \" '".equals(globalError.getCode()));
ObjectError globalErrorInList = (ObjectError) errors.getGlobalErrors().get(0);
assertTrue("Same global error in list", globalError.getDefaultMessage().equals(globalErrorInList.getDefaultMessage()));
ObjectError globalErrorInAllList = (ObjectError) errors.getAllErrors().get(3);
assertTrue("Same global error in list", globalError.getDefaultMessage().equals(globalErrorInAllList.getDefaultMessage()));
assertTrue("Correct field errors flag", errors.hasFieldErrors());
assertTrue("Correct number of field errors", errors.getFieldErrorCount() == 3);
assertTrue("Correct number of field errors in list", errors.getFieldErrors().size() == 3);
FieldError fieldError = errors.getFieldError();
assertTrue("Field error code not escaped", "NAME_EMPTY &".equals(fieldError.getCode()));
assertTrue("Field value escaped", "empty &amp;".equals(errors.getFieldValue("name")));
FieldError fieldErrorInList = (FieldError) errors.getFieldErrors().get(0);
assertTrue("Same field error in list", fieldError.getDefaultMessage().equals(fieldErrorInList.getDefaultMessage()));
assertTrue("Correct name errors flag", errors.hasFieldErrors("name"));
assertTrue("Correct number of name errors", errors.getFieldErrorCount("name") == 1);
assertTrue("Correct number of name errors in list", errors.getFieldErrors("name").size() == 1);
FieldError nameError = errors.getFieldError("name");
assertTrue("Name error message escaped", "message: &amp;".equals(nameError.getDefaultMessage()));
assertTrue("Name error code not escaped", "NAME_EMPTY &".equals(nameError.getCode()));
assertTrue("Name value escaped", "empty &amp;".equals(errors.getFieldValue("name")));
FieldError nameErrorInList = (FieldError) errors.getFieldErrors("name").get(0);
assertTrue("Same name error in list", nameError.getDefaultMessage().equals(nameErrorInList.getDefaultMessage()));
assertTrue("Correct age errors flag", errors.hasFieldErrors("age"));
assertTrue("Correct number of age errors", errors.getFieldErrorCount("age") == 2);
assertTrue("Correct number of age errors in list", errors.getFieldErrors("age").size() == 2);
FieldError ageError = errors.getFieldError("age");
assertTrue("Age error message escaped", "message: &lt;tag&gt;".equals(ageError.getDefaultMessage()));
assertTrue("Age error code not escaped", "AGE_NOT_SET <tag>".equals(ageError.getCode()));
assertTrue("Age value not escaped", (new Integer(0)).equals(errors.getFieldValue("age")));
FieldError ageErrorInList = (FieldError) errors.getFieldErrors("age").get(0);
assertTrue("Same name error in list", ageError.getDefaultMessage().equals(ageErrorInList.getDefaultMessage()));
FieldError ageError2 = (FieldError) errors.getFieldErrors("age").get(1);
assertTrue("Age error 2 message escaped", "message: &lt;tag&gt;".equals(ageError2.getDefaultMessage()));
assertTrue("Age error 2 code not escaped", "AGE_NOT_32 <tag>".equals(ageError2.getCode()));
}
}

View File

@ -1,256 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import static org.junit.Assert.*;
import java.beans.PropertyEditorSupport;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.springframework.beans.ITestBean;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.TestBean;
import org.springframework.mock.web.MockHttpServletRequest;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @author Scott Andrews
*/
public class ServletRequestDataBinderTests {
@Test
public void testBindingWithNestedObjectCreation() throws Exception {
TestBean tb = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(tb, "person");
binder.registerCustomEditor(ITestBean.class, new PropertyEditorSupport() {
public void setAsText(String text) throws IllegalArgumentException {
setValue(new TestBean());
}
});
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("spouse", "someValue");
request.addParameter("spouse.name", "test");
binder.bind(request);
assertNotNull(tb.getSpouse());
assertEquals("test", tb.getSpouse().getName());
}
@Test
public void testFieldPrefixCausesFieldReset() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("_postProcessed", "visible");
request.addParameter("postProcessed", "on");
binder.bind(request);
assertTrue(target.isPostProcessed());
request.removeParameter("postProcessed");
binder.bind(request);
assertFalse(target.isPostProcessed());
}
@Test
public void testFieldPrefixCausesFieldResetWithIgnoreUnknownFields() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
binder.setIgnoreUnknownFields(false);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("_postProcessed", "visible");
request.addParameter("postProcessed", "on");
binder.bind(request);
assertTrue(target.isPostProcessed());
request.removeParameter("postProcessed");
binder.bind(request);
assertFalse(target.isPostProcessed());
}
@Test
public void testFieldDefault() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("!postProcessed", "off");
request.addParameter("postProcessed", "on");
binder.bind(request);
assertTrue(target.isPostProcessed());
request.removeParameter("postProcessed");
binder.bind(request);
assertFalse(target.isPostProcessed());
}
@Test
public void testFieldDefaultPreemptsFieldMarker() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("!postProcessed", "on");
request.addParameter("_postProcessed", "visible");
request.addParameter("postProcessed", "on");
binder.bind(request);
assertTrue(target.isPostProcessed());
request.removeParameter("postProcessed");
binder.bind(request);
assertTrue(target.isPostProcessed());
request.removeParameter("!postProcessed");
binder.bind(request);
assertFalse(target.isPostProcessed());
}
@Test
public void testFieldDefaultNonBoolean() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("!name", "anonymous");
request.addParameter("name", "Scott");
binder.bind(request);
assertEquals("Scott", target.getName());
request.removeParameter("name");
binder.bind(request);
assertEquals("anonymous", target.getName());
}
@Test
public void testWithCommaSeparatedStringArray() throws Exception {
TestBean target = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(target);
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("stringArray", "bar");
request.addParameter("stringArray", "abc");
request.addParameter("stringArray", "123,def");
binder.bind(request);
assertEquals("Expected all three items to be bound", 3, target.getStringArray().length);
request.removeParameter("stringArray");
request.addParameter("stringArray", "123,def");
binder.bind(request);
assertEquals("Expected only 1 item to be bound", 1, target.getStringArray().length);
}
@Test
public void testBindingWithNestedObjectCreationAndWrongOrder() throws Exception {
TestBean tb = new TestBean();
ServletRequestDataBinder binder = new ServletRequestDataBinder(tb, "person");
binder.registerCustomEditor(ITestBean.class, new PropertyEditorSupport() {
public void setAsText(String text) throws IllegalArgumentException {
setValue(new TestBean());
}
});
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("spouse.name", "test");
request.addParameter("spouse", "someValue");
binder.bind(request);
assertNotNull(tb.getSpouse());
assertEquals("test", tb.getSpouse().getName());
}
@Test
public void testNoPrefix() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("forname", "Tony");
request.addParameter("surname", "Blair");
request.addParameter("age", "" + 50);
ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(request);
doTestTony(pvs);
}
@Test
public void testPrefix() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("test_forname", "Tony");
request.addParameter("test_surname", "Blair");
request.addParameter("test_age", "" + 50);
ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(request);
assertTrue("Didn't fidn normal when given prefix", !pvs.contains("forname"));
assertTrue("Did treat prefix as normal when not given prefix", pvs.contains("test_forname"));
pvs = new ServletRequestParameterPropertyValues(request, "test");
doTestTony(pvs);
}
@Test
public void testNoParameters() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(request);
assertTrue("Found no parameters", pvs.getPropertyValues().length == 0);
}
@Test
public void testMultipleValuesForParameter() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
String[] original = new String[] {"Tony", "Rod"};
request.addParameter("forname", original);
ServletRequestParameterPropertyValues pvs = new ServletRequestParameterPropertyValues(request);
assertTrue("Found 1 parameter", pvs.getPropertyValues().length == 1);
assertTrue("Found array value", pvs.getPropertyValue("forname").getValue() instanceof String[]);
String[] values = (String[]) pvs.getPropertyValue("forname").getValue();
assertEquals("Correct values", Arrays.asList(values), Arrays.asList(original));
}
/**
* Must contain: forname=Tony surname=Blair age=50
*/
protected void doTestTony(PropertyValues pvs) throws Exception {
assertTrue("Contains 3", pvs.getPropertyValues().length == 3);
assertTrue("Contains forname", pvs.contains("forname"));
assertTrue("Contains surname", pvs.contains("surname"));
assertTrue("Contains age", pvs.contains("age"));
assertTrue("Doesn't contain tory", !pvs.contains("tory"));
PropertyValue[] ps = pvs.getPropertyValues();
Map<String, String> m = new HashMap<String, String>();
m.put("forname", "Tony");
m.put("surname", "Blair");
m.put("age", "50");
for (int i = 0; i < ps.length; i++) {
Object val = m.get(ps[i].getName());
assertTrue("Can't have unexpected value", val != null);
assertTrue("Val i string", val instanceof String);
assertTrue("val matches expected", val.equals(ps[i].getValue()));
m.remove(ps[i].getName());
}
assertTrue("Map size is 0", m.size() == 0);
}
}

View File

@ -1,465 +0,0 @@
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.util.StopWatch;
/**
* @author Juergen Hoeller
* @author Chris Beams
* @since 06.08.2003
*/
public class ServletRequestUtilsTests {
@Test
public void testIntParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "5");
request.addParameter("param2", "e");
request.addParameter("paramEmpty", "");
assertEquals(ServletRequestUtils.getIntParameter(request, "param1"), new Integer(5));
assertEquals(ServletRequestUtils.getIntParameter(request, "param1", 6), 5);
assertEquals(ServletRequestUtils.getRequiredIntParameter(request, "param1"), 5);
assertEquals(ServletRequestUtils.getIntParameter(request, "param2", 6), 6);
try {
ServletRequestUtils.getRequiredIntParameter(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertEquals(ServletRequestUtils.getIntParameter(request, "param3"), null);
assertEquals(ServletRequestUtils.getIntParameter(request, "param3", 6), 6);
try {
ServletRequestUtils.getRequiredIntParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
try {
ServletRequestUtils.getRequiredIntParameter(request, "paramEmpty");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testIntParameters() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param", new String[] {"1", "2", "3"});
request.addParameter("param2", "1");
request.addParameter("param2", "2");
request.addParameter("param2", "bogus");
int[] array = new int[] {1, 2, 3};
int[] values = ServletRequestUtils.getRequiredIntParameters(request, "param");
assertEquals(3, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i]);
}
try {
ServletRequestUtils.getRequiredIntParameters(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testLongParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "5");
request.addParameter("param2", "e");
request.addParameter("paramEmpty", "");
assertEquals(ServletRequestUtils.getLongParameter(request, "param1"), new Long(5L));
assertEquals(ServletRequestUtils.getLongParameter(request, "param1", 6L), 5L);
assertEquals(ServletRequestUtils.getRequiredIntParameter(request, "param1"), 5L);
assertEquals(ServletRequestUtils.getLongParameter(request, "param2", 6L), 6L);
try {
ServletRequestUtils.getRequiredLongParameter(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertEquals(ServletRequestUtils.getLongParameter(request, "param3"), null);
assertEquals(ServletRequestUtils.getLongParameter(request, "param3", 6L), 6L);
try {
ServletRequestUtils.getRequiredLongParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
try {
ServletRequestUtils.getRequiredLongParameter(request, "paramEmpty");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testLongParameters() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setParameter("param", new String[] {"1", "2", "3"});
request.setParameter("param2", "0");
request.setParameter("param2", "1");
request.addParameter("param2", "2");
request.addParameter("param2", "bogus");
long[] array = new long[] {1L, 2L, 3L};
long[] values = ServletRequestUtils.getRequiredLongParameters(request, "param");
assertEquals(3, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i]);
}
try {
ServletRequestUtils.getRequiredLongParameters(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
request.setParameter("param2", new String[] {"1", "2"});
values = ServletRequestUtils.getRequiredLongParameters(request, "param2");
assertEquals(2, values.length);
assertEquals(1, values[0]);
assertEquals(2, values[1]);
request.removeParameter("param2");
try {
ServletRequestUtils.getRequiredLongParameters(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testFloatParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "5.5");
request.addParameter("param2", "e");
request.addParameter("paramEmpty", "");
assertTrue(ServletRequestUtils.getFloatParameter(request, "param1").equals(new Float(5.5f)));
assertTrue(ServletRequestUtils.getFloatParameter(request, "param1", 6.5f) == 5.5f);
assertTrue(ServletRequestUtils.getRequiredFloatParameter(request, "param1") == 5.5f);
assertTrue(ServletRequestUtils.getFloatParameter(request, "param2", 6.5f) == 6.5f);
try {
ServletRequestUtils.getRequiredFloatParameter(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertTrue(ServletRequestUtils.getFloatParameter(request, "param3") == null);
assertTrue(ServletRequestUtils.getFloatParameter(request, "param3", 6.5f) == 6.5f);
try {
ServletRequestUtils.getRequiredFloatParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
try {
ServletRequestUtils.getRequiredFloatParameter(request, "paramEmpty");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testFloatParameters() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param", new String[] {"1.5", "2.5", "3"});
request.addParameter("param2", "1.5");
request.addParameter("param2", "2");
request.addParameter("param2", "bogus");
float[] array = new float[] {1.5F, 2.5F, 3};
float[] values = ServletRequestUtils.getRequiredFloatParameters(request, "param");
assertEquals(3, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i], 0);
}
try {
ServletRequestUtils.getRequiredFloatParameters(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testDoubleParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "5.5");
request.addParameter("param2", "e");
request.addParameter("paramEmpty", "");
assertTrue(ServletRequestUtils.getDoubleParameter(request, "param1").equals(new Double(5.5)));
assertTrue(ServletRequestUtils.getDoubleParameter(request, "param1", 6.5) == 5.5);
assertTrue(ServletRequestUtils.getRequiredDoubleParameter(request, "param1") == 5.5);
assertTrue(ServletRequestUtils.getDoubleParameter(request, "param2", 6.5) == 6.5);
try {
ServletRequestUtils.getRequiredDoubleParameter(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertTrue(ServletRequestUtils.getDoubleParameter(request, "param3") == null);
assertTrue(ServletRequestUtils.getDoubleParameter(request, "param3", 6.5) == 6.5);
try {
ServletRequestUtils.getRequiredDoubleParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
try {
ServletRequestUtils.getRequiredDoubleParameter(request, "paramEmpty");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testDoubleParameters() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param", new String[] {"1.5", "2.5", "3"});
request.addParameter("param2", "1.5");
request.addParameter("param2", "2");
request.addParameter("param2", "bogus");
double[] array = new double[] {1.5, 2.5, 3};
double[] values = ServletRequestUtils.getRequiredDoubleParameters(request, "param");
assertEquals(3, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i], 0);
}
try {
ServletRequestUtils.getRequiredDoubleParameters(request, "param2");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
}
@Test
public void testBooleanParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "true");
request.addParameter("param2", "e");
request.addParameter("param4", "yes");
request.addParameter("param5", "1");
request.addParameter("paramEmpty", "");
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param1").equals(Boolean.TRUE));
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param1", false));
assertTrue(ServletRequestUtils.getRequiredBooleanParameter(request, "param1"));
assertFalse(ServletRequestUtils.getBooleanParameter(request, "param2", true));
assertFalse(ServletRequestUtils.getRequiredBooleanParameter(request, "param2"));
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param3") == null);
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param3", true));
try {
ServletRequestUtils.getRequiredBooleanParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param4", false));
assertTrue(ServletRequestUtils.getRequiredBooleanParameter(request, "param4"));
assertTrue(ServletRequestUtils.getBooleanParameter(request, "param5", false));
assertTrue(ServletRequestUtils.getRequiredBooleanParameter(request, "param5"));
assertFalse(ServletRequestUtils.getRequiredBooleanParameter(request, "paramEmpty"));
}
@Test
public void testBooleanParameters() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param", new String[] {"true", "yes", "off", "1", "bogus"});
request.addParameter("param2", "false");
request.addParameter("param2", "true");
request.addParameter("param2", "");
boolean[] array = new boolean[] {true, true, false, true, false};
boolean[] values = ServletRequestUtils.getRequiredBooleanParameters(request, "param");
assertEquals(array.length, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i]);
}
array = new boolean[] {false, true, false};
values = ServletRequestUtils.getRequiredBooleanParameters(request, "param2");
assertEquals(array.length, values.length);
for (int i = 0; i < array.length; i++) {
assertEquals(array[i], values[i]);
}
}
@Test
public void testStringParameter() throws ServletRequestBindingException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter("param1", "str");
request.addParameter("paramEmpty", "");
assertEquals("str", ServletRequestUtils.getStringParameter(request, "param1"));
assertEquals("str", ServletRequestUtils.getStringParameter(request, "param1", "string"));
assertEquals("str", ServletRequestUtils.getRequiredStringParameter(request, "param1"));
assertEquals(null, ServletRequestUtils.getStringParameter(request, "param3"));
assertEquals("string", ServletRequestUtils.getStringParameter(request, "param3", "string"));
assertNull(ServletRequestUtils.getStringParameter(request, "param3", null));
try {
ServletRequestUtils.getRequiredStringParameter(request, "param3");
fail("Should have thrown ServletRequestBindingException");
}
catch (ServletRequestBindingException ex) {
// expected
}
assertEquals("", ServletRequestUtils.getStringParameter(request, "paramEmpty"));
assertEquals("", ServletRequestUtils.getRequiredStringParameter(request, "paramEmpty"));
}
@Test
public void testGetIntParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getIntParameter(request, "nonExistingParam", 0);
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
@Test
public void testGetLongParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getLongParameter(request, "nonExistingParam", 0);
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
@Test
public void testGetFloatParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getFloatParameter(request, "nonExistingParam", 0f);
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
@Test
public void testGetDoubleParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getDoubleParameter(request, "nonExistingParam", 0d);
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
@Test
public void testGetBooleanParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getBooleanParameter(request, "nonExistingParam", false);
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
@Test
public void testGetStringParameterWithDefaultValueHandlingIsFastEnough() {
MockHttpServletRequest request = new MockHttpServletRequest();
StopWatch sw = new StopWatch();
sw.start();
for (int i = 0; i < 1000000; i++) {
ServletRequestUtils.getStringParameter(request, "nonExistingParam", "defaultValue");
}
sw.stop();
System.out.println(sw.getTotalTimeMillis());
assertTrue("getStringParameter took too long: " + sw.getTotalTimeMillis(), sw.getTotalTimeMillis() < 250);
}
}

View File

@ -1,485 +0,0 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.commons;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import junit.framework.TestCase;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.mock.web.PassThroughFilterChain;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.multipart.support.MultipartFilter;
import org.springframework.web.multipart.support.StringMultipartFileEditor;
import org.springframework.web.util.WebUtils;
/**
* @author Juergen Hoeller
* @since 08.10.2003
*/
public class CommonsMultipartResolverTests extends TestCase {
public void testWithApplicationContext() throws Exception {
doTestWithApplicationContext(false);
}
public void testWithApplicationContextAndLazyResolution() throws Exception {
doTestWithApplicationContext(true);
}
private void doTestWithApplicationContext(boolean lazy) throws Exception {
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
wac.refresh();
MockCommonsMultipartResolver resolver = new MockCommonsMultipartResolver();
resolver.setMaxUploadSize(1000);
resolver.setMaxInMemorySize(100);
resolver.setDefaultEncoding("enc");
if (lazy) {
resolver.setResolveLazily(false);
}
resolver.setServletContext(wac.getServletContext());
assertEquals(1000, resolver.getFileUpload().getSizeMax());
assertEquals(100, resolver.getFileItemFactory().getSizeThreshold());
assertEquals("enc", resolver.getFileUpload().getHeaderEncoding());
assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
MockHttpServletRequest originalRequest = new MockHttpServletRequest();
originalRequest.setMethod("POST");
originalRequest.setContentType("multipart/form-data");
originalRequest.addHeader("Content-type", "multipart/form-data");
originalRequest.addParameter("getField", "getValue");
assertTrue(resolver.isMultipart(originalRequest));
MultipartHttpServletRequest request = resolver.resolveMultipart(originalRequest);
Set parameterNames = new HashSet();
Enumeration parameterEnum = request.getParameterNames();
while (parameterEnum.hasMoreElements()) {
parameterNames.add(parameterEnum.nextElement());
}
assertEquals(3, parameterNames.size());
assertTrue(parameterNames.contains("field3"));
assertTrue(parameterNames.contains("field4"));
assertTrue(parameterNames.contains("getField"));
assertEquals("value3", request.getParameter("field3"));
List parameterValues = Arrays.asList(request.getParameterValues("field3"));
assertEquals(1, parameterValues.size());
assertTrue(parameterValues.contains("value3"));
assertEquals("value4", request.getParameter("field4"));
parameterValues = Arrays.asList(request.getParameterValues("field4"));
assertEquals(2, parameterValues.size());
assertTrue(parameterValues.contains("value4"));
assertTrue(parameterValues.contains("value5"));
assertEquals("value4", request.getParameter("field4"));
assertEquals("getValue", request.getParameter("getField"));
List parameterMapKeys = new ArrayList();
List parameterMapValues = new ArrayList();
for (Iterator parameterMapIter = request.getParameterMap().keySet().iterator(); parameterMapIter.hasNext();) {
String key = (String) parameterMapIter.next();
parameterMapKeys.add(key);
parameterMapValues.add(request.getParameterMap().get(key));
}
assertEquals(3, parameterMapKeys.size());
assertEquals(3, parameterMapValues.size());
int field3Index = parameterMapKeys.indexOf("field3");
int field4Index = parameterMapKeys.indexOf("field4");
int getFieldIndex = parameterMapKeys.indexOf("getField");
assertTrue(field3Index != -1);
assertTrue(field4Index != -1);
assertTrue(getFieldIndex != -1);
parameterValues = Arrays.asList((String[]) parameterMapValues.get(field3Index));
assertEquals(1, parameterValues.size());
assertTrue(parameterValues.contains("value3"));
parameterValues = Arrays.asList((String[]) parameterMapValues.get(field4Index));
assertEquals(2, parameterValues.size());
assertTrue(parameterValues.contains("value4"));
assertTrue(parameterValues.contains("value5"));
parameterValues = Arrays.asList((String[]) parameterMapValues.get(getFieldIndex));
assertEquals(1, parameterValues.size());
assertTrue(parameterValues.contains("getValue"));
Set fileNames = new HashSet();
Iterator fileIter = request.getFileNames();
while (fileIter.hasNext()) {
fileNames.add(fileIter.next());
}
assertEquals(3, fileNames.size());
assertTrue(fileNames.contains("field1"));
assertTrue(fileNames.contains("field2"));
assertTrue(fileNames.contains("field2x"));
CommonsMultipartFile file1 = (CommonsMultipartFile) request.getFile("field1");
CommonsMultipartFile file2 = (CommonsMultipartFile) request.getFile("field2");
CommonsMultipartFile file2x = (CommonsMultipartFile) request.getFile("field2x");
Map fileMap = request.getFileMap();
assertEquals(3, fileMap.size());
assertTrue(fileMap.containsKey("field1"));
assertTrue(fileMap.containsKey("field2"));
assertTrue(fileMap.containsKey("field2x"));
assertEquals(file1, fileMap.get("field1"));
assertEquals(file2, fileMap.get("field2"));
assertEquals(file2x, fileMap.get("field2x"));
assertEquals("type1", file1.getContentType());
assertEquals("type2", file2.getContentType());
assertEquals("type2", file2x.getContentType());
assertEquals("field1.txt", file1.getOriginalFilename());
assertEquals("field2.txt", file2.getOriginalFilename());
assertEquals("field2x.txt", file2x.getOriginalFilename());
assertEquals("text1", new String(file1.getBytes()));
assertEquals("text2", new String(file2.getBytes()));
assertEquals(5, file1.getSize());
assertEquals(5, file2.getSize());
assertTrue(file1.getInputStream() instanceof ByteArrayInputStream);
assertTrue(file2.getInputStream() instanceof ByteArrayInputStream);
File transfer1 = new File("C:/transfer1");
File transfer2 = new File("C:/transfer2");
file1.transferTo(transfer1);
file2.transferTo(transfer2);
assertEquals(transfer1, ((MockFileItem) file1.getFileItem()).writtenFile);
assertEquals(transfer2, ((MockFileItem) file2.getFileItem()).writtenFile);
MultipartTestBean1 mtb1 = new MultipartTestBean1();
assertEquals(null, mtb1.getField1());
assertEquals(null, mtb1.getField2());
ServletRequestDataBinder binder = new ServletRequestDataBinder(mtb1, "mybean");
binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
binder.bind(request);
assertEquals(file1, mtb1.getField1());
assertEquals(new String(file2.getBytes()), new String(mtb1.getField2()));
MultipartTestBean2 mtb2 = new MultipartTestBean2();
assertEquals(null, mtb2.getField1());
assertEquals(null, mtb2.getField2());
binder = new ServletRequestDataBinder(mtb2, "mybean");
binder.registerCustomEditor(String.class, "field1", new StringMultipartFileEditor());
binder.registerCustomEditor(String.class, "field2", new StringMultipartFileEditor("UTF-16"));
binder.bind(request);
assertEquals(new String(file1.getBytes()), mtb2.getField1());
assertEquals(new String(file2.getBytes(), "UTF-16"), mtb2.getField2());
resolver.cleanupMultipart(request);
assertTrue(((MockFileItem) file1.getFileItem()).deleted);
assertTrue(((MockFileItem) file2.getFileItem()).deleted);
resolver.setEmpty(true);
request = resolver.resolveMultipart(originalRequest);
binder.setBindEmptyMultipartFiles(false);
String firstBound = mtb2.getField1();
binder.bind(request);
assertTrue(mtb2.getField1().length() > 0);
assertEquals(firstBound, mtb2.getField1());
request = resolver.resolveMultipart(originalRequest);
binder.setBindEmptyMultipartFiles(true);
binder.bind(request);
assertTrue(mtb2.getField1().length() == 0);
}
public void testWithServletContextAndFilter() throws Exception {
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
wac.registerSingleton("filterMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues());
wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
wac.refresh();
wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext());
assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
filterConfig.addInitParameter("class", "notWritable");
filterConfig.addInitParameter("unknownParam", "someValue");
final MultipartFilter filter = new MultipartFilter();
filter.init(filterConfig);
final List files = new ArrayList();
final FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
MultipartHttpServletRequest request = (MultipartHttpServletRequest) servletRequest;
files.addAll(request.getFileMap().values());
}
};
FilterChain filterChain2 = new PassThroughFilterChain(filter, filterChain);
MockHttpServletRequest originalRequest = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
originalRequest.setMethod("POST");
originalRequest.setContentType("multipart/form-data");
originalRequest.addHeader("Content-type", "multipart/form-data");
filter.doFilter(originalRequest, response, filterChain2);
CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0);
CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1);
assertTrue(((MockFileItem) file1.getFileItem()).deleted);
assertTrue(((MockFileItem) file2.getFileItem()).deleted);
}
public void testWithServletContextAndFilterWithCustomBeanName() throws Exception {
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
wac.refresh();
wac.registerSingleton("myMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues());
wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext());
assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
filterConfig.addInitParameter("multipartResolverBeanName", "myMultipartResolver");
final List files = new ArrayList();
FilterChain filterChain = new FilterChain() {
public void doFilter(ServletRequest originalRequest, ServletResponse response) {
if (originalRequest instanceof MultipartHttpServletRequest) {
MultipartHttpServletRequest request = (MultipartHttpServletRequest) originalRequest;
files.addAll(request.getFileMap().values());
}
}
};
MultipartFilter filter = new MultipartFilter() {
private boolean invoked = false;
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
super.doFilterInternal(request, response, filterChain);
super.doFilterInternal(request, response, filterChain);
if (invoked) {
throw new ServletException("Should not have been invoked twice");
}
invoked = true;
}
};
filter.init(filterConfig);
MockHttpServletRequest originalRequest = new MockHttpServletRequest();
originalRequest.setMethod("POST");
originalRequest.setContentType("multipart/form-data");
originalRequest.addHeader("Content-type", "multipart/form-data");
HttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(originalRequest, response, filterChain);
CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0);
CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1);
assertTrue(((MockFileItem) file1.getFileItem()).deleted);
assertTrue(((MockFileItem) file2.getFileItem()).deleted);
}
public static class MockCommonsMultipartResolver extends CommonsMultipartResolver {
private boolean empty;
protected void setEmpty(boolean empty) {
this.empty = empty;
}
protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
return new ServletFileUpload() {
public List parseRequest(HttpServletRequest request) {
if (request instanceof MultipartHttpServletRequest) {
throw new IllegalStateException("Already a multipart request");
}
List fileItems = new ArrayList();
MockFileItem fileItem1 = new MockFileItem(
"field1", "type1", empty ? "" : "field1.txt", empty ? "" : "text1");
MockFileItem fileItem2 = new MockFileItem(
"field2", "type2", empty ? "" : "C:/field2.txt", empty ? "" : "text2");
MockFileItem fileItem2x = new MockFileItem(
"field2x", "type2", empty ? "" : "C:\\field2x.txt", empty ? "" : "text2");
MockFileItem fileItem3 = new MockFileItem("field3", null, null, "value3");
MockFileItem fileItem4 = new MockFileItem("field4", null, null, "value4");
MockFileItem fileItem5 = new MockFileItem("field4", null, null, "value5");
fileItems.add(fileItem1);
fileItems.add(fileItem2);
fileItems.add(fileItem2x);
fileItems.add(fileItem3);
fileItems.add(fileItem4);
fileItems.add(fileItem5);
return fileItems;
}
};
}
}
private static class MockFileItem implements FileItem {
private String fieldName;
private String contentType;
private String name;
private String value;
private File writtenFile;
private boolean deleted;
public MockFileItem(String fieldName, String contentType, String name, String value) {
this.fieldName = fieldName;
this.contentType = contentType;
this.name = name;
this.value = value;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(value.getBytes());
}
public String getContentType() {
return contentType;
}
public String getName() {
return name;
}
public boolean isInMemory() {
return true;
}
public long getSize() {
return value.length();
}
public byte[] get() {
return value.getBytes();
}
public String getString(String encoding) throws UnsupportedEncodingException {
return new String(get(), encoding);
}
public String getString() {
return value;
}
public void write(File file) throws Exception {
this.writtenFile = file;
}
public File getWrittenFile() {
return writtenFile;
}
public void delete() {
this.deleted = true;
}
public boolean isDeleted() {
return deleted;
}
public String getFieldName() {
return fieldName;
}
public void setFieldName(String s) {
this.fieldName = s;
}
public boolean isFormField() {
return (this.name == null);
}
public void setFormField(boolean b) {
throw new UnsupportedOperationException();
}
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
}
public class MultipartTestBean1 {
private MultipartFile field1;
private byte[] field2;
public void setField1(MultipartFile field1) {
this.field1 = field1;
}
public MultipartFile getField1() {
return field1;
}
public void setField2(byte[] field2) {
this.field2 = field2;
}
public byte[] getField2() {
return field2;
}
}
public class MultipartTestBean2 {
private String field1;
private String field2;
public void setField1(String field1) {
this.field1 = field1;
}
public String getField1() {
return field1;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField2() {
return field2;
}
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.multipart.support;
import java.io.IOException;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Rick Evans
*/
public final class ByteArrayMultipartFileEditorTests extends TestCase {
public void testSetValueAsByteArray() throws Exception {
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
String expectedValue = "Shumwere, shumhow, a shuck ish washing you. - Drunken Far Side";
editor.setValue(expectedValue.getBytes());
assertEquals(expectedValue, editor.getAsText());
}
public void testSetValueAsString() throws Exception {
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
String expectedValue = "'Green Wing' - classic British comedy";
editor.setValue(expectedValue);
assertEquals(expectedValue, editor.getAsText());
}
public void testSetValueAsCustomObjectInvokesToString() throws Exception {
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
final String expectedValue = "'Green Wing' - classic British comedy";
Object object = new Object() {
public String toString() {
return expectedValue;
}
};
editor.setValue(object);
assertEquals(expectedValue, editor.getAsText());
}
public void testSetValueAsNullGetsBackEmptyString() throws Exception {
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
editor.setValue(null);
assertEquals("", editor.getAsText());
}
public void testSetValueAsMultipartFile() throws Exception {
String expectedValue = "That is comforting to know";
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
MockControl mock = MockControl.createControl(MultipartFile.class);
MultipartFile file = (MultipartFile) mock.getMock();
file.getBytes();
mock.setReturnValue(expectedValue.getBytes());
mock.replay();
editor.setValue(file);
assertEquals(expectedValue, editor.getAsText());
mock.verify();
}
public void testSetValueAsMultipartFileWithBadBytes() throws Exception {
ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor();
MockControl mock = MockControl.createControl(MultipartFile.class);
MultipartFile file = (MultipartFile) mock.getMock();
file.getBytes();
mock.setThrowable(new IOException());
mock.replay();
try {
editor.setValue(file);
fail("Must have thrown an IllegalArgumentException: IOException thrown when reading MultipartFile bytes");
}
catch (IllegalArgumentException expected) {
}
mock.verify();
}
}

View File

@ -17,7 +17,6 @@ Import-Template:
javax.xml.*;version="0";resolution:=optional,
jxl.*;version="[2.6.6, 3.0.0)";resolution:=optional,
net.sf.jasperreports.*;version="[2.0.5, 3.0.0)";resolution:=optional,
org.apache.commons.fileupload.*;version="[1.2.0, 2.0.0)";resolution:=optional,
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)";resolution:=optional,
org.apache.poi.*;version="[3.0.2.FINAL, 4.0.0)";resolution:=optional,
org.apache.tiles.*;version="[2.1.2, 3.0.0)";resolution:=optional,
@ -28,12 +27,11 @@ Import-Template:
org.springframework.context.*;version="[3.0.0, 3.0.1)",
org.springframework.core.*;version="[3.0.0, 3.0.1)",
org.springframework.http.*;version="[3.0.0, 3.0.1)",
org.springframework.model.*;version="[3.0.0, 3.0.1)",
org.springframework.oxm.*;version="[3.0.0, 3.0.1)";resolution:=optional,
org.springframework.stereotype;version="[3.0.0, 3.0.1)",
org.springframework.ui.*;version="[3.0.0, 3.0.1)",
org.springframework.util.*;version="[3.0.0, 3.0.1)",
org.springframework.validation.*;version="[3.0.0, 3.0.1)",
org.springframework.validation.*;version="[3.0.0, 3.0.1)",
org.springframework.web.*;version="[3.0.0, 3.0.1)",
org.xml.sax.*;version="0";resolution:=optional,
org.w3c.dom.*;version="0";resolution:=optional