Skip to content

Commit 028b179

Browse files
author
Dennis Kieselhorst
authored
Merge pull request #755 from olegz/GH-754
GH-754 Fix request parameter parsing
2 parents 58b296f + 88f6e4a commit 028b179

File tree

5 files changed

+91
-5
lines changed

5 files changed

+91
-5
lines changed

aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/AwsSpringHttpProcessingUtils.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
import java.io.InputStream;
44
import java.nio.charset.StandardCharsets;
5+
import java.util.Iterator;
56
import java.util.Map;
7+
import java.util.Map.Entry;
8+
import java.util.Set;
69
import java.util.concurrent.CountDownLatch;
710
import java.util.concurrent.TimeUnit;
811

912
import org.apache.commons.logging.Log;
1013
import org.apache.commons.logging.LogFactory;
1114
import org.springframework.cloud.function.serverless.web.ServerlessHttpServletRequest;
1215
import org.springframework.cloud.function.serverless.web.ServerlessMVC;
16+
import org.springframework.util.CollectionUtils;
1317
import org.springframework.util.FileCopyUtils;
1418
import org.springframework.util.MultiValueMapAdapter;
1519
import org.springframework.util.StringUtils;
@@ -109,6 +113,9 @@ private static HttpServletRequest generateRequest1(String request, Context lambd
109113
AwsProxyRequest v1Request = readValue(request, AwsProxyRequest.class, mapper);
110114

111115
ServerlessHttpServletRequest httpRequest = new ServerlessHttpServletRequest(servletContext, v1Request.getHttpMethod(), v1Request.getPath());
116+
117+
populateQueryStringparameters(v1Request.getQueryStringParameters(), httpRequest);
118+
112119
if (v1Request.getMultiValueHeaders() != null) {
113120
MultiValueMapAdapter headers = new MultiValueMapAdapter(v1Request.getMultiValueHeaders());
114121
httpRequest.setHeaders(headers);
@@ -128,16 +135,21 @@ private static HttpServletRequest generateRequest1(String request, Context lambd
128135
securityWriter.writeSecurityContext(v1Request, lambdaContext));
129136
return httpRequest;
130137
}
138+
139+
131140

132141
@SuppressWarnings({ "rawtypes", "unchecked" })
133142
private static HttpServletRequest generateRequest2(String request, Context lambdaContext,
134143
SecurityContextWriter securityWriter, ObjectMapper mapper, ServletContext servletContext) {
135144
HttpApiV2ProxyRequest v2Request = readValue(request, HttpApiV2ProxyRequest.class, mapper);
145+
146+
136147
ServerlessHttpServletRequest httpRequest = new ServerlessHttpServletRequest(servletContext,
137148
v2Request.getRequestContext().getHttp().getMethod(), v2Request.getRequestContext().getHttp().getPath());
149+
populateQueryStringparameters(v2Request.getQueryStringParameters(), httpRequest);
138150

139151
v2Request.getHeaders().forEach(httpRequest::setHeader);
140-
152+
141153
if (StringUtils.hasText(v2Request.getBody())) {
142154
httpRequest.setContentType("application/json");
143155
httpRequest.setContent(v2Request.getBody().getBytes(StandardCharsets.UTF_8));
@@ -151,6 +163,14 @@ private static HttpServletRequest generateRequest2(String request, Context lambd
151163
return httpRequest;
152164
}
153165

166+
private static void populateQueryStringparameters(Map<String, String> requestParameters, ServerlessHttpServletRequest httpRequest) {
167+
if (!CollectionUtils.isEmpty(requestParameters)) {
168+
for (Entry<String, String> entry : requestParameters.entrySet()) {
169+
httpRequest.setParameter(entry.getKey(), entry.getValue());
170+
}
171+
}
172+
}
173+
154174
private static <T> T readValue(String json, Class<T> clazz, ObjectMapper mapper) {
155175
try {
156176
return mapper.readValue(json, clazz);

aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/SpringDelegatingLambdaContainerHandlerTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import org.junit.jupiter.params.ParameterizedTest;
1515
import org.junit.jupiter.params.provider.MethodSource;
16+
import org.springframework.cloud.function.serverless.web.ServerlessServletContext;
1617
import org.springframework.util.CollectionUtils;
1718

1819
import com.amazonaws.serverless.proxy.spring.servletapp.MessageData;
@@ -72,12 +73,16 @@ public class SpringDelegatingLambdaContainerHandlerTests {
7273
+ " },\n"
7374
+ " \"queryStringParameters\": {\n"
7475
+ " \"abc\": \"xyz\",\n"
76+
+ " \"name\": \"Ricky\",\n"
7577
+ " \"foo\": \"baz\"\n"
7678
+ " },\n"
7779
+ " \"multiValueQueryStringParameters\": {\n"
7880
+ " \"abc\": [\n"
7981
+ " \"xyz\"\n"
8082
+ " ],\n"
83+
+ " \"name\": [\n"
84+
+ " \"Ricky\"\n"
85+
+ " ],\n"
8186
+ " \"foo\": [\n"
8287
+ " \"bar\",\n"
8388
+ " \"baz\"\n"
@@ -124,7 +129,7 @@ public class SpringDelegatingLambdaContainerHandlerTests {
124129
" \"version\": \"2.0\",\n" +
125130
" \"routeKey\": \"$default\",\n" +
126131
" \"rawPath\": \"/my/path\",\n" +
127-
" \"rawQueryString\": \"parameter1=value1&parameter1=value2&parameter2=value\",\n" +
132+
" \"rawQueryString\": \"parameter1=value1&parameter1=value2&name=Ricky&parameter2=value\",\n" +
128133
" \"cookies\": [\n" +
129134
" \"cookie1\",\n" +
130135
" \"cookie2\"\n" +
@@ -135,6 +140,7 @@ public class SpringDelegatingLambdaContainerHandlerTests {
135140
" },\n" +
136141
" \"queryStringParameters\": {\n" +
137142
" \"parameter1\": \"value1,value2\",\n" +
143+
" \"name\": \"Ricky\",\n" +
138144
" \"parameter2\": \"value\"\n" +
139145
" },\n" +
140146
" \"requestContext\": {\n" +
@@ -202,6 +208,22 @@ public static Collection<String> data() {
202208
return Arrays.asList(new String[]{API_GATEWAY_EVENT, API_GATEWAY_EVENT_V2});
203209
}
204210

211+
@MethodSource("data")
212+
@ParameterizedTest
213+
public void validateComplesrequest(String jsonEvent) throws Exception {
214+
initServletAppTest();
215+
InputStream targetStream = new ByteArrayInputStream(this.generateHttpRequest(jsonEvent, "POST",
216+
"/foo/male/list/24", "{\"name\":\"bob\"}", null));
217+
ByteArrayOutputStream output = new ByteArrayOutputStream();
218+
handler.handleRequest(targetStream, output, null);
219+
Map result = mapper.readValue(output.toString(StandardCharsets.UTF_8), Map.class);
220+
assertEquals(200, result.get("statusCode"));
221+
String[] respponseBody = ((String) result.get("body")).split("/");
222+
assertEquals("male", respponseBody[0]);
223+
assertEquals("24", respponseBody[1]);
224+
assertEquals("Ricky", respponseBody[2]);
225+
}
226+
205227
@MethodSource("data")
206228
@ParameterizedTest
207229
public void testAsyncPost(String jsonEvent) throws Exception {

aws-serverless-java-container-springboot3/src/test/java/com/amazonaws/serverless/proxy/spring/servletapp/ServletApplication.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.amazonaws.serverless.proxy.spring.servletapp;
22

33
import org.springframework.boot.autoconfigure.SpringBootApplication;
4-
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
5-
import org.springframework.context.annotation.ComponentScan;
64
import org.springframework.context.annotation.Import;
5+
import org.springframework.http.MediaType;
6+
import org.springframework.web.bind.annotation.PathVariable;
7+
import org.springframework.web.bind.annotation.RequestMapping;
8+
import org.springframework.web.bind.annotation.RequestMethod;
9+
import org.springframework.web.bind.annotation.RequestParam;
10+
import org.springframework.web.bind.annotation.RestController;
711

812
@SpringBootApplication(exclude = {
913
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration.class,
@@ -14,5 +18,15 @@
1418
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class
1519
})
1620
@Import(MessageController.class)
21+
@RestController
1722
public class ServletApplication {
23+
24+
@RequestMapping(path = "/foo/{gender}/list/{age}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
25+
public String complexRequest(
26+
@PathVariable("gender") String gender,
27+
@PathVariable("age") String age,
28+
@RequestParam("name") String name
29+
) {
30+
return gender + "/" + age + "/" + name;
31+
}
1832
}

samples/springboot3/alt-pet-store/README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,21 @@ PetStoreApi - URL for application https://xxxxxxxxxx.execute-api.us-w
3636
---------------------------------------------------------------------------------------------------------
3737
3838
$ curl https://xxxxxxxxxx.execute-api.us-west-2.amazonaws.com/pets
39-
```
39+
```
40+
41+
You can also try a complex request passing both path and request parameters to complex endpoint such as this:
42+
43+
44+
```
45+
@RequestMapping(path = "/foo/{gender}/bar/{age}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
46+
public String complexRequest(@RequestBody String body,
47+
@PathVariable("gender") String gender,
48+
@PathVariable("age") String age,
49+
@RequestParam("name") String name
50+
)
51+
```
52+
For example.
53+
54+
```
55+
curl -d '{"key1":"value1", "key2":"value2"}' -H "Content-Type: application/json" -X POST https://zuhd709386.execute-api.us-east-2.amazonaws.com/foo/male/bar/25?name=Ricky
56+
```

samples/springboot3/alt-pet-store/src/main/java/com/amazonaws/serverless/sample/springboot3/controller/PetsController.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import com.amazonaws.serverless.sample.springboot3.model.Pet;
1818
import com.amazonaws.serverless.sample.springboot3.model.PetData;
1919

20+
import org.springframework.http.MediaType;
21+
import org.springframework.web.bind.annotation.PathVariable;
2022
import org.springframework.web.bind.annotation.RequestBody;
2123
import org.springframework.web.bind.annotation.RequestMapping;
2224
import org.springframework.web.bind.annotation.RequestMethod;
@@ -32,6 +34,7 @@
3234
@RestController
3335
@EnableWebMvc
3436
public class PetsController {
37+
3538
@RequestMapping(path = "/pets", method = RequestMethod.POST)
3639
public Pet createPet(@RequestBody Pet newPet) {
3740
if (newPet.getName() == null || newPet.getBreed() == null) {
@@ -73,5 +76,15 @@ public Pet listPets() {
7376
newPet.setName(PetData.getRandomName());
7477
return newPet;
7578
}
79+
80+
@RequestMapping(path = "/foo/{gender}/bar/{age}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
81+
public String complexRequest(@RequestBody String body,
82+
@PathVariable("gender") String gender,
83+
@PathVariable("age") String age,
84+
@RequestParam("name") String name
85+
) {
86+
System.out.println("Body: " + body + " - " + gender + "/" + age + "/" + name);
87+
return gender + "/" + age + "/" + name;
88+
}
7689

7790
}

0 commit comments

Comments
 (0)