프로그래밍/Flash/Flex

LCDS/BlazeDS services-config.xml 컴파일러 세팅 안하도록 만들어보자

드럼캡 2010. 6. 21. 10:07
LCDS나 BlazeDS는 플렉스와 서버와의 통신을 도와주는 미들웨어 입니다. 여기서 서버 설정에 대한 부분은 인터넷에 널려있으니 넘어가고, 플렉스에서의 설정에 대해서만 이야기 해 보도록 하겠습니다.
플렉스 프로젝트를 만들면 RemoteObject 등을 사용하여 통신하기 위해 아래와 같이 프로젝트 생성 위자드에서 설정을 하는 과정을 거칩니다. 

그러면 빌더는 다음과 같은 프로젝트 설정 정보들을 화면에 보여주면서 LCDS/BlazeDS 등의 서버 기술을 사용할 수 있게 도와 줍니다.

 

차례대로 설명하면, 서버 탭에 생긴 정보들은 빌더에서 사용하는 정보로써, 이 정보를 참고하여 플래시 빌더4의 서비스 생성 위자드, 컴파일, 실행 등을 매끄럽게 할 수 있습니다. 
컴파일러 탭의 Additional Compiler Arguments 항목에 –services 에 LCDS/BlazeDS의 서비스 xml 이 지정되어 있는 것을 보실 수 있습니다. 이것은 컴파일 시에 해당 서비스 xml 정보를 플래시 안에 넣기 위함이며, 컴파일러가 알아서 해 줍니다. 공동 작업 시에는 이 services 컴파일러 아규먼트가 달라서 개발자마다 이 정보를 변경해 줘야 했습니다.

여기서 고민이 생겼습니다.
개발자마다 파일은 같지만 위치가 다르다고 해서 설정을 바꾸는 수고를 매번 해야할까? 라고 말이죠. 이것으로 쏠쏠하게 세팅할 때마다 불려 다니곤 했습니다.

해결책1. RemoteObject에 endpoint 속성을 매번 넣어주기

사실 RemoteObject 클래스에는 endpoint 라는 속성이 있는데, 여기에 해당 서비스의 endpoint 를 아래와 같이 지정해 주시면 됩니다. 다만, RemoteObject 선언할 때 매번 설정해 줘야겠죠


해결책2. 직접 services-config.xml 정보를 넣어주기.

위와 같이 일일이 설정하는 것은 답이 아니라 생각해서 컴파일러 아규먼트에 촛점을 맞춰 해결책을 강구해 봤습니다. 이 아규먼트가 들어감으로 해서 어떤 일이 생기는지 분석해 보면 자연스레 해결될 것이니까요. 그래서 컴파일러 아규먼트에 -keep을 추가해서 mxml에서 생성되는 as 클래스들을 찾아 하나하나 자세히 분석해 보았습니다. 그랬더니 의외의 결과가 나왔는데, 컴파일러는 –services 아규먼트를 지정하면 부가 코드를 여럿 생성하지만 가장 중요한 부분이 지정한 xml을 읽어와 mx.messaging.config.ServerConfig 클래스의 스태틱인 xml속성에 넣어주는 것 밖에 없었습니다.

궁금하시면 컴파일러 아규먼트 –services 를 지정하셨다면 아래와 같이 해 보세요. services-config.xml 설정 정보가 쫙 펼쳐져 보일 것입니다.

trace(ServerConfig.xml.toXMLString());

결론은 간단합니다. 글을 장황하게는 썼지만 그냥 다음과 같은 간단한 클래스를 만들어 mxml코드에 넣어주기만 하면 됩니다. 초기화 시에 서비스를 다녀와야 할 일이 있다면 as 코드에 직접 설정정보를 예제와 같이 넣으시고요. 아니라면 xml를 읽어온 이후에 서버의 타이밍에 따라 다르지만 대체로 applicationComplete 이벤트 디스패치 된 이후에 세팅완료 됩니다. RemoteObject 에서 endpoint를 찾을 수 있습니다.

LcdsServiceInitializer.as
package
{
	import mx.core.IMXMLObject;
	import mx.core.mx_internal;
	import mx.messaging.config.ServerConfig;
	import mx.rpc.AsyncToken;
	import mx.rpc.Responder;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;

	use namespace mx_internal;

	/**
	 * LCDS , BlazeDS의 Services Config를 컴파일러에서 세팅하지 않고 
	 * 동적으로 세팅하게 해 주는 초기화 클래스
	 *  
	 * @author Yun Dosun
	 */
	public class LcdsServiceInitializer implements IMXMLObject
	{
		//-----------------------------------------------------------
		//
		// Constants
		// 
		//-----------------------------------------------------------
		private static const DEFAULT_XML_LOCATION:String = "config/services-config.xml";
		private static const DEFAULT_SERVICES:XML = 
				
					
						
							
						
					
				
				
					
						
							
						
					
				
				
				
				
					
						
						
							true
							4
						
					
					
						
						
						
					
					
						
						
						
					
				
			;


		/**
		 * IMXMLObject 를 구현한 클래스 (MXML에서 세팅한 속성값 적용을 위한 목적)
		 * @param document
		 * @param id
		 */
		public function initialized(document:Object, id:String):void
		{
			this.document = document;
			this.id = id;

			setROService();
		}

		/**
		 * configPath 설정파일 경로에서 잘 찾아오면 그 값으로, 
		 * 설정파일이 없으면 기본 설정정보로 셋  
		 */
		private function setROService():void
		{
			var service:HTTPService = new HTTPService();
			service.url = configPath;
			service.resultFormat = "e4x";

			var resultFunc:Function = function(event:ResultEvent):void
				{
					var xml:XML = event.result as XML;
					ServerConfig.xml = xml;
				}

			var faultFunc:Function = function(event:FaultEvent):void
				{
					ServerConfig.xml = DEFAULT_SERVICES;
				}

			var responder:Responder = new Responder(resultFunc, faultFunc);

			var token:AsyncToken = service.send();
			token.addResponder(responder);
		}

		//--------------------------------------------------------
		//
		// Variables
		// 
		//--------------------------------------------------------

		mx_internal var document:Object;
		mx_internal var id:String;

		/**
		 * services-config.xml(플렉스용) 파일의 경로
		 * @return 
		 */
		public function get configPath():String
		{
			var ret:String = _configPath;

			if (!_configPath)
			{
				ret = DEFAULT_XML_LOCATION;
			}

			return ret;
		}
		private var _configPath:String;

		/**
		 * services-config.xml(플렉스용) 파일의 경로
		 * @param value
		 */
		public function set configPath(value:String):void
		{
			if (_configPath == value)
			{
				return;
			}
			_configPath = value;
			
			setROService();
		}
		
		/**
		 * 현재 어플리케이션에 설정 되어있는 services-config 정보
		 * @return 
		 */
		public function get serverConfigXml():XML
		{
			return ServerConfig.xml;
		}
	}
}
main.mxml


	
		<![CDATA[
			import mx.rpc.CallResponder;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;

			import volcano.uxsb.platform.utils.RemoteObjectHelper;

			private var cr:CallResponder;

			protected function datagrid1_clickHandler(event:MouseEvent):void
			{
				cr.token=RemoteObjectHelper.sendRemote(new Object, "getData111", "drumcap");
				cr.addEventListener(ResultEvent.RESULT, onResultEventHandler);
			}

			private function onResultEventHandler(event:ResultEvent):void
			{
				trace("result===", event.result);
			}
		]]>
	

	
	

	


반응형