Configuration
通過類ch.ralscha.extdirectspring.controller.Configuration可以方便的微調ExtDirectSpring。
RemotingProvider Configuration
可以通過三個屬性timeout, maxRetries and enableBuffer配置RemotingProvider。
<bean id="extDirectSpringConfiguration"
class="ch.ralscha.extdirectspring.controller.Configuration"
p:timeout="12000" p:maxRetries="10" p:enableBuffer="false"/>
如果指定了這些參數,這些參數將會成爲api.js的一部分。
上面配置調用api-debug.js的輸出例子如下。
Ext.app.REMOTING_API = {
"url" : "/controller/router",
"type" : "remoting",
"actions" : {
"treeProvider" : [ {
"name" : "getTree",
"len" : 1
} ]
},
"timeout" : 12000,
"maxRetries" : 10,
"enableBuffer" : false
};
如果沒有特殊配置api.js將不會包含這些屬性。RemotingProvider將會用默認的配置:timeout=30000, maxRetries=1和enableBuffer=10
providerType (since 1.2.2)
可以全局設置Configuration.providerType屬性。Extjs使用這個值找到對應的Provider"類"(第一個字母大寫,加“Provider”)默認值是'remoting',並在Ext JS中創建一個Ext.direct.RemotingProvider的。
如下創建了Ext.direct.SampleProvider,並在Ext Direct調用。
<bean id="extDirectSpringConfiguration"
class="ch.ralscha.extdirectspring.controller.Configuration"
p:providerType="sample"/>
輸出api-debug.js如下:
Ext.app.REMOTING_API = {
"url" : "/demo/router",
"type" : "sample",
"actions" : {
...
} ]
}
};
synchronizeOnSession會話同步
默認爲false。將此屬性設置爲true,將會一個同步塊中調用一個@ ExtDirectMethod。這是非常有用的,當服務器的方法需要操縱會話對象。
<bean id="extDirectSpringConfiguration"
class="ch.ralscha.extdirectspring.controller.Configuration"
p:synchronizeOnSession="true"
除了全局開啓此功能,每一個方法都可以單獨指定synchronizeOnSession在@ExtDirectMethod註解。
@ExtDirectMethod(value = ExtDirectMethodType.STORE_MODIFY, synchronizeOnSession=true)
public List<User> create(List<User> newUsers) {
//...
}
FORM_POST方法不支持這個功能,如果你按老的格式寫ExtDirect方法,如果你按新的1.2.1的格式支持。
streamResponse (since 1.1.0)
這個特性需要特殊指出的是 Jackson ObjectMapper應該像1.0.x的版本那樣直接將返回寫到http servlet response並且不設置http header Content-Length (**true**)。如果設置爲false(默認值)ObjectMapper 先寫返回到內部buffer,設置Content-Length header ,然後將要返回響應寫道http servlet response。
除了可以全局開啓這個功能設置,每個方法可以獨立設置streamResponse屬性在註釋@ExtDirectMethod
Content-Type for api.js (since 1.2.1)
默認請求 api.js和api-debug.js的返回的Content-Type是"application/javascript"。這個值可以改變通過設置 jsContentType。
<bean id="extDirectSpringConfiguration"
class="ch.ralscha.extdirectspring.controller.Configuration"
p:jsContentType="application/x-javascript"/>
或用JavaConfig
@Bean
public ch.ralscha.extdirectspring.controller.Configuration configuration() {
ch.ralscha.extdirectspring.controller.Configuration config = new ch.ralscha.extdirectspring.controller.Configuration();
config.setJsContentType("application/x-javascript")
return config;
}
Error Messages
沒有特殊配置,服務器發生異常,返回到客戶端消息包含message“Server Error”和type“exception”。
[
{
"method": "method4",
"action": "remoteProviderSimple",
"tid": 2,
"message": "Server Error",
"type": "exception"
}
]
調整返回的消息需要增加一個bean id爲“extDirectSpringConfiguration”和class爲“ch.ralscha.extdirectspring.controller.Configuration”到spring上下文。
<context:component-scan base-package="ch.ralscha.extdirectspring" />
<mvc:annotation-driven />
<bean id="extDirectSpringConfiguration"
class="ch.ralscha.extdirectspring.controller.Configuration"
p:defaultExceptionMessage="Panic!!!"
p:sendExceptionMessage="false"
p:sendStacktrace="true">
<property name="exceptionToMessage">
<map>
<entry key="java.lang.IllegalArgumentException"
value="illegal argument"/>
<entry key="org.springframework.beans.factory.NoSuchBeanDefinitionException">
<null/>
</entry>
</map>
</property>
</bean>
defaultExceptionMessage | Defines the default exception message. Field *message* in the response | Default: 'Server Error' |
sendExceptionMessage | If true sends exception.getMessage() back. Field *message* in the response | Default: false |
sendStacktrace | If true sends the whole stacktrace in the field *where* back | Default: false |
exceptionToMessage | Mapping from exception class (key) to message (value) | Default: empty |
消息返回規則:
1.如果有對應的exception在exceptionToMessage並且值不是null返回此值。
2.如果有對應的exception在exceptionToMessage並且值是null返回exception.getMessage()。
3.如果沒有對應的exception在exceptionToMessage,並且sendExceptionMessage是true,返回exception.getMessage()。
4.如果沒有對應的exception在exceptionToMessage,並且sendExceptionMessage是false,返回defaultExceptionMessage。
Concurrent execution of batched method calls 併發執行批處理方法調用
如果該功能被禁用(默認),在請求處理線程上一個一個執行批處理方法。這可能是一個問題,如果一個方法執行很長時間,後面的方法將會一直處於等待狀態。
通過啓用此功能可以解決這個問題,它可以併發執行方法。要啓用它,設置併發batchedMethodsExecutionPolicy,與batchedMethodsExecutorService指定一個線程池。如果沒有指定線程池,默認創建有5個線程(Executors.newFixedThreadPool(5))的線程池。
<bean id="threadPool" class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean">
<property name="corePoolSize" value="50" />
<property name="maxPoolSize" value="200" />
<property name="queueCapacity" value="5000" />
</bean>
<bean id="extDirectSpringConfiguration" class="ch.ralscha.extdirectspring.controller.Configuration">
<property name="batchedMethodsExecutionPolicy" value="CONCURRENT" />
<property name="batchedMethodsExecutorService" ref="threadPool"/>
</bean>
JavaConfig
@Bean
public ThreadPoolExecutorFactoryBean threadPoolExecutorFactoryBean() {
ThreadPoolExecutorFactoryBean factory = new ThreadPoolExecutorFactoryBean();
factory.setCorePoolSize(50);
factory.setMaxPoolSize(200);
factory.setQueueCapacity(5000);
return factory;
}
@Bean
public ch.ralscha.extdirectspring.controller.Configuration configuration() throws Exception {
ch.ralscha.extdirectspring.controller.Configuration config = new ch.ralscha.extdirectspring.controller.Configuration();
config.setBatchedMethodsExecutionPolicy(BatchedMethodsExecutionPolicy.CONCURRENT);
config.setBatchedMethodsExecutorService(threadPoolExecutorFactoryBean().getObject());
return config;
}
請注意,啓用此功能會降低性能,在某些情況下,由於線程處理開銷。沒有做任何性能測試情況下不要啓用此功能。如果啓用此功能,客戶端只有一個方法調用類庫執行方法在請求處理線程,並且沒有線程池。在那種情況下沒有線程處理性能損失。
備註:Extjs不能批量調用表單post方法,因此對哪類方法沒有批量調用支持。
Spring Security
如果你用Spring Security和併發方法執行,你必須添加下面的代碼在某些地方,保證在程序啓動時執行。
SecurityContextHolder.setStrategyName("MODE_INHERITABLETHREADLOCAL");