z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
[Servlet Thread]
Start processing
Do some work
Send response
[Servlet Thread]
Start processing
Switch to async mode
Exit thread leaving response open
.
[Servlet Thread]
Start processing
Switch to async mode
Exit thread leaving response open
[Application Thread]
Produce or receive result
Dispatch to container to resume processing
.
[Servlet Thread]
Start processing
Switch to async mode
Exit thread leaving response open
[Application Thread]
Produce or receive result
Dispatch to container to resume processing
[Servlet Thread]
Start processing
Process result from application thread
Send response
@RequestMapping
return valuesjava.util.concurrent.Callable
DeferredResult
AsyncTask
@RequestMapping
asynchronously@RequestMapping
asynchronouslyCallable
with extrasAsyncTaskExecutor
Callable
HandlerExceptionResolver
mechanism@RequestMapping
methodsDeferredResult
DeferredResult
provides setErrorResult(Object)
HandlerExceptionResolver
mechanismasync-supported
flag in web.xmlOncePerRequestFilter
(+ all Spring MVC filters)AsyncHandlerInterceptor
afterConcurrentHandlingStarted
vs postProcess
/afterCompletion
WebMvcConfigurer.configureAsyncSupport
async-support
sub-element of annotation-driven
AsyncTaskExecutor
for Callable
processingweb.xml
Configurationasync-supported
flag on all Filters and Servletdispatcher-type
of ASYNC
for FiltersWebApplicationInitializer
async-supported
flag and dispatcher-type
public class DispatcherServletInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebMvcConfig.class };
}
protected String[] getServletMappings() {
return new String[] { "/" };
}
protected Filter[] getServletFilters() {
return new Filter[] { new OpenSessionInViewFilter() };
}
}
@ExceptionHandler
DefaultHandlerExceptionResovler
@ExceptionHandler
Methods@ControllerAdvice
- component annotation@ExceptionHandler
methods@ControllerAdvice
@InitBinder
methodsDataBinder
initialization@ModelAttribute
methodsResponseEntityExceptionHandler
DefaultHandlerExceptionResolver
ResponseEntity<Object>
response.sendError(int, String)
error-page
in web.xml"javax.servlet.error.status_code"
"javax.servlet.error.message"
See updated section on Exception Handling in reference docs
Global exception in Spring MVC Showcase
@ResponseBody
used 'Accept'
header@RequestMapping(produces="")
did likewiseContentNegotiatingViewResolver
...ContentNegotiationStrategy
'Accept'
Header/accounts/1?format=json
ContentNeogitationManager
ContentNegotiationStrategy
RequestMappingHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
ContentNegotiatingViewResolver
'Accept'
header only@ResponseBody
'Accept'
header 2nd.json
, .xml
auto-registered if libraries presentContentNegotiatingViewResolver
See section on Configuring Content Negotiation in reference docs
URL extension for content negotiation in Spring MVC Showcase
RFC 2396, section 3.3
/qa-releases;buildNumber=135;revision=3.2
/answers/id1;id2;id3;id4/comments
@MatrixVariable
args// GET /pets/42;q=11;r=22
@RequestMapping(value = "/pets/{petId}")
public void findPet(
@PathVariable String petId, @MatrixVariable int q) {
// petId == 42
// q == 11
}
// GET /owners/42;q=11;r=12/pets/21;q=22;s=23
@RequestMapping(value = "/owners/{ownerId}/pets/{petId}")
public void findPet(
@MatrixVariable Map<String, String> matrixVars) {
// matrixVars: ["q" : [11,22], "r" : 12, "s" : 23]
}
// GET /owners/42;q=11/pets/21;q=22
@RequestMapping(value = "/owners/{ownerId}/pets/{petId}")
public void findPet(
@MatrixVariable(value="q", pathVar="ownerId") int q1,
@MatrixVariable(value="q", pathVar="petId") int q2) {
// q1 == 11
// q2 == 22
}
MockHttpServletRequest/Response
spring-test
moduleDispatcherServlet
mockMvc.perform(get("/foo").accept("application/json"))
.andExpect(status().isOk())
.andExpect(content().mimeType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
Tests in Spring MVC Showcase
Client and Server sample tests in the Spring Framework
Testing Web Applications with Spring 3.2
(Thursday 10:15)
GenericHttpMessageConverter
HttpInputMessage
to generic target typeJaxb2CollectionHttpMessageConverter
RestTemplate
ParameterizedTypeReference<List<Integer>> listOfInts =
new ParameterizedTypeReference<List<Integer>>() {};
ResponseEntity<List<Integer>> result =
restTemplate.exchange(
"http://example.com/accounts",
HttpMethod.GET, null, listOfInts);
@RequestBody
@RequestMapping
public void handle(@RequestBody List<Integer> ints) {
}
JacksonObjectMapperFactoryBean