INT-2388 Update Gradle build
This is a significant update to the build system, including the changes listed below. README.md has been updated with instructions on the most important day-to-day commands. - Eliminate buildSrc submodule In favor of using the new bundlor and docbook-reference plugins. The net effect is a large reduction in number of lines of build code. Common docbook resources, stylesheets, etc are stored directly in the docbook plugin. This means that --recursive is no longer required when cloning and there will never be a need to use `git submodule` commands. README files have been updated to reflect. Use of the new bundlor plugin also means the removal of template.mf files from the source tree in favor of an inline approach. See build.gradle for details. Bundlor 'import templates' are built up programmatically and kept physically close to gradle dependency declarations, leading to more convenience when changing these values and hopefully fewer errors / version inconsistencies over time. Certain tests depended on the presence of template.mf files, all of which have recently been removed from the source tree in favor of the new bundlor plugin which allows for inlining bundlor configuration within the Gradle build script. These tests now create temp files using the java.io.File API instead. - Upgrade to Gradle 1.0-milestone-6 The m6 release is significantly faster when resolving dependencies and has a number of valuable new features over the earlier m3 version. Review the release notes for Gradle 1.0-milestone-6 online for full details. - Switch to repo.springsource.org repository Previously the project build declared as many repositories as necessary to resolve all project dependencies. Now depending on a single 'virtual repository' defined within the SpringSource Artifactory instance at http://repo.springsource.org. Currently, the virtual repository in use is 'libs-milestone', which allows for the resolution of all "milestone-or-better" versions of all S2 and third-party dependencies. Should snapshot dependencies become required, this value may be changed from 'libs-milestone' to 'libs-snapshot'. To build only against GA releases, change the value to 'libs-release'. - New build plan(s) Spring Integration build plans have been updated to use the Artifactory Bamboo plugin and publish to repo.springsource.org. Build plans have names like 2.1.x to reflect the version under development, not necessarily the name of the branch, as this may change over time and across major releases. - Improve release process As mentioned above, Spring Integration will now use the Artifactory Bamboo plugin to publish releases and also use Artifactory's support for pushing builds directly into Maven Central via oss.sonatype.org. Generate poms that contain all necessary fields for onboarding at Maven central (scm, developers, organization, licenses, etc). Generate -source and -javadoc poms to comply with Maven Central onboarding rules (and for general good practice anyway). Generation of PGP signatures, sha1 and md5 checksums are all handled automatically by Artifactory. These are also requirements for automated entry into Maven Central. - Remove source-level pom generation Automatic generation of Maven poms suitable for use in building Spring Integration is no longer supported. Generation and publication of poms for the purpose of dependency management remains supported. Sonar support has to date depended on these poms, but will be switched over to use the Gradle Sonar plugin shortly. - Eliminate docs subproject Move docs/src to the root of the project and eliminate docs as a formal subproject. This simplifies the build in a number of ways, including removing the need for distinguishing between 'subprojects' and 'javaprojects' as well as allowing users to build both 'api' and 'reference' docs without qualifying with a ':docs' prefix. Also rename the src/info directory to src/dist to better reflect that these files are packaged with the distribution. For example, the readme.txt there is really the distribution readme, distinct from the README.md at the root of the project which is for building from source, etc.
This commit is contained in:
381
src/reference/docbook/http.xml
Normal file
381
src/reference/docbook/http.xml
Normal file
@@ -0,0 +1,381 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="http"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>HTTP Support</title>
|
||||
|
||||
<section id="http-intro">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
The HTTP support allows for the execution of HTTP requests and the processing of inbound HTTP requests. Because interaction over HTTP is always synchronous, even if all that is returned is a 200 status code, the HTTP support consists of two gateway implementations:
|
||||
<classname>HttpInboundEndpoint</classname> and <classname>HttpRequestExecutingMessageHandler</classname>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="http-inbound">
|
||||
<title>Http Inbound Gateway</title>
|
||||
<para>
|
||||
To receive messages over HTTP you need to use an HTTP inbound Channel Adapter or Gateway. In common with the HttpInvoker
|
||||
support the HTTP inbound adapters need to be deployed within a servlet container. The easiest way to do this is to provide a servlet
|
||||
definition in <emphasis>web.xml</emphasis>, see
|
||||
<xref linkend="httpinvoker-inbound"/> for further details. Below is an example bean definition for a simple HTTP inbound endpoint.
|
||||
<programlisting language="xml"><![CDATA[<bean id="httpInbound"
|
||||
class="org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway">
|
||||
<property name="requestChannel" ref="httpRequestChannel" />
|
||||
<property name="replyChannel" ref="httpReplyChannel" />
|
||||
</bean>]]></programlisting>
|
||||
The <classname>HttpRequestHandlingMessagingGateway</classname> accepts a list of <interfacename>HttpMessageConverter</interfacename> instances or else
|
||||
relies on a default list. The converters allow
|
||||
customization of the mapping from <interfacename>HttpServletRequest</interfacename> to <interfacename>Message</interfacename>. The default converters
|
||||
encapsulate simple strategies, which for
|
||||
example will create a String message for a <emphasis>POST</emphasis> request where the content type starts with "text", see the Javadoc for
|
||||
full details.
|
||||
</para>
|
||||
<para>Starting with this release MultiPart File support was implemented. If the request has been wrapped as a
|
||||
<emphasis>MultipartHttpServletRequest</emphasis>, when using the default converters, that request will be converted
|
||||
to a Message payload that is a MultiValueMap containing values that may be byte arrays, Strings, or instances of
|
||||
Spring's <interfacename>MultipartFile</interfacename> depending on the content type of the individual parts.
|
||||
<note>
|
||||
The HTTP inbound Endpoint will locate a MultipartResolver in the context if one exists with the bean name
|
||||
"multipartResolver" (the same name expected by Spring's DispatcherServlet). If it does in fact locate that
|
||||
bean, then the support for MultipartFiles will be enabled on the inbound request mapper. Otherwise, it will
|
||||
fail when trying to map a multipart-file request to a Spring Integration Message. For more on Spring's
|
||||
support for MultipartResolvers, refer to the <ulink url="http://static.springsource.org/spring/docs/2.5.x/reference/mvc.html#mvc-multipart">Spring Reference Manual</ulink>.
|
||||
</note>
|
||||
</para>
|
||||
<para>
|
||||
In sending a response to the client there are a number of ways to customize the behavior of the gateway. By default the gateway will
|
||||
simply acknowledge that the request was received by sending a 200 status code back. It is possible to customize this response by providing a
|
||||
'viewName' to be resolved by the Spring MVC <interfacename>ViewResolver</interfacename>.
|
||||
In the case that the gateway should expect a reply to the <interfacename>Message</interfacename> then setting the <property>expectReply</property> flag
|
||||
(constructor argument) will cause
|
||||
the gateway to wait for a reply <interfacename>Message</interfacename> before creating an HTTP response. Below is an example of a gateway
|
||||
configured to serve as a Spring MVC Controller with a view name. Because of the constructor arg value of TRUE, it wait for a reply. This also shows
|
||||
how to customize the HTTP methods accepted by the gateway, which
|
||||
are <emphasis>POST</emphasis> and <emphasis>GET</emphasis> by default.
|
||||
<programlisting language="xml"><![CDATA[<bean id="httpInbound"
|
||||
class="org.springframework.integration.http.inbound.HttpRequestHandlingController">
|
||||
<constructor-arg value="true" /> <!-- indicates that a reply is expected -->
|
||||
<property name="requestChannel" ref="httpRequestChannel" />
|
||||
<property name="replyChannel" ref="httpReplyChannel" />
|
||||
<property name="viewName" value="jsonView" />
|
||||
<property name="supportedMethodNames" >
|
||||
<list>
|
||||
<value>GET</value>
|
||||
<value>DELETE</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>]]></programlisting>
|
||||
The reply message will be available in the Model map. The key that is used
|
||||
for that map entry by default is 'reply', but this can be overridden by setting the
|
||||
'replyKey' property on the endpoint's configuration.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="http-outbound">
|
||||
<title>Http Outbound Gateway</title>
|
||||
|
||||
<para>
|
||||
To configure the <classname>HttpRequestExecutingMessageHandler</classname> write a bean definition like this:
|
||||
<programlisting language="xml"><![CDATA[<bean id="httpOutbound"
|
||||
class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
|
||||
<constructor-arg value="http://localhost:8080/example" />
|
||||
<property name="outputChannel" ref="responseChannel" />
|
||||
</bean>]]></programlisting>
|
||||
This bean definition will execute HTTP requests by delegating to a <classname>RestTemplate</classname>. That template in turn delegates
|
||||
to a list of HttpMessageConverters to generate the HTTP request body from the Message payload. You can configure those converters as well
|
||||
as the ClientHttpRequestFactory instance to use:
|
||||
<programlisting language="xml"><![CDATA[<bean id="httpOutbound"
|
||||
class="org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler">
|
||||
<constructor-arg value="http://localhost:8080/example" />
|
||||
<property name="outputChannel" ref="responseChannel" />
|
||||
<property name="messageConverters" ref="messageConverterList" />
|
||||
<property name="requestFactory" ref="customRequestFactory" />
|
||||
</bean>]]></programlisting>
|
||||
By default the HTTP request will be generated using an instance of <classname>SimpleClientHttpRequestFactory</classname> which uses the JDK
|
||||
<classname>HttpURLConnection</classname>. Use of the Apache Commons HTTP Client is also supported through the provided
|
||||
<classname>CommonsClientHttpRequestFactory</classname> which can be injected as shown above.
|
||||
</para>
|
||||
<para>
|
||||
<note>
|
||||
In the case of the Outbound Gateway, the reply message produced by the gateway will contain all Message Headers present in the request message.
|
||||
</note>
|
||||
</para>
|
||||
<para><emphasis>Cookies</emphasis></para>
|
||||
<para>
|
||||
Basic cookie support is provided by the <emphasis>transfer-cookies</emphasis> attribute on the outbound gateway. When
|
||||
set to true (default is false), a <emphasis>Set-Cookie</emphasis> header received from the server in a response will be
|
||||
converted to <emphasis>Cookie</emphasis> in the reply message. This header will then be used
|
||||
on subsequent sends. This enables simple stateful interactions, such as...
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>...->logonGateway->...->doWorkGateway->...->logoffGateway->...</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
If <emphasis>transfer-cookies</emphasis> is false, any <emphasis>Set-Cookie</emphasis> header received will
|
||||
remain as <emphasis>Set-Cookie</emphasis> in the reply message, and will be dropped on subsequent sends.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="http-namespace">
|
||||
<title>HTTP Namespace Support</title>
|
||||
<para>
|
||||
Spring Integration provides an "http" namespace and schema definition. To include it in your
|
||||
configuration, simply provide the following URI within a namespace declaration:
|
||||
'http://www.springframework.org/schema/integration/http'. The schema location should then map to
|
||||
'http://www.springframework.org/schema/integration/http/spring-integration-http.xsd'.
|
||||
</para>
|
||||
<para>
|
||||
To configure an inbound http channel adapter which is an instance of <classname>HttpInboundEndpoint</classname> configured
|
||||
not to expect a response.
|
||||
<programlisting language="xml"><![CDATA[<int-http:inbound-channel-adapter id="httpChannelAdapter" channel="requests"
|
||||
supported-methods="PUT, DELETE"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
To configure an inbound http gateway which expects a response.
|
||||
<programlisting language="xml"><![CDATA[ <int-http:inbound-gateway id="inboundGateway"
|
||||
request-channel="requests"
|
||||
reply-channel="responses"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
To configure the outbound gateway you can use the namespace support as well. The following code snippet shows the different configuration options for an outbound Http gateway. Most importantly, notice that the 'http-method' and 'expected-response-type' are provided. Those are two of the most commonly configured values. The
|
||||
default http-method is POST, and the default response type is <emphasis>null</emphasis>. With a null response type, the payload of the reply Message would only
|
||||
contain the status code (e.g. 200) as long as it's a successful status (non-successful status codes will throw Exceptions). If you are expecting a different
|
||||
type, such as a <classname>String</classname>, then provide that fully-qualified class name as shown below.
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway id="example"
|
||||
request-channel="requests"
|
||||
url="http://localhost/test"
|
||||
http-method="POST"
|
||||
extract-request-payload="false"
|
||||
expected-response-type="java.lang.String"
|
||||
charset="UTF-8"
|
||||
request-factory="requestFactory"
|
||||
request-timeout="1234"
|
||||
reply-channel="replies"/>]]></programlisting>
|
||||
</para>
|
||||
<para>If your outbound adapter is to be used in a unidirectional way, then you can use an outbound-channel-adapter instead. This means that
|
||||
a successful response will simply execute without sending any Messages to a reply channel. In the case of any non-successful response
|
||||
status code, it will throw an exception. The configuration looks very similar to the gateway:
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-channel-adapter id="example"
|
||||
url="http://localhost/example"
|
||||
http-method="GET"
|
||||
channel="requests"
|
||||
charset="UTF-8"
|
||||
extract-payload="false"
|
||||
expected-response-type="java.lang.String"
|
||||
request-factory="someRequestFactory"
|
||||
order="3"
|
||||
auto-startup="false"/>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Mapping URI variables</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
If your URL contains URI variables you can map them using <code>uri-variable</code> sub element in
|
||||
<emphasis>Http Outbound Gateway</emphasis> configuration.
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway id="trafficGateway"
|
||||
url="http://local.yahooapis.com/trafficData?appid=YdnDemo&zip={zipCode}"
|
||||
request-channel="trafficChannel"
|
||||
http-method="GET"
|
||||
expected-response-type="java.lang.String">
|
||||
<int-http:uri-variable name="zipCode" expression="payload.getZip()"/>
|
||||
</int-http:outbound-gateway>]]></programlisting>
|
||||
|
||||
The <code>uri-variable</code> defines two attributes <code>expression</code> and <code>value</code>. You generally use
|
||||
the <code>value</code> attribute for literal values, but if the value you are trying to inject is dynamic and requires
|
||||
access to Message data you can use a SpEL expression via the <code>expression</code> attribute. In the above configuration
|
||||
the <code>getZip()</code> method will be invoked on the payload object of the Message and the result of that
|
||||
method will be used as the value for URI variable named 'zipCode'.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="http-proxy">
|
||||
<title>HTTP Proxy configuration</title>
|
||||
|
||||
<para>
|
||||
If you are behind a proxy and need to configure proxy settings for HTTP outbound adapters and/or
|
||||
gateways, you can apply one of two approaches. In most cases, you can rely on the standard Java
|
||||
System Properties that control the proxy settings. Otherwise, you can explicitly configure a
|
||||
Spring bean for the HTTP client request factory instance.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Standard Java Proxy configuration</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are 3 System Properties you can set to configure the proxy settings that will be used by the HTTP protocol handler:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis>http.proxyHost</emphasis> - the host name of the proxy server. </para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>http.proxyPort</emphasis> - the port number, the default value being 80. </para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>http.nonProxyHosts</emphasis> - a list of hosts that should be reached directly,
|
||||
bypassing the proxy. This is a list of patterns separated by '|'. The patterns may start or end with a '*' for wildcards. Any host matching one of these patterns will be reached through a direct connection instead of through a proxy. </para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
And for HTTPS:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis>https.proxyHost</emphasis> - the host name of the proxy server. </para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>https.proxyPort</emphasis> - the port number, the default value being 80. </para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
For more information please refer to this document: http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Spring's SimpleClientHttpRequestFactory</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
If for any reason, you need more explicit control over the proxy configuration, you can use Spring's
|
||||
<classname>SimpleClientHttpRequestFactory</classname> and configure its 'proxy' property as such:
|
||||
<programlisting language="xml"><![CDATA[<bean id="requestFactory"
|
||||
class="org.springframework.http.client.SimpleClientHttpRequestFactory">
|
||||
<property name="proxy">
|
||||
<bean id="proxy" class="java.net.Proxy">
|
||||
<constructor-arg>
|
||||
<util:constant static-field="java.net.Proxy.Type.HTTP"/>
|
||||
</constructor-arg>
|
||||
<constructor-arg>
|
||||
<bean class="java.net.InetSocketAddress">
|
||||
<constructor-arg value="123.0.0.1"/>
|
||||
<constructor-arg value="8080"/>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>]]></programlisting>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
<section id="http-header-mapping">
|
||||
<title> HTTP Header Mappings</title>
|
||||
<para>
|
||||
Spring Integration provides support for Http Header mapping for both HTTP Request and HTTP Responses.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By default all standard Http Headers as defined here
|
||||
http://en.wikipedia.org/wiki/List_of_HTTP_header_fields will be mapped from the message to HTTP request/response headers without
|
||||
further configuration.
|
||||
However if you do need further customization you may provide additional configuration via convenient namespace support.
|
||||
You can provide a comma-separated list of header names, and you can also include simple patterns with the '*' character acting as a wildcard.
|
||||
If you do provide such values, it will override the default behavior. Basically, it assumes you are in complete control at that point.
|
||||
However, if you do want to include all of the standard HTTP headers, you can use the shortcut patterns: HTTP_REQUEST_HEADERS and
|
||||
HTTP_RESPONSE_HEADERS. Here are some examples:
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway id="httpGateway"
|
||||
url="http://localhost/test2"
|
||||
mapped-request-headers="foo, bar"
|
||||
mapped-response-headers="X-*, HTTP_RESPONSE_HEADERS"
|
||||
channel="someChannel"/>
|
||||
|
||||
<int-http:outbound-channel-adapter id="httpAdapter"
|
||||
url="http://localhost/test2"
|
||||
mapped-request-headers="foo, bar, HTTP_REQUEST_HEADERS"
|
||||
channel="someChannel"/>]]></programlisting>
|
||||
|
||||
The adapters and gateways will use the <classname>DefaultHttpHeaderMapper</classname> which now provides
|
||||
two static factory methods for "inbound" and "outbound" adapters so that the proper direction can be
|
||||
applied (mapping HTTP requests/responses IN/OUT as appropriate).
|
||||
</para>
|
||||
<para>
|
||||
If further customization is required you can also configure a <classname>DefaultHttpHeaderMapper</classname> independently
|
||||
and inject it into the adapter via the <code>header-mapper</code> attribute.
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int-http:outbound-gateway id="httpGateway"
|
||||
url="http://localhost/test2"
|
||||
header-mapper="headerMapper"
|
||||
channel="someChannel"/>
|
||||
|
||||
<bean id="headerMapper" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
|
||||
<property name="inboundHeaderNames" value="foo*, *bar, baz"/>
|
||||
<property name="outboundHeaderNames" value="a*b, d"/>
|
||||
</bean>]]></programlisting>
|
||||
</para>
|
||||
<para>Of course, you can even implement the HeaderMapper strategy interface directly and provide a reference to that
|
||||
if you need to do something other than what the <classname>DefaultHttpHeaderMapper</classname> supports.</para>
|
||||
</section>
|
||||
|
||||
<section id="http-samples">
|
||||
<title>HTTP Samples</title>
|
||||
<section id="multipart-rest-inbound">
|
||||
<title>Multipart HTTP request - RestTemplate (client) and Http Inbound Gateway (server)</title>
|
||||
<para>
|
||||
This example demonstrates how simple it is to send a Multipart HTTP request via Spring's RestTemplate and receive
|
||||
it with a Spring Integration HTTP Inbound Adapter. All we are doing is creating a <classname>MultiValueMap</classname> and
|
||||
populating it with multi-part data. The <classname>RestTemplate</classname> will take care of the rest (no pun intended) by
|
||||
converting it to a <classname>MultipartHttpServletRequest</classname> . This particular client will send a multipart HTTP Request
|
||||
which contains the name of the company as well as an image file with the company logo.
|
||||
<programlisting language="java"><![CDATA[RestTemplate template = new RestTemplate();
|
||||
String uri = "http://localhost:8080/multipart-http/inboundAdapter.htm";
|
||||
Resource s2logo =
|
||||
new ClassPathResource("org/springframework/samples/multipart/spring09_logo.png");
|
||||
MultiValueMap map = new LinkedMultiValueMap();
|
||||
map.add("company", "SpringSource");
|
||||
map.add("company-logo", s2logo);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(new MediaType("multipart", "form-data"));
|
||||
HttpEntity request = new HttpEntity(map, headers);
|
||||
ResponseEntity<?> httpResponse = template.exchange(uri, HttpMethod.POST, request, null);]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
That is all for the client.
|
||||
</para>
|
||||
<para>
|
||||
On the server side we have the following configuration:
|
||||
<programlisting language="xml"><![CDATA[<int-http:inbound-channel-adapter id="httpInboundAdapter"
|
||||
channel="receiveChannel"
|
||||
name="/inboundAdapter.htm"
|
||||
supported-methods="GET, POST" />
|
||||
|
||||
<int:channel id="receiveChannel"/>
|
||||
|
||||
<int:service-activator input-channel="receiveChannel">
|
||||
<bean class="org.springframework.integration.samples.multipart.MultipartReceiver"/>
|
||||
</int:service-activator>
|
||||
|
||||
<bean id="multipartResolver"
|
||||
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
|
||||
]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The 'httpInboundAdapter' will receive the request, convert it to a <classname>Message</classname> with a payload
|
||||
that is a <classname>LinkedMultiValueMap</classname>. We then are parsing that in the 'multipartReceiver' service-activator;
|
||||
<programlisting language="java"><![CDATA[public void receive(LinkedMultiValueMap<String, Object> multipartRequest){
|
||||
System.out.println("### Successfully received multipart request ###");
|
||||
for (String elementName : multipartRequest.keySet()) {
|
||||
if (elementName.equals("company")){
|
||||
System.out.println("\t" + elementName + " - " +
|
||||
((String[]) multipartRequest.getFirst("company"))[0]);
|
||||
}
|
||||
else if (elementName.equals("company-logo")){
|
||||
System.out.println("\t" + elementName + " - as UploadedMultipartFile: " +
|
||||
((UploadedMultipartFile) multipartRequest.getFirst("company-logo")).
|
||||
getOriginalFilename());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]]></programlisting>
|
||||
You should see the following output:
|
||||
<programlisting language="xml"><![CDATA[### Successfully received multipart request ###
|
||||
company - SpringSource
|
||||
company-logo - as UploadedMultipartFile: spring09_logo.png]]></programlisting>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user