|
|
|
@ -17,7 +17,7 @@ |
|
|
|
package org.springframework.test.web.servlet.samples.standalone; |
|
|
|
package org.springframework.test.web.servlet.samples.standalone; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.StringWriter; |
|
|
|
import java.io.StringWriter; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.nio.charset.Charset; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.concurrent.Callable; |
|
|
|
import java.util.concurrent.Callable; |
|
|
|
import java.util.concurrent.CompletableFuture; |
|
|
|
import java.util.concurrent.CompletableFuture; |
|
|
|
@ -78,7 +78,7 @@ public class AsyncTests { |
|
|
|
public void streaming() throws Exception { |
|
|
|
public void streaming() throws Exception { |
|
|
|
this.mockMvc.perform(get("/1").param("streaming", "true")) |
|
|
|
this.mockMvc.perform(get("/1").param("streaming", "true")) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andDo(r -> r.getAsyncResult()) // fetch async result similar to "asyncDispatch" builder
|
|
|
|
.andDo(MvcResult::getAsyncResult) // fetch async result similar to "asyncDispatch" builder
|
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(content().string("name=Joe")); |
|
|
|
.andExpect(content().string("name=Joe")); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -87,7 +87,7 @@ public class AsyncTests { |
|
|
|
public void streamingSlow() throws Exception { |
|
|
|
public void streamingSlow() throws Exception { |
|
|
|
this.mockMvc.perform(get("/1").param("streamingSlow", "true")) |
|
|
|
this.mockMvc.perform(get("/1").param("streamingSlow", "true")) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andDo(r -> r.getAsyncResult()) |
|
|
|
.andDo(MvcResult::getAsyncResult) |
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(content().string("name=Joe&someBoolean=true")); |
|
|
|
.andExpect(content().string("name=Joe&someBoolean=true")); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -96,7 +96,7 @@ public class AsyncTests { |
|
|
|
public void streamingJson() throws Exception { |
|
|
|
public void streamingJson() throws Exception { |
|
|
|
this.mockMvc.perform(get("/1").param("streamingJson", "true")) |
|
|
|
this.mockMvc.perform(get("/1").param("streamingJson", "true")) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andDo(r -> r.getAsyncResult()) |
|
|
|
.andDo(MvcResult::getAsyncResult) |
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(status().isOk()) |
|
|
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) |
|
|
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.5}")); |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.5}")); |
|
|
|
@ -129,10 +129,7 @@ public class AsyncTests { |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@Test // SPR-13079
|
|
|
|
* SPR-13079 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void deferredResultWithDelayedError() throws Exception { |
|
|
|
public void deferredResultWithDelayedError() throws Exception { |
|
|
|
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithDelayedError", "true")) |
|
|
|
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("deferredResultWithDelayedError", "true")) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
@ -157,10 +154,7 @@ public class AsyncTests { |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@Test // SPR-12597
|
|
|
|
* SPR-12597 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void completableFutureWithImmediateValue() throws Exception { |
|
|
|
public void completableFutureWithImmediateValue() throws Exception { |
|
|
|
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("completableFutureWithImmediateValue", "true")) |
|
|
|
MvcResult mvcResult = this.mockMvc.perform(get("/1").param("completableFutureWithImmediateValue", "true")) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
.andExpect(request().asyncStarted()) |
|
|
|
@ -172,10 +166,7 @@ public class AsyncTests { |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
.andExpect(content().string("{\"name\":\"Joe\",\"someDouble\":0.0,\"someBoolean\":false}")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@Test // SPR-12735
|
|
|
|
* SPR-12735 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void printAsyncResult() throws Exception { |
|
|
|
public void printAsyncResult() throws Exception { |
|
|
|
StringWriter writer = new StringWriter(); |
|
|
|
StringWriter writer = new StringWriter(); |
|
|
|
|
|
|
|
|
|
|
|
@ -203,12 +194,9 @@ public class AsyncTests { |
|
|
|
@RequestMapping(path = "/{id}", produces = "application/json") |
|
|
|
@RequestMapping(path = "/{id}", produces = "application/json") |
|
|
|
private static class AsyncController { |
|
|
|
private static class AsyncController { |
|
|
|
|
|
|
|
|
|
|
|
private final Collection<DeferredResult<Person>> deferredResults = |
|
|
|
private final Collection<DeferredResult<Person>> deferredResults = new CopyOnWriteArrayList<>(); |
|
|
|
new CopyOnWriteArrayList<DeferredResult<Person>>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Collection<ListenableFutureTask<Person>> futureTasks = |
|
|
|
|
|
|
|
new CopyOnWriteArrayList<ListenableFutureTask<Person>>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Collection<ListenableFutureTask<Person>> futureTasks = new CopyOnWriteArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "callable") |
|
|
|
@RequestMapping(params = "callable") |
|
|
|
public Callable<Person> getCallable() { |
|
|
|
public Callable<Person> getCallable() { |
|
|
|
@ -217,7 +205,7 @@ public class AsyncTests { |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "streaming") |
|
|
|
@RequestMapping(params = "streaming") |
|
|
|
public StreamingResponseBody getStreaming() { |
|
|
|
public StreamingResponseBody getStreaming() { |
|
|
|
return os -> os.write("name=Joe".getBytes()); |
|
|
|
return os -> os.write("name=Joe".getBytes(Charset.forName("UTF-8"))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "streamingSlow") |
|
|
|
@RequestMapping(params = "streamingSlow") |
|
|
|
@ -226,7 +214,7 @@ public class AsyncTests { |
|
|
|
os.write("name=Joe".getBytes()); |
|
|
|
os.write("name=Joe".getBytes()); |
|
|
|
try { |
|
|
|
try { |
|
|
|
Thread.sleep(200); |
|
|
|
Thread.sleep(200); |
|
|
|
os.write("&someBoolean=true".getBytes()); |
|
|
|
os.write("&someBoolean=true".getBytes(Charset.forName("UTF-8"))); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (InterruptedException e) { |
|
|
|
catch (InterruptedException e) { |
|
|
|
/* no-op */ |
|
|
|
/* no-op */ |
|
|
|
@ -237,26 +225,26 @@ public class AsyncTests { |
|
|
|
@RequestMapping(params = "streamingJson") |
|
|
|
@RequestMapping(params = "streamingJson") |
|
|
|
public ResponseEntity<StreamingResponseBody> getStreamingJson() { |
|
|
|
public ResponseEntity<StreamingResponseBody> getStreamingJson() { |
|
|
|
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8) |
|
|
|
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON_UTF8) |
|
|
|
.body(os -> os.write("{\"name\":\"Joe\",\"someDouble\":0.5}".getBytes(StandardCharsets.UTF_8))); |
|
|
|
.body(os -> os.write("{\"name\":\"Joe\",\"someDouble\":0.5}".getBytes(Charset.forName("UTF-8")))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "deferredResult") |
|
|
|
@RequestMapping(params = "deferredResult") |
|
|
|
public DeferredResult<Person> getDeferredResult() { |
|
|
|
public DeferredResult<Person> getDeferredResult() { |
|
|
|
DeferredResult<Person> deferredResult = new DeferredResult<Person>(); |
|
|
|
DeferredResult<Person> deferredResult = new DeferredResult<>(); |
|
|
|
this.deferredResults.add(deferredResult); |
|
|
|
this.deferredResults.add(deferredResult); |
|
|
|
return deferredResult; |
|
|
|
return deferredResult; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "deferredResultWithImmediateValue") |
|
|
|
@RequestMapping(params = "deferredResultWithImmediateValue") |
|
|
|
public DeferredResult<Person> getDeferredResultWithImmediateValue() { |
|
|
|
public DeferredResult<Person> getDeferredResultWithImmediateValue() { |
|
|
|
DeferredResult<Person> deferredResult = new DeferredResult<Person>(); |
|
|
|
DeferredResult<Person> deferredResult = new DeferredResult<>(); |
|
|
|
deferredResult.setResult(new Person("Joe")); |
|
|
|
deferredResult.setResult(new Person("Joe")); |
|
|
|
return deferredResult; |
|
|
|
return deferredResult; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "deferredResultWithDelayedError") |
|
|
|
@RequestMapping(params = "deferredResultWithDelayedError") |
|
|
|
public DeferredResult<Person> getDeferredResultWithDelayedError() { |
|
|
|
public DeferredResult<Person> getDeferredResultWithDelayedError() { |
|
|
|
final DeferredResult<Person> deferredResult = new DeferredResult<Person>(); |
|
|
|
final DeferredResult<Person> deferredResult = new DeferredResult<>(); |
|
|
|
new Thread() { |
|
|
|
new Thread() { |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
try { |
|
|
|
try { |
|
|
|
@ -273,14 +261,14 @@ public class AsyncTests { |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "listenableFuture") |
|
|
|
@RequestMapping(params = "listenableFuture") |
|
|
|
public ListenableFuture<Person> getListenableFuture() { |
|
|
|
public ListenableFuture<Person> getListenableFuture() { |
|
|
|
ListenableFutureTask<Person> futureTask = new ListenableFutureTask<Person>(() -> new Person("Joe")); |
|
|
|
ListenableFutureTask<Person> futureTask = new ListenableFutureTask<>(() -> new Person("Joe")); |
|
|
|
this.futureTasks.add(futureTask); |
|
|
|
this.futureTasks.add(futureTask); |
|
|
|
return futureTask; |
|
|
|
return futureTask; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "completableFutureWithImmediateValue") |
|
|
|
@RequestMapping(params = "completableFutureWithImmediateValue") |
|
|
|
public CompletableFuture<Person> getCompletableFutureWithImmediateValue() { |
|
|
|
public CompletableFuture<Person> getCompletableFutureWithImmediateValue() { |
|
|
|
CompletableFuture<Person> future = new CompletableFuture<Person>(); |
|
|
|
CompletableFuture<Person> future = new CompletableFuture<>(); |
|
|
|
future.complete(new Person("Joe")); |
|
|
|
future.complete(new Person("Joe")); |
|
|
|
return future; |
|
|
|
return future; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -291,7 +279,7 @@ public class AsyncTests { |
|
|
|
return e.getMessage(); |
|
|
|
return e.getMessage(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void onMessage(String name) { |
|
|
|
void onMessage(String name) { |
|
|
|
for (DeferredResult<Person> deferredResult : this.deferredResults) { |
|
|
|
for (DeferredResult<Person> deferredResult : this.deferredResults) { |
|
|
|
deferredResult.setResult(new Person(name)); |
|
|
|
deferredResult.setResult(new Person(name)); |
|
|
|
this.deferredResults.remove(deferredResult); |
|
|
|
this.deferredResults.remove(deferredResult); |
|
|
|
|