10 changed files with 344 additions and 35 deletions
@ -0,0 +1,99 @@
@@ -0,0 +1,99 @@
|
||||
/* |
||||
* Copyright 2002-2010 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.http.client; |
||||
|
||||
import java.io.IOException; |
||||
import java.net.InetSocketAddress; |
||||
import java.net.ServerSocket; |
||||
import java.util.Random; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Utility class that finds free BSD ports for use in testing scenario's. |
||||
* |
||||
* @author Ben Hale |
||||
* @author Arjen Poutsma |
||||
*/ |
||||
public abstract class FreePortScanner { |
||||
|
||||
private static final int MIN_SAFE_PORT = 1024; |
||||
|
||||
private static final int MAX_PORT = 65535; |
||||
|
||||
private static final Random random = new Random(); |
||||
|
||||
/** |
||||
* Returns the number of a free port in the default range. |
||||
*/ |
||||
public static int getFreePort() { |
||||
return getFreePort(MIN_SAFE_PORT, MAX_PORT); |
||||
} |
||||
|
||||
/** |
||||
* Returns the number of a free port in the given range. |
||||
*/ |
||||
public static int getFreePort(int minPort, int maxPort) { |
||||
Assert.isTrue(minPort > 0, "'minPort' must be larger than 0"); |
||||
Assert.isTrue(maxPort > minPort, "'maxPort' must be larger than minPort"); |
||||
int portRange = maxPort - minPort; |
||||
int candidatePort; |
||||
int searchCounter = 0; |
||||
do { |
||||
if (++searchCounter > portRange) { |
||||
throw new IllegalStateException( |
||||
String.format("There were no ports available in the range %d to %d", minPort, maxPort)); |
||||
} |
||||
candidatePort = getRandomPort(minPort, portRange); |
||||
} |
||||
while (!isPortAvailable(candidatePort)); |
||||
|
||||
return candidatePort; |
||||
} |
||||
|
||||
private static int getRandomPort(int minPort, int portRange) { |
||||
return minPort + random.nextInt(portRange); |
||||
} |
||||
|
||||
private static boolean isPortAvailable(int port) { |
||||
ServerSocket serverSocket; |
||||
try { |
||||
serverSocket = new ServerSocket(); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new IllegalStateException("Unable to create ServerSocket.", ex); |
||||
} |
||||
|
||||
try { |
||||
InetSocketAddress sa = new InetSocketAddress(port); |
||||
serverSocket.bind(sa); |
||||
return true; |
||||
} |
||||
catch (IOException ex) { |
||||
return false; |
||||
} |
||||
finally { |
||||
try { |
||||
serverSocket.close(); |
||||
} |
||||
catch (IOException ex) { |
||||
// ignore
|
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,172 @@
@@ -0,0 +1,172 @@
|
||||
/* |
||||
* Copyright 2002-2011 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.mvc.method.annotation.support; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
import java.net.URI; |
||||
import java.util.Arrays; |
||||
|
||||
import org.junit.AfterClass; |
||||
import org.junit.Before; |
||||
import org.junit.BeforeClass; |
||||
import org.junit.Test; |
||||
import org.mortbay.jetty.Server; |
||||
import org.mortbay.jetty.servlet.Context; |
||||
import org.mortbay.jetty.servlet.ServletHolder; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
import org.springframework.http.HttpEntity; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.http.client.FreePortScanner; |
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; |
||||
import org.springframework.http.converter.HttpMessageConverter; |
||||
import org.springframework.http.converter.ResourceHttpMessageConverter; |
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; |
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.util.LinkedMultiValueMap; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestMethod; |
||||
import org.springframework.web.bind.annotation.RequestPart; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
import org.springframework.web.multipart.MultipartResolver; |
||||
import org.springframework.web.multipart.commons.CommonsMultipartResolver; |
||||
import org.springframework.web.servlet.DispatcherServlet; |
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc; |
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; |
||||
|
||||
/** |
||||
* Test access to parts of a multipart request with {@link RequestPart}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class RequestPartIntegrationTests { |
||||
|
||||
private RestTemplate restTemplate; |
||||
|
||||
private static Server server; |
||||
|
||||
private static String baseUrl; |
||||
|
||||
@BeforeClass |
||||
public static void startServer() throws Exception { |
||||
|
||||
int port = FreePortScanner.getFreePort(); |
||||
baseUrl = "http://localhost:" + port; |
||||
|
||||
server = new Server(port); |
||||
Context context = new Context(server, "/"); |
||||
|
||||
ServletHolder commonsResolverServlet = new ServletHolder(DispatcherServlet.class); |
||||
commonsResolverServlet.setInitParameter("contextConfigLocation", CommonsMultipartResolverTestConfig.class.getName()); |
||||
commonsResolverServlet.setInitParameter("contextClass", AnnotationConfigWebApplicationContext.class.getName()); |
||||
context.addServlet(commonsResolverServlet, "/commons/*"); |
||||
|
||||
server.start(); |
||||
} |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
XmlAwareFormHttpMessageConverter converter = new XmlAwareFormHttpMessageConverter(); |
||||
converter.setPartConverters(Arrays.<HttpMessageConverter<?>>asList( |
||||
new ResourceHttpMessageConverter(), new MappingJacksonHttpMessageConverter())); |
||||
|
||||
restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); |
||||
restTemplate.setMessageConverters(Arrays.<HttpMessageConverter<?>>asList(converter)); |
||||
} |
||||
|
||||
@AfterClass |
||||
public static void stopServer() throws Exception { |
||||
if (server != null) { |
||||
server.stop(); |
||||
} |
||||
} |
||||
|
||||
@Test |
||||
public void commonsMultipartResolver() throws Exception { |
||||
|
||||
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>(); |
||||
HttpEntity<TestData> jsonEntity = new HttpEntity<TestData>(new TestData("Jason")); |
||||
parts.add("json-data", jsonEntity); |
||||
parts.add("file-data", new ClassPathResource("logo.jpg", this.getClass())); |
||||
|
||||
URI location = restTemplate.postForLocation(baseUrl + "/commons/test", parts); |
||||
assertEquals("http://localhost:8080/test/Jason/logo.jpg", location.toString()); |
||||
} |
||||
|
||||
@Configuration |
||||
@EnableWebMvc |
||||
static class RequestPartTestConfig extends WebMvcConfigurerAdapter { |
||||
|
||||
@Bean |
||||
public RequestPartTestController controller() { |
||||
return new RequestPartTestController(); |
||||
} |
||||
} |
||||
|
||||
static class CommonsMultipartResolverTestConfig extends RequestPartTestConfig { |
||||
|
||||
@Bean |
||||
public MultipartResolver multipartResolver() { |
||||
return new CommonsMultipartResolver(); |
||||
} |
||||
|
||||
} |
||||
|
||||
@SuppressWarnings("unused") |
||||
@Controller |
||||
private static class RequestPartTestController { |
||||
|
||||
@RequestMapping(value = "/test", method = RequestMethod.POST, consumes = { "multipart/mixed", "multipart/form-data" }) |
||||
public ResponseEntity<Object> create(@RequestPart("json-data") TestData testData, @RequestPart("file-data") MultipartFile file) { |
||||
String url = "http://localhost:8080/test/" + testData.getName() + "/" + file.getOriginalFilename(); |
||||
HttpHeaders headers = new HttpHeaders(); |
||||
headers.setLocation(URI.create(url)); |
||||
return new ResponseEntity<Object>(headers, HttpStatus.CREATED); |
||||
} |
||||
} |
||||
|
||||
@SuppressWarnings("unused") |
||||
private static class TestData { |
||||
|
||||
private String name; |
||||
|
||||
public TestData() { |
||||
super(); |
||||
} |
||||
|
||||
public TestData(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
} |
||||
|
||||
} |
After Width: | Height: | Size: 17 KiB |
Loading…
Reference in new issue