2015-10-20 43 views
1

我想在我的彈簧集成配置中使用特定場景的Groovy腳本。有幾個錯誤我無法解決,或者超出了我的理解範圍。請原諒,因爲我不熟悉groovy腳本。Spring集成Groovy腳本和SpEL

我在我的庫中有spring-integration-groovy-3.0.2.RELEASE.jar

下面是我的春天一體化配置:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:int="http://www.springframework.org/schema/integration" xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:stream="http://www.springframework.org/schema/integration/stream" 
    xmlns:int-groovy="http://www.springframework.org/schema/integration/groovy" xmlns:lang="http://www.springframework.org/schema/lang" 
    xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.2.xsd 
     http://www.springframework.org/schema/integration/groovy http://www.springframework.org/schema/integration/groovy/spring-integration-groovy-3.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd 
     http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <!-- Works fine: Using service-activator and SpEL to call a java bean.method(params) --> 
    <int:chain input-channel="requestChannel" output-channel="responseChannel"> 
     <int-xml:xslt-transformer xsl-templates="BookingClassFilter_Template" result-transformer="resultToDOMSource" /> 
     <int:service-activator expression="@errorDetectionUtil.checkAndThrowExceptionOnError(#root)" /> 
    </int:chain> 

    // Note: I want to replace the above int:chain with the below. Only the below section appears in my final configuration file deployed. The above int:chain is only as an example for Q&A. 
    <!-- NOT WORKING: Using Groovy script --> 
    <int:chain id="businessLayerResponse" input-channel="requestChannel" output-channel="responseChannel"> 
     <int-xml:xslt-transformer xsl-templates="BookingClassFilter_Template" result-transformer="resultToDOMSource" /> 
     <int-groovy:script> 
      def valBool = errorDetectionUtil.hasErrors(payload) 
      if(valBool) throw new AppException(#root)  
      return #root  
     </int-groovy:script> 
    </int:chain> 
</beans> 

下面是我的Java類:

import javax.xml.transform.dom.DOMSource; 

@Component("errorDetectionUtil") 
public class ErrorDetectionUtil { 
    public boolean hasErrors(DOMSource domSource) { 
     double countDbl = (double) errorsCounter.evaluate(domSource.getNode(), XPathConstants.NUMBER); 
     return ((int) countDbl > 0) 
    } 
    public Message<?> checkAndThrowExceptionOnError(Message<?> message) throws AppException { 
     if (hasErrors((DOMSource) message.getPayload())) { 
      throw new AppException(message); 
     } 
     return message; 
    } 
} 
// AppException extends org.springframework.integration.MessagingException 

我不知道我在做什麼錯在這裏。下面是我啓動應用程序服務器時看到的異常stacktrace。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.handler.MessageHandlerChain#13': Cannot create inner bean 'businessLayerResponse$child#2.handler' of type [org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor] while setting bean property 'handlers' with key [2]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'businessLayerResponse$child#2.handler': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'componentName' of bean class [org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor]: Bean property 'componentName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:154) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1387) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1128) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) 
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586) 
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1750) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'businessLayerResponse$child#2.handler': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'componentName' of bean class [org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor]: Bean property 'componentName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1423) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1128) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271) 
    ... 30 more 
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'componentName' of bean class [org.springframework.integration.groovy.GroovyScriptExecutingMessageProcessor]: Bean property 'componentName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? 
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1042) 
    at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902) 
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75) 
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1420) 
    ... 34 more 

回答

0
  1. <groovy:script>不是組件本身。它只能反映其他EIP特定組件的行爲。

因此,您的<service-activator>也將在那裏。但是,使用<script>而不是expression

  1. #root變量是SpEL的一部分,它恰好是Message<?>。對於腳本,它被分割爲​​和headers變量。是的,你應該使用它們已經沒有#

自從Spring集成3.0以來,您的errorDetectionUtil在Groovy腳本中可用。

+0

謝謝Artem!我使用''內的''做了實現更改。是的,我擺脫了'componentName'異常。但是我需要在'AppException'中發送'Message '對象。有沒有一種方法可以在拋出'AppException'時設置'Message'對象?例如'拋出新的AppException(#root)' – Nashvi

+0

很高興聽到!如果這對你很好,接受答案是好的基調。 –

+0

我剛剛編輯了我以前的評論。你能再請參考嗎?謝謝! – Nashvi

0

按照我的Spring集成解決變化問題:

<int:chain id="businessLayerResponse" input-channel="requestChannel" output-channel="responseChannel"> 
    <int-xml:xslt-transformer xsl-templates="BookingClassFilter_Template" result-transformer="resultToDOMSource" /> 
    <int:service-activator> 
     <int-groovy:script> 
     def valBool = errorDetectionUtil.hasErrors(payload) 
     def message = org.springframework.integration.support.MessageBuilder.withPayload(payload).copyHeaders(headers).build() 
     if(java.lang.Boolean.valueOf(valBool)) { 
      throw new x.y.z.AppException(message) 
     }  
     return message 
     </int-groovy:script> 
    </int:service-activator> 
</int:chain> 

注:完全限定的Java類名是必需的腳本。

+0

???這是不好的基調,添加自己的答案,當它是基於另一個... –

+0

嗨Artem,對不起,我最初不明白你的意思是'好的語氣來接受答案'和'壞音添加自己的答案,當它基於另一個'。是否有任何選項可以讓我錯過接受評論作爲答案?我會做出必要的改變,這將成爲我今後的指導方針。 – Nashvi

+0

沒問題!這只是例行公事,但我喜歡參加這場賭博:-)。你應該跟着http://stackoverflow.com/tour –