我正在處理一個大的Grails 1.3.7項目,我想從過濾器訪問流狀態名稱以進行日誌記錄。我一直在使用谷歌搜索,我能找到的最接近的答案是:Grails WebFlow State Name,但它只能在流程內部工作。從過濾器訪問流狀態名稱
有什麼方法可以從流程(過濾器)外部獲取當前會話中正在執行的流程的狀態名稱?
由於提前,
吉列爾莫
我正在處理一個大的Grails 1.3.7項目,我想從過濾器訪問流狀態名稱以進行日誌記錄。我一直在使用谷歌搜索,我能找到的最接近的答案是:Grails WebFlow State Name,但它只能在流程內部工作。從過濾器訪問流狀態名稱
有什麼方法可以從流程(過濾器)外部獲取當前會話中正在執行的流程的狀態名稱?
由於提前,
吉列爾莫
很多使用Google和調試後,我設法生產出下面的代碼。它適用於一個簡單的應用程序。當我從假期回來時,我會將它與主應用程序集成,然後我會更新此問題。
package org.glalejos
import org.springframework.context.ApplicationContext
import org.springframework.webflow.context.ExternalContext
import org.springframework.webflow.context.ExternalContextHolder
import org.springframework.webflow.context.servlet.ServletExternalContext
import org.springframework.webflow.execution.FlowExecution
import org.springframework.webflow.execution.FlowExecutionKey
import org.springframework.webflow.execution.repository.FlowExecutionRepository
class LoggingFilters {
def grailsApplication
String getFlowStateName(def grailsApplication, def servletContext, def request, def response) {
String stateName
if (grailsApplication && servletContext && request && request.queryString && response) {
try {
String strKey = null
String[] keys = request.queryString.split("&")
keys.each{ if (it.startsWith("execution=")) strKey = it.substring(10)}
if (strKey != null) {
ApplicationContext ctx = grailsApplication.mainContext
FlowExecutionRepository fer = ctx.getBean("flowExecutionRepository")
FlowExecutionKey fek = fer.parseFlowExecutionKey(strKey)
ExternalContext previousContext = ExternalContextHolder.getExternalContext()
try {
// You have to set an external context before invoking "fer.getFlowExecution()" or it'll throw a NPE
ExternalContextHolder.setExternalContext(new ServletExternalContext(servletContext, request, response));
FlowExecution fe = fer.getFlowExecution(fek)
stateName = fe.getActiveSession().getState().getId()
} finally {
ExternalContextHolder.setExternalContext(previousContext);
}
} else {
stateName = null
}
} catch(Exception e) {
stateName = null
}
} else {
stateName = null
}
return stateName
}
def filters = {
logData(controller:"*", action:"*") {
before = {
println("Incoming request. Current flow state name is: ${getFlowStateName(grailsApplication, servletContext, request, response)}")
}
after = {
println("Dispatched request. Current flow state name is: ${getFlowStateName(grailsApplication, servletContext, request, response)}")
}
}
}
}
EDIT:上面的代碼行,以確定在給定時間點的電流流動狀態的名稱,但它不會更新日誌框架的映射診斷上下文作爲流執行演變。爲此,有必要實施org.springframework.webflow.execution.FlowExecutionListener
和conf/spring/resources.groovy
註冊它:
beans = {
myLoggingFlowExecutionListener(org.example.MyLoggingFlowExecutionListener)
}
您必須先註冊這個監聽器bean和hibernateConversationListener
豆在executionListenerLoader
豆,但是,出於某種原因,春季DSL不在這種情況下工作(見下面的EDIT2)。因此,這裏是resources.xml
,你可以在同一個文件夾中放置的resources.groovy
爲了正確聲明你的資源:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="executionListenerLoader" class="org.springframework.webflow.execution.factory.StaticFlowExecutionListenerLoader">
<constructor-arg>
<list>
<ref bean="hibernateConversationListener" />
<ref bean="myLoggingFlowExecutionListener" />
</list>
</constructor-arg>
</bean>
</beans>
每個FlowExecutionListener
方法受到了很多的,可以用來進行日誌記錄上下文信息(我ommiting爲了清晰起見,這個類的實現)。
EDIT2:失敗流生命週期中的操作域對象時hibernateConversationListener
豆添加到executionListenerLoader
導致休眠異常。但是,Spring DSL在這種情況下不起作用,所以我不得不使用XML格式聲明所需的bean。見http://grails.1312388.n4.nabble.com/Registering-custom-flow-execution-listener-td2279764.html。我已經將上面的代碼更新爲最終的工作版本。
我發現了一些與此問題相關的鏈接:[從Spring Web Flow外部訪問流執行](http://www.ervacon.com/products/swf/tips/tip1.html)和[ webflow - 列出所有活動流程](http://grails.1312388.n4.nabble.com/webflow-list-all-active-flows-td1376853.html)。我需要從FlowExecutionRepository中獲得'FlowExecution'(我想我可以通過'session.webflowConversationContainer'中的流鍵獲得它),但是我無法弄清楚如何在Grails中獲取任何控制器過濾。 – 2013-03-08 10:40:27