Skip to content
Ralph Schaer edited this page Aug 13, 2015 · 21 revisions

With the class ch.ralscha.extdirectspring.controller.Configuration it is possible to tweak different aspects of ExtDirectSpring.

RemotingProvider Configuration

The three properties timeout, maxRetries, bufferLimit and enableBuffer configure the RemotingProvider. Description about these properties.

<bean id="extDirectSpringConfiguration" 
      class="ch.ralscha.extdirectspring.controller.Configuration" 
      p:timeout="12000" p:maxRetries="10" p:enableBuffer="false" p:bufferLimit="3"/>

If specified api.js sends these parameters to the client as part of the remoting configuration.

Example output of a call to api-debug.js with the above configuration present in the Spring context.

Ext.app.REMOTING_API = {
  "url" : "/controller/router",
  "type" : "remoting",
  "actions" : {
    "treeProvider" : [ {
      "name" : "getTree",
      "len" : 1
    } ]
  },
  "timeout" : 12000,
  "maxRetries" : 10,
  "enableBuffer" : false
};

If not specified api.js does not include these properties in the response. RemotingProvider will then use these default values: timeout=30000, maxRetries=1 and enableBuffer=10

providerType (since 1.2.2)

The type can be globally set with the Configuration.providerType property. Ext JS will use this value to find the corresponding Provider "class" (capitalize first letter and append the word 'Provider') The default value is 'remoting' and creates a Ext.direct.RemotingProvider in Ext JS.

Here an example when somebody creates a hypothetical Ext.direct.SampleProvider and want to use that for Ext Direct calls.

<bean id="extDirectSpringConfiguration" 
      class="ch.ralscha.extdirectspring.controller.Configuration" 
      p:providerType="sample"/>

Output of api-debug.js:

Ext.app.REMOTING_API = {
  "url" : "/demo/router",
  "type" : "sample",
  "actions" : {
    ...
    } ]
  }
};

synchronizeOnSession

Defaults to false. Setting this property to true will wrap every call to a @ExtDirectMethod in a synchronized block. This is useful when the server method needs to manipulate session objects.

<bean id="extDirectSpringConfiguration" 
      class="ch.ralscha.extdirectspring.controller.Configuration" 
      p:synchronizeOnSession="true"

Instead of globally turn on this feature, every method can individually specify the synchronizeOnSession with the @ExtDirectMethod annotation.

@ExtDirectMethod(value = ExtDirectMethodType.STORE_MODIFY, synchronizeOnSession=true)
public List<User> create(List<User> newUsers) {
  //...
}

FORM_POST methods do not support this feature. FORM_POST methods support this as well if they are written in the new 1.2.1 style. Not supported if written in the old style.

streamResponse (since 1.1.0)

This property specifies that the Jackson ObjectMapper should work like in version 1.0.x and write the response directly into the http servlet response without setting the http header Content-Length (true). If set to false (default) the ObjectMapper first writes the response into an internal buffer, sets the Content-Length header and then writes the response into the http servlet response.

Instead of globally turn on this feature every method can individually configure the streamResponse property with the @ExtDirectMethod annotation.

Content-Type for api.js (since 1.2.1)

By default responses from api.js and api-debug.js requests are sent with the Content-Type "application/javascript". This value can be changed with the config option jsContentType

<bean id="extDirectSpringConfiguration" 
      class="ch.ralscha.extdirectspring.controller.Configuration" 
      p:jsContentType="application/x-javascript"/>

or with 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

If an exception happens on the server and there is no special configuration present the server sends this response back to the client. message contains the text "Server Error" and type the text "exception".

[
  {
    "method": "method4",
    "action": "remoteProviderSimple",
    "tid": 2,
    "message": "Server Error",
    "type": "exception"
  }
]

To tweak this behavior add a bean with id extDirectSpringConfiguration and type ch.ralscha.extdirectspring.controller.Configuration to the Spring context.

<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

Rules for response field message:

  1. If there is a mapping for the exception in exceptionToMessage and the value is not null send this value.
  2. If there is a mapping for the exception in exceptionToMessage and the value is null send exception.getMessage().
  3. If there is no mapping and sendExceptionMessage is true send exception.getMessage().
  4. If there is no mapping and sendExceptionMessage is false send defaultExceptionMessage.

Concurrent execution of batched method calls

If this feature is disabled (default) batched methods are executed one after another on the request handling thread. This could be a problem if first a method is called that runs a long time, because every method that follows has to wait.

To solve this problem it's possible to execute the methods in parallel by enabling this feature. To enable it set batchedMethodsExecutionPolicy to CONCURRENT and specify a thread pool with batchedMethodsExecutorService. If no thread pool is specified the library will create a fixed thread pool with 5 threads (Executors.newFixedThreadPool(5)).

Example:

	<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>

or with 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;
}

Be aware that enabling this feature can decrease performance in certain cases because of the thread handling overhead. Don't enable this feature without doing any performance measurements.

If this feature is enabled and the client sends only one method call the library executes this method on the request handling thread and not with the help of the thread pool. In this case there is no thread handling performance penalty.

Remark: Ext JS does not batch calls to form post methods. So there is no batching support for this kind of method.

Spring Security:
If you work with Spring Security and CONCURRENT method execution you have to add this line of code somewhere so that it is executed during application startup.

SecurityContextHolder.setStrategyName("MODE_INHERITABLETHREADLOCAL");
Clone this wiki locally