在spring mvc3.2及以上版本增加了對請求的異步處理,是在servlet3的基礎上進行封裝的。
1、修改web.xml
1
2
3
4
5
6
7
|
<? xml version = "1.0" encoding = "UTF-8" ?> < web-app version = "3.0" xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> ... </ web-app > |
1.1、聲明version="3.0",聲明web-app_3_0.xsd
1.2、為servlet或者filter設置啟用異步支持: <async-supported>true</async-supported> ,修改WEB應用的web.xml
1
2
3
4
5
6
7
8
9
10
11
|
<!-- spring mvc --> < servlet > < servlet-name >SpringMvc</ servlet-name > < servlet-class >org.springframework.web.servlet.DispatcherServlet</ servlet-class > < init-param > < param-name >contextConfigLocation</ param-name > < param-value >...</ param-value > </ init-param > < load-on-startup >1</ load-on-startup > < async-supported >true</ async-supported > </ servlet > |
2、使controller類支持async
2.1、返回java.util.concurrent.Callable來完成異步處理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package org.springframework.samples.mvc.async; import java.util.concurrent.Callable; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.async.WebAsyncTask; @Controller @RequestMapping ( "/async/callable" ) public class CallableController { @RequestMapping ( "/response-body" ) public @ResponseBody Callable<String> callable() { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep( 2000 ); return "Callable result" ; } }; } @RequestMapping ( "/view" ) public Callable<String> callableWithView( final Model model) { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep( 2000 ); model.addAttribute( "foo" , "bar" ); model.addAttribute( "fruit" , "apple" ); return "views/html" ; } }; } @RequestMapping ( "/exception" ) public @ResponseBody Callable<String> callableWithException( final @RequestParam (required= false , defaultValue= "true" ) boolean handled) { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep( 2000 ); if (handled) { // see handleException method further below throw new IllegalStateException( "Callable error" ); } else { throw new IllegalArgumentException( "Callable error" ); } } }; } @RequestMapping ( "/custom-timeout-handling" ) public @ResponseBody WebAsyncTask<String> callableWithCustomTimeoutHandling() { Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { Thread.sleep( 2000 ); return "Callable result" ; } }; return new WebAsyncTask<String>( 1000 , callable); } @ExceptionHandler @ResponseBody public String handleException(IllegalStateException ex) { return "Handled exception: " + ex.getMessage(); } } |
2.2、在異步處理完成時返回org.springframework.web.context.request.async.DeferredResult其他線程,例如一個JMS或一個AMQP消息,Redis通知等等:
1
2
3
4
5
6
7
8
9
10
11
|
@RequestMapping ( "/quotes" ) @ResponseBody public DeferredResult<String> quotes() { DeferredResult<String> deferredResult = new DeferredResult<String>(); // Add deferredResult to a Queue or a Map... return deferredResult; } // In some other thread... deferredResult.setResult(data); // Remove deferredResult from the Queue or Map |
3、spring配置文件的修改
spring mvc的dtd的聲明必須大于等于3.2
1
2
3
4
|
< mvc:annotation-driven > <!-- 可不設置,使用默認的超時時間 --> < mvc:async-support default-timeout = "3000" /> </ mvc:annotation-driven > |
實際使用示例:
1
2
3
4
5
6
|
function deferred(){ $.get( 'quotes.htm' , function (data){ console.log(data); deferred(); //每次請求完成,再發一次請求,避免客戶端定時刷新來獲取數據 }); } |
這么做的好處避免web server的連接池被長期占用而引起性能問題,調用后生成一個非web的服務線程來處理,增加web服務器的吞吐量~~
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/yangzhilong/p/3725128.html