달력

4

« 2024/4 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
2012. 11. 28. 09:57

Gallileo에서 Flex Builder 사용하기 Enjoy/FLEX2012. 11. 28. 09:57



출처 : http://blog.naver.com/zestun/60117466702


Gallileo에서 Flex Builder 사용하기


1. 우선 Ganymede를 설치하고 플렉스 빌더를 설치한다. 

(Ganymede 이하 버젼이 아니면 플렉스 빌더가 깔릴때 오류를 발생시킨다. 다 깔고나면 가니메데는 지워도 상관없음.)


 

2. 갈릴레오를 깔고 갈릴레오가 설치된 폴더 안에 links 폴더를 없으면 만들어주고 다음의 파일을 넣어준다.

내용은 단순한데 그냥 path=c:~~ 플렉스 빌더 플러그인 폴더 위치이다.


3. C:\Program Files\Adobe\Flex Builder 3\plugins\com.adobe.flexbuilder.project_3.0.214193로 찾아가서 zornproject.jar 파일을 첨부한 파일로 교체해준다.

 
 
요 부분이 핵심인데, 실제 ProblemManager라는 클래스가 말썽인 모양이다. 

그것만 이 제임스 와드란 친구의 클래스로 교체해주면 별 문제없이 빌드도 잘되고 실행도 잘된다는 결론.


결국 이렇게 해서 해결이 되었나 했는데 한가지 문제가 더 발생하였다.

이클립스에서 빌더가 Flex SDK를 못 찾는 것. (뭐 이정도야 문제라고 할수도 없지만서도..)

Window-Preferences-Flex-Installed Flex Sdks 항목에서 Add 를 눌러서 C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0 (기본설치시...) 를 지정해주면 이제 갈릴레오에서도 플렉스를 개발할 수가 있게 되었다.


:
Posted by 라면스프

출처 : http://active.tutsplus.com/tutorials/flex/using-as3xls-with-the-flex-framework-excel-import/






This tutorial will cover implementation of the AS3XLS ActionScript 3.0 library for the Flex framework. We will demonstrate loading an Excel .xls file into Flash and parsing the data into a Flex datagrid. 

 
:
Posted by 라면스프
2012. 3. 2. 10:33

[Flex] file uploading with return data Enjoy/FLEX2012. 3. 2. 10:33

출처 :  http://dgrigg.com/blog/2007/08/02/Flex-and-Flash-file-uploading-with-return-data/ 

The addition of the FileReference class in AS2 made file uploading significantly easier in Actionscript. However, one issue that remained problematic was the ability to get detailed information back from the server once the upload was complete. The best you could do was to get a ’200′ response saying the file upload had completed, but there was no easy way to return additional data from the server with respect to the uploaded process …. until now.

Adobe has finally added the missing piece to accomplish a nice tight uploading process, theUPLOAD_COMPLETE_DATA event (Flash Player 9.0.28.0). This event fires after the COMPLETE event and contains an important piece of information. The data property of the DataEvent contains the raw data returned from the server after a successful file upload. Finally, a way to return from the server information about the file and/or process. This is especially useful if during the upload process you need to do additional things like create a database record and then return the new database id, or possibly put the file in a different path based on the user, and return the path where the file exists back to the client.

Here’s a quick sample of implementing the new event in Flex and also a Coldfusion and PHP script to upload a file and then output and return data back to the client in a clean consistent fashion.

The Flex code. As you can see, this is a very simple example, you select a file and when the upload has completed the results from the server are output into a text area.

<?xml version="1.0" encoding="utf-8"?>
<!--
Derrick Grigg
derrick@dgrigg.com
http://www.dgrigg.com
created on August 2, 2007

A simple file upload process with data returned from the server
using the UPLOAD_COMPLETE_DATA event.
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
public var file:FileReference;

public function selectFile():void
{
file = new FileReference();
file.addEventListener(Event.SELECT, fileSelected);
file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadDataComplete);
file.addEventListener(Event.COMPLETE, uploadComplete);
file.addEventListener(IOErrorEvent.IO_ERROR, handleError);
file.browse();
}

public function handleError(event:IOErrorEvent):void
{
status_txt.text = 'ERROR: ' + event.text + ' ';
}
public function fileSelected(event:Event):void
{
file = FileReference(event.target);
file_txt.text = file.name;
status_txt.text = 'upload file: '+ file.name + ' ';

var request:URLRequest = new URLRequest();
request.url = "uploader.cfm";
file.upload(request);
}

public function uploadDataComplete(event:DataEvent):void
{
var result:XML = new XML(event.data);
status_txt.text += 'Upload Data Complete '
status_txt.text += 'RESULT: ' + result.toString() + ' '
status_txt.text += 'STATUS: ' + result.status + ' ';
status_txt.text += 'MESSAGE: '+ result.message;
}

public function uploadComplete(event:Event):void
{
status_txt.text += 'Upload complete ';

}
]]>
</mx:Script>
<mx:VBox>
<mx:TextInput id="file_txt"/>
<mx:Button id="select_btn" label="select" click="selectFile();"/>
<mx:TextArea id="status_txt" width="400" height="200"/>
</mx:VBox>
</mx:Application>

 

The Coldfusion and PHP scripts upload a file and then output a simple XML string stating if the upload worked. You could easily modify this to return back any additional data you needed. The scripts are very simplified for demonstration purposes, you would definitely want to make them more robust in a production environment.

The Coldfusion upload script.

<cfprocessingdirective  suppresswhitespace="true">
<cftry>
<cffile action="upload" fileField="filedata" destination="c:wampwww estflex" nameconflict="overwrite">
<cfxml variable="status"><result><status>OK</status><message><cfoutput>#filename#</cfoutput> uploaded successfully.</message></result></cfxml>
<cfcatch>
<cfxml variable="status"><result><status>Error</status><message><cfoutput>#cfcatch.Message#</cfoutput></message></result></cfxml>
</cfcatch>
</cftry>
<cfoutput>#status#</cfoutput>
</cfprocessingdirective>

 

The PHP upload script

<?php

$upload_dir = $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']) . '/';
$upload_url = "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']) . '/';
$message ="";

$temp_name = $_FILES['Filedata']['tmp_name'];
$file_name = $_FILES['Filedata']['name'];
$file_name = str_replace("","",$file_name);
$file_name = str_replace("'","",$file_name);
$file_path = $upload_dir.$file_name;

$result = move_uploaded_file($temp_name, $file_path);
if ($result)
{
$message = "<result><status>OK</status><message>$file_name uploaded successfully.</message></result>";
}
else
{
$message = "<result><status>Error</status><message>Somthing is wrong with uploading a file.</message></result>";
}

echo $message;
?>

 

You can download the sample files here.

I’m glad to see Adobe finally added this, it makes life so much easier.


 

:
Posted by 라면스프
2011. 11. 24. 10:30

Modifying data in a database Enjoy/FLEX2011. 11. 24. 10:30

출처 : http://www.adobe.com/devnet/flex/trial/examples/10_complex_app.html?trackingid=IJYYH

Modifying data in a database

 

Explanation

This sample project shows you how to connect a Flex application to server-side data to retrieve, update, add, and delete records in a database. To look at the code, right-click on the SWF in the browser and select View Source or download the sample files and view the source files in a text editor or follow the instructions to import the Flash Builder FXP.

Communicating with the server

Flex applications cannot connect directly to a remote database. Instead, they communicate with back-end servers using either direct socket connections or more commonly, through HTTP. HTTP requests are made to a remote data service written in your favorite web language (PHP, ColdFusion, Java, or any other server-side web technology) using one of the Flex framework's remote procedure call APIs: HTTPService, WebService, or RemoteObject. All three wrap Flash Player's HTTP connectivity, which in turn, uses the browser's HTTP library.

With HTTPService, you make HTTP requests to JSP, PHP, CFM, or XML files; RESTful web services; or other server files that returns text over HTTP. You specify the endpoint URL, listener functions (the callback functions to be invoked when the HTTPService request returns a successful or unsuccessful response), and a data type for the returned data (what type of data structure it should be translated into once received in the Flex application). You can specify the data to be handled as raw text and assigned to a String variable or converted to XML, E4X, or plain old ActionScript objects. If you get back JSON, you can use the Adobe Flex corelib package of classes to deserialize the JSON objects into ActionScript objects. To make calls to SOAP based web services, you can use the HTTPService API or the more specialized WebService API, which automatically handles the serialization and deserialization of SOAP formatted text to ActionScript data types and vice versa.

The third option for making remote procedure calls is to use the RemoteObject API. It makes a Flash Remoting request to a method of a server-side class (which can be a ColdFusion component) that returns binary Action Message Format (AMF) over HTTP. You specify an endpoint (which in this case is a server-side Flash Remoting class to handle the remoting request), a destination (the server-side class that has the methods you want to call), and listener functions to handle the responses. The data translation between the client and server-side data types is handled automatically.

This sample project uses Flash Remoting whose binary data transfer format enables applications to load data up to 10 times faster than with the more verbose, text-based formats such as XML, JSON, or SOAP. To see a comparison of AMF to other text-based serialization technologies, see James Ward's Census RIA Benchmark application.

Using Flash Remoting

Flash Remoting is a combination of client and server-side functionality that together provides a call-and-response model for accessing server-side objects from Flash Platform applications as if they were local objects. It provides transparent data transfer between ActionScript and server-side data types, handling the serialization into binary Action Message Format (AMF), deserialization, and data marshaling between the client and the server.

Flash Remoting uses client-side functionality built in to Flash Player and server-side functionality that must be installed on the application server. Flash Remoting is built in to some servers (like ColdFusion and Zend) but must be installed on other servers (as BlazeDS or LiveCycle Data Services on Java EE servers, WebORB or FluorineFX on .NET servers, the Zend Framework or amfphp on PHP servers, and more).

Setting up the server

Let's start by taking a look at the server-side files.

ColdFusion

Flash Remoting is built in ColdFusion servers and little setup is necessary. You need to make sure that Flash Remoting is enabled in the ColdFusion Administrator (Data & Services > Flex Integration > Enable Flash Remoting support) and then in your ColdFusion components, specify an access of remote for the functions you want to access from Flex applications. This sample project calls methods of EmployeeService.cfc located in/wwwroot/TestDrive/services/.

<cfcomponent output="false"> <cffunction name="getEmployees" output="false" access="remote" returntype="Query"> <cfset var qGetEmployees=""> <cfquery name="qGetEmployees" datasource="testdrive_db"> SELECT *FROM employees </cfquery> <cfreturn qGetEmployees> </cffunction> <!-- other functions --> </cfcomponent>

The files for configuring Flash Remoting files are located in /ColdFusion/wwwroot/WEB-INF/flex/. The main configuration file, services-config.xml, defines channels to specify how communication should take place between the client and server, including the protocol to use (for example, AMF over HTTP or HTTPS), the endpoints (the classes to handle and route the calls on the server), and other information for finetuning the calls (like specifying if query columns names and structure keys should be translated into ActionScript with lowercase or uppercase property names). You set the case by modifying the <property-case> tag as shown below.

<property-case> <!-- cfc property names --> <force-cfc-lowercase>true</force-cfc-lowercase> <!-- Query column names --> <force-query-lowercase>true</force-query-lowercase> <!-- struct keys --> <force-struct-lowercase>true</force-struct-lowercase> </property-case>

The services-config.xml file also includes a reference to the remoting-config.xml file, which is where you can define destinations, or mappings to specific ColdFusion components you want to call from Flex. (After changes to the configuration files, you must restart the server.) By default, remoting-config.xml contains one default destination (with an id of ColdFusion) that has its source property set to a wildcard so it can be used for any Flash Remoting calls to any ColdFusion components.

<destination id="ColdFusion"> <channels> <channel ref="my-cfamf"/> </channels> <properties> <source>*</source> </properties> </destination>

To make a call from Flex with RemoteObject, you specify a destination of ColdFusion and a source of TestDrive.services.employeeService, the fully qualified name of the ColdFusion component that you want to call from the webroot.

You can also add named destinations to remoting-config. For example, you could create a destination called employeeService that points to that same CFC:

<destination id="employeeService"> <properties> <source>TestDrive.services.EmployeeService</source> </properties> </destination>

... and then when making calls from Flex, you would specify a destination of employeeService (instead of ColFusion) and no source (because it is now included in the destination)

Java

To use Flash Remoting with Java, you need to install an implementation of Flash Remoting on the server. Adobe provides the open-source BlazeDS or the commercial LiveCycle Data Services. This sample uses BlazeDS and the BlazeDS files (JAR files and configuration files) are included in the Test Drive WAR file along with the Java classes to call from the Flex application. For more details, read the Flex and Java technology overview and the architecture overview.

This sample project calls methods of EmployeeService located in the testdrive webapp: /testdrive/WEB-INF/classes/services/. (The source files are also included for reference in /testdrive/webapps/WEB-INF/src/services/.) It uses a typical assembler design pattern and manipulates instances of an Employee data transfer object, which we will map to a corresponding client-side ActionScript object for passing data back and forth between the client and server. To be called from Flex, the Java class must have a no argument constructor.

package services; import java.util.List; import services.EmployeeDAO; import services.Employee; public class EmployeeService { public EmployeeService() { } public List getEmployees() { EmployeeDAO dao = new EmployeeDAO(); return dao.getEmployees(); } //more methods... }

The files for configuring Flash Remoting files are located in /testdrive/WEB-INF/flex/. The main configuration file, services-config.xml, defines channels to specify how communication should take place between the client and server, including the protocol to use (for example, AMF over HTTP or HTTPS), the endpoints (the classes to handle and route the calls on the server), and other information for finetuning the calls.

The services-config.xml file also includes a reference to the remoting-config.xml file, which is where you define destinations, or mappings to the specific Java classes you want to call from Flex. Here is the destination used for the sample projects called employeeService:

<destination id="employeeService"> <properties> <source>services.EmployeeService</source> <scope>application</scope> </properties> </destination>

To make a call from Flex with RemoteObject, you specify a destination of employeeService.

PHP

To use Flash Remoting with PHP, you need to install an implementation of Flash Remoting on the server. This sample uses the Zend Framework. You must install the framework and then create a PHP file (in this sample, gateway.php) to use the framework and handle all the requests from Flex, including passing them to the appropriate PHP classes, handling all the data translation and serialization, and more. If you use the Create Data Service wizard in Flash Builder to create a data service to connect to a PHP class, the Zend framework is automatically installed on your server (if it is not already) and gateway.php and an amf-config.ini file created and placed on the server along with the SWF. Although this sample does not use service files created with the Flash Builder Data Service wizard, it does use the gateway.php and amf-config.ini files it creates. (The Flex Test Drive has a tutorial for creating the service with the wizard.)

This sample project calls methods of EmployeeService located in /htdocs/TestDrive/services/.

<?php class EmployeeService { public function getEmployees() { $stmt = mysqli_prepare($this->connection,"SELECT *FROM employees"); //more code return $rows; } //more methods }

You specify directories that contain PHP classes to call from Flex in the amf-config.ini file.

;more code amf.directories[]=TestDrive/servicesc

To make a call from Flex with RemoteObject, you specify a destination of zend, an endpoint of gateway.php, and a source of EmployeeService, the name of the PHP class to call.

Creating a RemoteObject

Now that we've looked at the server-side files, let's see how to call them from Flex. The first step is to define an instance of the RemoteObject class either in the Script block with ActionScript or in the Declarations tag with MXML; they are equivalent. The Declaration tag provides a way to define non-visual objects with MXML. (The green color of the tag indicates it is a compiler tag associated with compiler instructions and not an instance of a class.)

Depending upon what server you are using, the RemoteObject will have slightly different properties specified (the destination and possibly the source and/or endpoint). For ColdFusion and Java, the endpoint is set dynamically using the services-config.xml file and for ColdFusion, a source needs to be set if the default ColdFusion destination is used. After substituting the values from the constants set in the Script block of the sample code, the RemoteObject tag will look like one of these.

<fx:Declarations> <!-- ColdFusion--> <s:RemoteObject id="employeeService " destination="ColdFusion" source="TestDrive.services.EmployeeService" showBusyCursor="true" fault="employeeService_faultHandler(event)"/> <!-- PHP --> <s:RemoteObject id="employeeService " destination="zend" source="EmployeeService" endpoint="gateway.php" showBusyCursor="true" fault="employeeService_faultHandler(event)"/> <!--Java--> <s:RemoteObject id="employeeService " destination="employeeService" showBusyCursor="true" fault="employeeService_faultHandler(event)"/> </fx:Declarations>

You call a method of the server-side class by calling that method on this client-side object, for example,employeesService.getEmployees().

Remote procedure calls are asynchronous so you also need to specify listener functions, the callback functions to be invoked when a request returns a successful or unsuccessful response. For Flex remote procedure calls, you register to listen for result and fault events. Because a data service often has multiple methods that can be called and they can be called at different times in the application, the callback functions are usually specified on a per call basis instead of on the service object.

In this sample, a fault handler is specified for the RemoteObject but no result handler. This fault handler will be used for all service calls that do not have their own fault handler specified. The handler uses the Flex Alert component (which has a static show() method), to display a popup with the fault message. The FaultEvent object has a property called fault that is equal to an instance of the Fault class that has properties faultString andfaultDetail.

import mx.controls.Alert; import mx.rpc.events.FaultEvent; protected function employeeService_faultHandler(event:FaultEvent):void { Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail,"Error"); }

Note: Instead of using the RemoteObject class directly as in this sample, you can also use Flash Builder's Create Data Service wizard to create a data service and then call methods of a generated service class that wraps the RemoteObject class. Flash Builder introspects the server-side class file and creates a corresponding client-side class with the same operations. (For this introspection and code generation to occur, RDS must be enabled on your server.) If the server returns strongly typed objects (which is the case for the Java classes in this sample), ActionScript classes are created that map to the corresponding objects manipulated by the methods of the class. If the server returns general objects (which is the case for the PHP class and CFC in this sample), you can configure the data service to create typed ActionScript objects whose properties match those for the general objects returned from the server. Of course, you can also write your PHP classes and CFC methods to return strongly typed objects instead of general objects as well. After creation, the data service, its methods, its argument types, and its return types are displayed in the Data/Services view and methods can be dragged and dropped on components in the application to add them. The Flex Test Drive tutorials create and use data services created with the Flash Builder Data Service wizard.

Retrieving data

Next, let's look at the calls to the server. We want to retrieve the employee and department data on application startup. To do this, you usually specify an event handler for the Application object's initialize orcreationComplete events. Every Flex component has a series of events that are broadcast as the component is created, from the time it is instantiated until the time it is drawn on the Flash Player drawing surface. Theinitialize event is broadcast after the component has been created and all of its properties are set and those of its subobjects. creationComplete is broadcast later after the component and all its subobjects also have sizes and positions. Use creationComplete if any of the code references any sizes or positions.

In the sample code, a handler is specified for the Application's initialize event:

<s:Application initialize="init()" ...>

... and inside the handler, the getEmployees() and getDepartments() methods of the service object are called.

protected function init():void { getEmployeesResult.token = employeeService.getEmployees(); getDepartmentsResult.token = employeeService.getDepartments(); }

When this code is executed, Flash Player makes a call to the server. This happens asynchronously in the background; the user can still interact with the application. 
When you make a service call, you need to specify what Flash Player should do when it gets a result or error back from the server. A fault handler was specified for the data service itself and will be used to display errors returned from calls to any of its operations in a popup box.

Using call responders to specify callbacks

To handle successful results, CallResponder objects are declared for each of the calls.

<fx:Declarations> <s:CallResponder id="getEmployeesResult" .../> <s:CallResponder id="getDepartmentsResult"/> (...) </fx:Declarations>

These need to be associated with the corresponding service call. When a service call is initiated, an instance of the AsyncToken class is created. To associate the CallResponder object with the service call, you set the CallResponder'stoken property equal to the AsyncToken generated at the time the service call is made. When data is returned from the server, it is handled by that CallResponder.

getEmployeesResult.token=employeeService.getEmployees();

A CallResponder object has a lastResult property that automatically gets populated with the data when it is returned to Flash Player from the server. It can be easily used by binding a control to it. In the application, thedataProvider property of a DataGrid component is bound to the lastResult property of thegetDepartmentsResult CallResponder object. Whenever the value of getDepartmentsResult.lastResultchanges, the DataGrid's dataProvider property is updated and the DataGrid repopulates itself with the new data.

<s:DataGrid id="deptDg" dataProvider="{getDepartmentsResult.lastResult}" ...> <s:columns> <s:ArrayList> <s:GridColumn headerText="Name" dataField="name" /> <s:GridColumn headerText="ID" dataField="id" width="40"/> <s:GridColumn headerText="Manager" dataField="manager" width="170"/> <s:GridColumn dataField="budget" headerText="Budget" width="155"/> <s:GridColumn dataField="actualexpenses" headerText="Expenses" width="155"/> </s:ArrayList> </s:columns> </s:DataGrid>

By default, one column is created for each of the fields in the objects used to populate the DataGrid. You control what properties to display and in what order by setting the columns property equal to an ArrayList of GridColumn objects. For each DataGridColumn object, you specify what property it should display (dataField), the title for the column (headerText), its size, and more.

Using the CallResponder lastResult property works fine if you just want to bind the results to a component as shown here, but many times you will want to execute some code when the results are returned. To do this, you register to listen for the result or fault events for the CallResponder. In the sample, a result handler is registered for the getEmployeesResult CallResponder.

<s:CallResponder id="getEmployeesResult" result="getEmployeesResult_resultHandler(event)"/>

... and the getEmployeesResult_resultHandler() defined.

Handling return data

This application manipulates employee data. When you bind controls to collections of objects (as we just saw in thedeptDg DataGrid and will see next for the empDg DataGrid), the data should be strored in a Flex collection class. For example, instead of storing the employee data objects in an Array (a top level data type in Flash Player), you should use an ArrayList or ArrayCollection. The ArrayList and ArrayCollection classes basically wraps an Array so that when any value in any position of the array changes, an event is broadcast and any controls bound to it will be updated. If the objects were stored in an Array, even if it was made bindable, events would be broadcast only when the value of the entire array changed, for example, if it went from null to a value or was set to an entirely different value. Unlike an ArrayList, an ArrayCollection can also be sorted, filtered, and traversed with a cursor.

In this application, an employees ArrayCollection is defined in the Declarations block:

<s:ArrayCollection id="employees"/>

... which is equivalent to setting a public, bindable variable in ActionScript:

[Bindable]public var employees:ArrayCollection;

The dataProvider property of the empDg DataGrid is bound to this collection.

<mx:DataGrid id="empDg" dataProvider="{employees}" ...>

Inside this collection, we want to store strongly typed, bindable Employee objects, not general Objects. This way we will get code-hinting when manipulating these objects and compiler and runtime property and property type checking. These objects will also be bindable, so if any of their properties change, an event will be broadcast and any objects bound to it updated.

If you look in the valueObjects folder, you will see an Employee class definition.

package valueObjects { [Bindable] //if server was returning typed objects like for java, ///[RemoteClass(alias="services.Employee")] public class Employee { public var id:uint; public var firstname:String; public var lastname:String; //other property declarations public function Employee() { } } }

If the server-side class returns strongly typed objects (as does the Java class in this sample), you need to include a RemoteClass metadata tag that maps this ActionScript class to the corresponding class on the server.

[RemoteClass(alias="services.Employee")]

This is the crucial information needed by Flash Player so it can map the server-side objects to the correct client-side objects automatically. In this case, the getEmployeeResult_resultHandler() only needs to populate the employees ArrayCollection with the data returned from the server because the data has already been translated to an ArrayCollection of Employee objects.

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { employees=event.result as ArrayCollection; }

The data returned from a server-side method call is stored in the result property of the event object that is passed to the result event handler. The employees variable is data typed as an ArrayCollection but the resultproperty of the event object is data typed as a general Object, so you have to cast event.result to an ArrayCollection to assign it to employees.

To see what types of ActionScript objects the returned server-side data objects are converted to, place a breakpoint inside the result handler and debug the application. You can also look at tables of the data type mappings forActionScript and JavaActionScript and PHP, or ActionScript and ColdFusion.

If Employee objects are not returned from the server (as is the case for the PHP class and CFC in this sample),getEmployeesResult_resultHandler() needs to create this collection of Employee objects manually. For PHP, you get an Array of Objects back from the server and for ColdFusion, an ArrayCollection of Objects. To convert the Objects into Employee objects, you need to loop through the collection, creating a new Employee instance for each item and populating its properties with the corresponding properties of the general Object, and then adding that Employee object to the collection. You could explicitly write each property assignment:

emp.id=data[i].id;
emp.firstname=data[i].firstname;
emp.lastname=data[i].lastname;
//do the same for all properties

... but this code instead uses the describeType() method (in the flash.utils package). describeType() returns an XML object that contains an accessor element (which has nameaccesstype, and declaredBy attributes) for each of object's properties. This is the ActionScript implementation of reflection.

For ColdFusion, the getEmployeesResult_resultHandler() appears as shown here.

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { var data:ArrayCollection=event.result as ArrayCollection; for(var i:uint=0; i<data.length; i++) { var emp:Employee=new Employee(); for each(var field:XML in describeType(emp)..accessor){ emp[field.@name]=data[i][field.@name]; } employees.addItem(emp); } }

The ArrayColletion addItem() method is used to add the new employee to the employees ArrayCollection.

The handler is slightly different for PHP because you get an Array instead of an ArrayCollection back from the server.

protected function getEmployeesResult_resultHandler(event:ResultEvent):void { var data:ArrayCollection=new ArrayCollection(event.result as Array); for(var i:uint=0; i<data.length; i++) { var emp:Employee=new Employee(); for each(var field:XML in describeType(emp)..accessor){ emp[field.@name]=data[i][field.@name]; } employees.addItem(emp); } }

Displaying details

When the user selects an employee in the DataGrid, that employee's details are displayed beneath it. In theDeclarations block, you'll see an employee variable defined of type Employee (that is bindable by default).

<valueObjects:Employee id="employee"/>

Beneath the Declarations block, you'll see a Binding tag:

<fx:Binding source="empDg.selectedItem as Employee" destination="employee"/>

This is just another way to create a binding between two variables without using {} in an MXML tag. Whenever theselectedItem property of empDg changes, the employee variable is updated.

As well, there is code to listen for the DataGrid's selectionChange event:

<s:DataGrid id="empDg" dataProvider="{employees}" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees" selectionChange="empDg_selectionChangeHandler(event)" ...>

Inside the selectionChange handler, you switch to the application's EmployeeDetails state:

protected function empDg_selectionChangeHandler(event:GridSelectionEvent):void{ currentState="EmployeeDetails"; }

... that includes a Form container that has one Label control for each of the employee object's properties.

<s:Form includeIn="EmployeeDetails" x="63" y="325"> <s:FormItem label="Last Name"> <s:Label id="lastnameLabel" text="{employee.lastname}"/> </s:FormItem> <s:FormItem label="First Name"> <s:Label id="firstnameLabel" text="{employee.firstname}"/> </s:FormItem> (...) </mx:Form>

The employee details will be displayed in the Label controls in the Form. A Flex Form container is purely a layout container, helping to easily line up multiple controls that have labels in front of them; it has no other purpose like in an HTML form. When you send data to the server which we will look at next, you specify explicity what objects to send; they have nothing to do with Form components.

Now that we have seen how to retrieve and display data from the server, let's look at how to modify this data on the server, updating, adding, and deleting records in the database. You may want to go look at your application server's class file (or CFC) now to familiarize yourself with the methods it contains before looking at the code to call these methods. If you installed the files, you can look at the source code on your server. Otherwise, you can right-click the SWF in the browser, select View Source, and browse to the appropriate PHP class, Java class, or CFC.

Using the DataGrid to update data

One way to let users update the data is to make the DataGrid editable and then to send the changes to the server. You make the DataGrid editable by setting its editable property to true and then registering to listen for itsgridItemEditorSessionSave event which is broadcast when the user makes changes to a cell value.

<s:DataGrid id="empDg" dataProvider="{employees}" editable="true" gridItemEditorSessionSave="empDg_gridItemEditorSessionSaveHandler(event)" ...>

Inside the handler, you need to send the modified Employee instance to the server: call the updateEmployee()method and pass to it the selected item in the DataGrid.

employeeService.updateEmployee(employee);

For ColdFusion, you need to modify this slightly. When you pass an object to a Flash Remoting request, it is treated as a group of named arguments and passed to the CFC method as individual arguments, not as a single object argument. To actually pass a single object as an argument, you must create an Object instance with the name of the argument expected by the CFC, in this case an argument called item, and pass that to the server-side method. The {} here are are an ActonScript short hand notation for creating an Object; multiple name/value pairs would be separated by commas.

employeeService.updateEmployee({item:employee});

In this case, you're not going to do anything after the data is successfully updated so you don't need to specify a CallResponder to handle the results.

In this application, updates are sent to the server every time the user changes data in one DataGrid cell. If a lot of changes are going to be made, you may want to wait and submit all changes to the server at once.

Using a form to update data

Only some of the employee data is displayed in the DataGrid, so you may also want to provide a form for the user to modify all of the employee data.
When an employee is selected and the EmployeeDetails state displayed, an update button is enabled.

<s:Button id="updateBtn" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate" label="Update" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" click="updateBtn_clickHandler(event)" .../>

When the user clicks this button, the application switches to its EmployeeUpdate state:

protected function updateBtn_clickHandler(event:MouseEvent):void{ currentState="EmployeeUpdate"; }

... that has a Form containing one TextInput control for each of the employee properties that can be updated.

<s:Form includeIn="EmployeeAdd,EmployeeUpdate" defaultButton="{button}"...> <s:FormItem label="Last Name"> <s:TextInput id="lastnameTextInput" text="{employee.lastname}"/> </s:FormItem> <s:FormItem label="First Name"> <s:TextInput id="firstnameTextInput" text="{employee.firstname}"/> </s:FormItem> <!-- more FormItem controls --> <s:FormItem> <s:Button id="button" label="Add" click="button_clickHandler(event)" label.EmployeeUpdate="Update"/> </s:FormItem> </s:Form>

When the user clicks this button in the Form container, the employee object is updated with the values the user entered in the input controls and then passed to the data service's updateEmployee() method.

protected function button_clickHandler(event:MouseEvent):void { employee.lastname = lastnameTextInput.text; employee.firstname = firstnameTextInput.text; employee.title = titleTextInput.text; //code to set the rest of the properties if(employee.id==0){ //for Java and PHP createEmployeeResult.token = employeeService.createEmployee(employee); //for CF, createEmployeeResult.token = employeeService.createEmployee({item:employee}); } else{ //for Java and PHP updateEmployeeResult.token = employeeService.updateEmployee(employee); //for CF, updateEmployeeResult.token = employeeService.updateEmployee({item:employee}); } }

Similar functionionality will be used to add a new employee next, so this function has been written to handle both cases. If an existing employee is being updated, employee.id will be non-zero, so the server-sideupdateEmployee() method is called. Otherwise, the createEmployee() method is called. As before, the code for ColdFusion is slightly different to pass an object to a server-side method.

In this case, we do want to do something after the data has successfully been sent to the server, so a new CallResponder is defined with a result handler:

<s:CallResponder id="updateEmployeeResult" result="updateEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.

updateEmployeeResult.token=employeeService.updateEmployee(employee);

In the result handler, the application switches to its EmployeeDetails state and shows the details for the modified employee.

protected function updateEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; }

Using the form to add data

Similar code is used to add a new employee to the database. When an employee is selected, an add button is enabled.

<s:Button id="addBtn" label="Add" click="addBtn_clickHandler(event)" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" .../>

When the user clicks this button, the application switches to its EmployeeAdd state, which shows the same form as used to update an employee, but now the submit button is labeled Add instead of Update.

protected function addBtn_clickHandler(event:MouseEvent):void { currentState="EmployeeAdd"; employee=new Employee(); }

Using the form to add data

Similar code is used to add a new employee to the database. When an employee is selected, an add button is enabled.

<s:Button id="addBtn" label="Add" click="addBtn_clickHandler(event)" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate,Employees" enabled.EmployeeAdd="false" enabled.EmployeeUpdate="false" .../>

When the user clicks this button, the application switches to its EmployeeAdd state, which shows the same form as used to update an employee, but now the submit button is labeled Add instead of Update.

protected function addBtn_clickHandler(event:MouseEvent):void { currentState="EmployeeAdd"; employee=new Employee(); }

The employee object is also set equal to a new Employee instance (employee could currently contain the employee selected in the DataGrid) so the input controls in the Form container that are bound to it will all be set to the Employee class's default values.

The same handler is called when the user clicks the button in the form:

<s:FormItem> <s:Button id="button" label="Add" click="button_clickHandler(event)" label.EmployeeUpdate="Update"/> </s:FormItem>

... which populates employee with the data from the input controls and now in this case, employee.id will be zero so employee is passed to the data service's createEmployee() method.

protected function button_clickHandler(event:MouseEvent):void { employee.lastname = lastnameTextInput.text; employee.firstname = firstnameTextInput.text; employee.title = titleTextInput.text; //code to set the rest of the properties if(employee.id==0){ //for Java and PHP createEmployeeResult.token = employeeService.createEmployee(employee); //for CF, createEmployeeResult.token = employeeService.createEmployee({item:employee}); } else{ //for Java and PHP updateEmployeeResult.token = employeeService.updateEmployee(employee); //for CF, updateEmployeeResult.token = employeeService.updateEmployee({item:employee}); } }

To handle results, a new CallResponder is defined with a result handler:

<s:CallResponder id="createEmployeeResult" result="createEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.

createEmployeeResult.token=employeeService.createEmployee(employee);

After the data is added successfully to the database, the EmployeeDetails state is shown with the details for this new employee.

protected function createEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; // more code }

At this point the new employee is saved in the database, but not in the collection of data being displayed in the DataGrid. You need to assign the newly generated id to employee and add employee to the data displayed in the DataGrid.

If you look in the TestDrive server-side service file, you will see that the createEmployee() method returns an integer equal to the id of the new employee inserted in the database. The data returned from a server-side method call is stored in the result property of the event object that is passed to the result event handler. The idproperty of employee is data typed as an integer and the result property of the event object is data typed as a general Object, so you have to cast event.result to an integer to set id equal to it.

employee.id=event.result as int;

You use the addItem() method to add the new employee to the employees ArrayCollection.

employees.addItem(employee);

Note: In this example, you are writing code to update both the server-side data (stored in the database) and the client-side data (stored in the DataGrid dataProvider). Flash Builder also has a data management feature you can use to help synchronize client and server-side data.

Then, you select it in the DataGrid:

empDg.setSelectedIndex (employees.getItemIndex(employee));

... and then scroll to it so it is displayed:

empDg.ensureCellIsVisible(empDg.selectedIndex);

The result event handler for adding an employee appears as shown here.

protected function createEmployeeResult_resultHandler(event:ResultEvent):void { currentState="EmployeeDetails"; employee.id=event.result as int; employees.addItem(employee); empDg.setSelectedIndex(employees.getItemIndex(employee)); empDg.ensureCellIsVisible(empDg.selectedIndex); }

Deleting data

The last thing to look at is how to delete an employee from the database. The process is very similar to those for adding and updating. When an employee is selected, a delete button is enabled.

<s:Button id="deleteBtn" click="deleteBtn_clickHandler(event)" enabled.EmployeeAdd="false" includeIn="EmployeeAdd,EmployeeDetails,EmployeeUpdate" label="Delete" enabled.EmployeeUpdate="true"/>

When the user clicks this button, the server-side deleteEmployee() method is called.

protected function deleteBtn_clickHandler(event:MouseEvent):void { deleteEmployeeResult.token = employeeService.deleteEmployee(employee.id); }

To handle results, a new CallResponder is defined with a result handler:

<s:CallResponder id="deleteEmployeeResult" result="deleteEmployeeResult_resultHandler(event)"/>

... and the service call assigned to the CallResponder's token property.

deleteEmployeeResult.token=employeeService.deleteEmployee(employee.id);

The server-side method expects one argument, the id of the employee to delete.

In the result handler, the employee is removed from the employees ArrayCollection using its removeItemAt()method and the application is switched to its Employees state (there is no longer any employee selected to show details for).

protected function deleteEmployeeResult_resultHandler(event:ResultEvent):void { employees.removeItemAt(empDg.selectedIndex); currentState="Employees"; }
:
Posted by 라면스프
2011. 11. 1. 09:17

[FLEX]플래시(Flash) 소켓(Socket) 레퍼런스 Enjoy/FLEX2011. 11. 1. 09:17




패키지 :loadClassListFrame('class-list.html')">flash.net
클래스 public class Socket
상속 Socket Inheritance EventDispatcher Inheritance Object
구현 IDataInputIDataOutput

언어 버전:  ActionScript 3.0
런타임 버전:  AIR 1.0, Flash Player 9

Socket 클래스는 ActionScript 코드를 활성화하여 소켓 연결을 만들고 원시 이진 데이터를 읽고 쓸 수 있도록 합니다. XMLSocket과 유사하지만, 수신된 또는 전송된 데이터의 형식을 지정하지는 않습니다.

소켓 클래스는 이진 프로토콜을 사용하는 서버와의 작업에서 유용합니다.

Socket 클래스의 메서드를 사용하려면 우선 생성자인 new Socket을 사용하여 Socket 객체를 만들어야 합니다.

local-with-filesystem 샌드박스의 SWF 파일은 소켓을 사용할 수 없습니다.

대상 호스트의 소켓 정책 파일은SWF 파일에서 소켓 연결을 만들 수 있는 호스트 및 가능한 대상 포트를 지정합니다. Flash Player의 버전이 올라가면서소켓 정책 파일에 대한 보안 요구 사항이 보다 엄격해졌습니다. 모든 버전의 Flash Player에서 소켓 정책 파일을 사용하는것이 좋습니다. 소켓 정책 파일이 필수적인 경우도 있습니다. 따라서 XMLSocket 객체를 사용할 때는 필요한 경우 대상호스트가 소켓 정책 파일을 제공하는지 확인해야 합니다.

다음 목록에서는 여러 버전의 Flash Player에서 소켓 정책 파일에 대한 요구 사항을 보여 줍니다.

  • Flash Player 9.0.124.0 이상에서는 모든 Socket 연결에 소켓 정책 파일이 필요합니다. 즉, 연결하는 포트에관계없이 대상 호스트에 소켓 정책 파일이 있어야 하며, SWF 파일을 제공하는 해당 호스트의 포트에 연결하는 경우에도마찬가지입니다.
  • Flash Player 9.0.115.0 이전 버전에서는 1024보다 낮은 포트 번호에 연결하거나 SWF 파일을 제공하는 호스트와 다른 호스트에 연결하려는 경우 대상 호스트에 소켓 정책 파일이 있어야 합니다.
  • Flash Player 9.0.115.0에서는 소켓 정책 파일이 필수적이지 않지만 대상 호스트에서 소켓 정책 파일을 제공하지 않으면 Flash Debug Player를 사용할 때 경고가 표시됩니다.

보안과 관련된 자세한 내용은 다음을 참조하십시오.

  • 보안 장(ActionScript 3.0 프로그래밍 설명서) 및 LiveDocs의 최신 의견
  • Flash Player 개발자 센터 항목: 보안

예제 보기



Public 속성
 속성다음에 의해 정의됨
    bytesAvailable : uint
[읽기 전용] 입력 버퍼에서 읽을 수 있는 데이터 바이트 수입니다.
Socket
    connected : Boolean
[읽기 전용] 이 소켓 객체가 현재 연결되어 있는지 여부를 나타냅니다.
Socket
  Inherited constructor : Object
지정된 객체 인스턴스의 클래스 객체 또는 생성자 함수에 대한 참조입니다.
Object
    endian : String
데이터의 바이트 순서를 나타냅니다. flash.utils.Endian 클래스에서 Endian.BIG_ENDIAN 또는 Endian.LITTLE_ENDIAN 상수 값을 가질 수 있습니다.
Socket
    objectEncoding : uint
객체를 쓰거나 읽을 때 사용되는 AMF 버전을 제어합니다.
Socket
  Inherited prototype : Object
[정적] 클래스 또는 함수 객체의 프로토타입 객체에 대한 참조입니다.
Object
    timeout : uint
연결을 기다릴 시간(밀리초)를 나타냅니다.



[보안정책 참고용] 
Flash Socket(소켓) Policy(보안) 정책
 
http://cafe.naver.com/q69/117152 http://www.jcraft.com/jhttptunnel/index.html

 
:
Posted by 라면스프
2011. 7. 1. 13:57

[FLEX] 그래프 샘플사이트 Enjoy/FLEX2011. 7. 1. 13:57

http://demo.quietlyscheming.com/ChartSampler/app.html
:
Posted by 라면스프
2011. 7. 1. 13:56

[FLEX] Application 컴파일 옵션 Enjoy/FLEX2011. 7. 1. 13:56

The CSS type selector 'XXXXX' was not processed,
because the type was not used in the application.

요 Warnings가 뜰때.... 컴파일 할때마다 신경쓰게 하는 메시지였다.
저 메시지의 원인은 CSS에서 Style을 지정한 컴포넌트를 사용하지 않아서 이다
그렇다고 Application 마다 CSS를 따로 만들수도 없는 노릇이다.

해결방법은 컴파일 옵션
-show-unused-type-selector-warnings=false

:
Posted by 라면스프
출처 : http://blog.jidolstar.com/




[Flex/AIR]BitmapData를 PNG나 JPG로 변환하여 ByteArray로 서버에 전송하는 방법

로컬자원을 서버에 전송하기 위해 우리는 FileReference Class를 사용하면 된다.
FileReference로 파일을 서버에 전송하는 방법은 많이 공개가 되어 있다.
알다시피 FileReference의 browse()함수를 호출한 뒤, select 이벤트가 발생시 upload() 함수를 이용하여 선택한 로컬자원을 서버로 보낸다. 

서버에서는 아주 단순하게 서버 임시 저장소에 저장된 파일을 원하는 곳에 복사하기만 하면 된다. 
php의 경우 move_uploaded_file() 메소드를 사용하면 되겠다.

그럼 Flex 시행도중 캡쳐한 화면을 저장하는 경우에도 위와 같은 방법으로 저장이 가능할까?

답은 "된다"


나는 예전에 ImageSnapshot 클래스를 이용해 base64로 변환해서 서버로 전송한 뒤에 base64를 decode하여 저장하는 방법에 대해서 언급한적이 있다. (http://blog.jidolstar.com/301  참고)
이 방법의 단점은 이미지가 큰 경우 base64로 encode, decode 하는 과정에서 서버성능 및 클라이언트 성능에 따라 속도 및 부하에 영향을 준다. 그러므로 이 방법으로는 PNGEncoder 및 JPGEncoder로 PNG, JPG 파일 형식에 맞는 데이타를 만들었다고 해도, FileReference와 같이 데이타를 전송을 할 수 없었다.

하지만 Google을 열심히 돌아다녔다니 이 문제점에 대한 해결의 실마리를 찾을 수 있었다.
(역시 Google!!!)

간단히 방법을 요약하자면 
화면을 BitmapData로 만들어 PNGEncoder나 JPGEncoder를 이용하여 encode한 다음, 그 결과값인 byteArray값을 서버에 전송한다. 전송된 데이타는 FileReference에서 upload()을 이용해 보낸 파일을 저장할때와 동일하게 저장하면 되겠다.

1. BitmapData로 캡쳐해라.

아래 target은 캡쳐할 UIComponent와 같은 DisplayObject 객체이다.

BitmapData로 캡쳐
var bitmapData:BitmapData = new BitmapData(target.width, target.heighttrue, 0xFFFFFF);
var drawingRectangle:Rectangle =  new Rectangle(00, target.width, target.height);
bitmapData.draw(target, new Matrix()nullnull, drawingRectangle, false);

단, BitmapData를 이용해서 화면을 캡쳐할 대상이 외부 동영상이나 사진같은 거라면 crossdomain.xml 에 대한 check가 있어야 한다. 컨텐츠 로드시 checkPolicyFile 속성을  true로 설정할 필요가 있겠다.
그리고 2880px 이상의 크기는 BitmapData로 만들 수 없다.



2. JPG나 PNG로 Encode 하여 ByteArray를 얻는다.


Flex 3 SDK에는 mx.graphics.codec 패키지에 JPGEncoder와 PNGEncoder가 있다. 인터넷을 뒤져보면 GIFEncoder등도 있을것이다. Flex 2 환경에서 작업한다면 Google code에 Adobe AS3 Corelib에 이들이 제공된다. 만약 JPGEncoder를 사용한다면 다음과 같이 하면 되겠다.

JPGEncoder를 이용하여  JPG  ByteArray값 만들기
import mx.graphics.codec.JPGEncoder;

var byteArray:ByteArray = new JPGEncoder().encode(bitmapData);


Flex 3 SDK는 이러한 Encoder가 IImageEncoder로 구현되었다. 필요하다면 언제 어디서나 Encoder를 바꿔야 하는 경우 IImageEncoder를 사용하는 것이 좋을 수 있겠다.
가령 아래 예제처럼 말이다.

다양한 Image Encoder 사용하기
import mx.graphics.codec.*;

var imageType:String = "jpg";
var imageEncoder:IImageEncoder;
if( imageType.toUpperCase() == "JPG" ) imageEncoder= new JPEGEncoder();
else if( imageType.toUpperCase() == "PNG" ) imageEncoder= new PNGEncoder();
var byteArray:ByteArray = imageEncoder.encode(bitmapData);



 

3. 서버에 ByteArray를 전송한다.

데이타를 전송할때는 FileReference를 사용하지 않는다.
바로 URLLoader와 URLRequest만 이용해서 전송이 가능하다. 참고 데이타는 POST방식으로 URLVariable을 이용해서 보낼 수 있다. 

Flex/AIR 데이터 전송 방법
//assumed variable declarations
//var byteArray:ByteArray = 2번째 단계에서 JPG 데이타를 얻었다.
//var fileName:String = "desiredfilename.jpg" //저장할 파일 이름이다. 아무거나 적자!
//var uploadPath:String = "저장할 때 사용되는 서버측 script 경로"
//var parameters:URLVariables = 이미지 이외에 다른 보낼 다른 데이타가 있다면 이것을 이용한다.
//function onComplete(eventObj:Event):void {  성공적으로 데이타를 전송했을때 핸들러 함수 정의
//function onError(eventObj:ErrorEvent):void {  이미지 전송을 실패했을때 핸들러 함수 정의

var urlRequest:URLRequest = new URLRequest();
urlRequest.url = uploadPath;
urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = UploadPostHelper.getPostData(file, byteArray, parameters);
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control''no-cache' ) );

var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, onComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
urlLoader.load(urlRequest);


위에 진한 부분에 대한 클래스는 아래에 정의되어 있다. 당신은 이 클래스가 어떻게 구성되었는가 열심히 공부할 필요가 없다.(원한다면 해도 된다. 말리지 않음 ^^)

UploadPostHelper Class (Language : java)
package {

    import flash.events.*;
    import flash.net.*;
    import flash.utils.ByteArray;
    import flash.utils.Endian;

    /**
     * Take a fileName, byteArray, and parameters object as input and return ByteArray post data suitable for a UrlRequest as output
     *
     * @see http://marstonstudio.com/?p=36
     * @see http://www.w3.org/TR/html4/interact/forms.html
     * @see http://www.jooce.com/blog/?p=143
     * @see http://www.jooce.com/blog/wp%2Dcontent/uploads/2007/06/uploadFile.txt
     * @see http://blog.je2050.de/2006/05/01/save-bytearray-to-file-with-php/
     *
     * @author Jonathan Marston
     * @version 2007.08.19
     *
     * This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 3.0 License.
     * @see http://creativecommons.org/licenses/by-nc-sa/3.0/
     *
     */

    public class UploadPostHelper {

        /**
         * Boundary used to break up different parts of the http POST body
         */

        private static var _boundary:String = "";

        /**
         * Get the boundary for the post.
         * Must be passed as part of the contentType of the UrlRequest
         */

        public static function getBoundary():String {

            if(_boundary.length == 0) {
                for (var i:int = 0; i < 0x20; i++ ) {
                    _boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
                }
            }

            return _boundary;
        }

        /**
         * Create post data to send in a UrlRequest
         */

        public static function getPostData(fileName:String, byteArray:ByteArray, parameters:Object = null):ByteArray {

            var i: int;
            var bytes:String;

            var postData:ByteArray = new ByteArray();
            postData.endian = Endian.BIG_ENDIAN;

            //add Filename to parameters
            if(parameters == null) {
                parameters = new Object();
            }
            parameters.Filename = fileName;

            //add parameters to postData
            for(var name:String in parameters) {
                postData = BOUNDARY(postData);
                postData = LINEBREAK(postData);
                bytes = 'Content-Disposition: form-data; name="' + name + '"';
                for ( i = 0; i < bytes.length; i++ ) {
                    postData.writeByte( bytes.charCodeAt(i) );
                }
                postData = LINEBREAK(postData);
                postData = LINEBREAK(postData);
                postData.writeUTFBytes(parameters[name]);
                postData = LINEBREAK(postData);
            }

            //add Filedata to postData
            postData = BOUNDARY(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Disposition: form-data; name="Filedata"; filename="';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData.writeUTFBytes(fileName);
            postData = QUOTATIONMARK(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Type: application/octet-stream';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);
            postData = LINEBREAK(postData);
            postData.writeBytes(byteArray, 0, byteArray.length);
            postData = LINEBREAK(postData);

            //add upload filed to postData
            postData = LINEBREAK(postData);
            postData = BOUNDARY(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Disposition: form-data; name="Upload"';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);
            postData = LINEBREAK(postData);
            bytes = 'Submit Query';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);

            //closing boundary
            postData = BOUNDARY(postData);
            postData = DOUBLEDASH(postData);

            return postData;
        }

        /**
         * Add a boundary to the PostData with leading doubledash
         */

        private static function BOUNDARY(p:ByteArray):ByteArray {
            var l:int = UploadPostHelper.getBoundary().length;

            p = DOUBLEDASH(p);
            for (var i:int = 0; i < l; i++ ) {
                p.writeByte( _boundary.charCodeAt( i ) );
            }
            return p;
        }

        /**
         * Add one linebreak
         */

        private static function LINEBREAK(p:ByteArray):ByteArray {
            p.writeShort(0x0d0a);
            return p;
        }

        /**
         * Add quotation mark
         */

        private static function QUOTATIONMARK(p:ByteArray):ByteArray {
            p.writeByte(0x22);
            return p;
        }

        /**
         * Add Double Dash
         */

        private static function DOUBLEDASH(p:ByteArray):ByteArray {
            p.writeShort(0x2d2d);
            return p;
        }

    }
}



한가지 중요한 정보를 언급하겠다.
URLLoader를 이용해 서버에 전송할때, 프로그램이 같은 도메인상에 있는 경우에는 보안문제가 없다. 하지만 다른 도메인에 위치한 서버로 이미지를 전송할때는 반드시 crossdomain.xml을 check해야한다. 

1. Security.loadPolicyFile(http://다른도메인/crossdomain.xml ); 를 URLLoader의 load()함수를 호출하기 전에 호출한다. 

2. Flash Player 9.0.124.0 버전부터는 HTTP Header 보안취약점을 해결하기 위해서 cross domain 정책이 변경되었는데.... 서버측에 있는 crossdomain.xml에 allow-http-request-headers-from가 추가되어져야 한다. 이것은 HTTP 헤더 전송을 허용할지 결정해준다.

crossdomain.xml (Language : xml)
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
      <allow-access-from domain="*.jidolstar.com" />
      <allow-http-request-headers-from domain="*.jidolstar.com" headers="*"/>
</cross-domain-policy>

위 처럼 서버측 crossdomain.xml에 allow-http-request-headers-from을 추가함으로 다른 도메인간에 HTTP 헤더 전송을 허용할 수 있다. 

서로 다른 도메인에 SWF와 서버측 코드가 배치되어 있다면 반드시 이 사실을 숙지하길 바란다.
 

4. 서버측 코드 작성

만약 위 3번 코드에서 var parameters:URLVariables를 아래와 같이 작성했다고 하자.

URLVariables 설정 (Language : java)
var parameters:URLVariables = new URLVariables();
parameters.method = "id";
parameters.userId = "2000321";


그럼 PHP 코드로 아래와 같은 방법처럼 만들면 되겠다.(테스트는 안해봤음)

PHP 코드 예제 (Language : php)
<?php
$method = $_POST['method'];
$userId = $_POST['userId'];
$file_temp = $_FILES['Filedata']['tmp_name'];
$file_name = $_FILES['Filedata']['name'];
$file_size = $_FILES['Filedata']['size'];

if( $method == "id" )
{
  $movePath = "/home/myPath/images/$userId_$file_name";
}
else
{
  $movePath = "/home/myPath/images/time_".time()."_".$file_name;
}

move_uploaded_file($file_temp,$movePath);

echo "save Complete";
?>


마지막 save Comple 메시지를 받기 위해서는 Flex의 Complete 이벤트 발생시 아래와 같은 방법으로 받으면 되겠다. 이것을 알아내는데도 많이 힘들었다. 일종의 팁이다. ^^;

데이타 받기 (Language : java)
var loader:URLLoader = URLLoader(event.target);
var bytedata:ByteArray = loader.data;
var strData:String = bytedata.toString();
trace( strData)


실제 업무에도 잘 이용하고 있다.
이미지 에디터 등을 만들때 아주아주 유용한 자료가 될 것이다.

누가 예제 프로그램 만들어서 트랙백 걸어 주시면 고맙겠다.


:
Posted by 라면스프
2011. 5. 24. 18:15

BlazeDS Source Enjoy/FLEX2011. 5. 24. 18:15

출처 : http://opensource.adobe.com/wiki/display/blazeds/Source

BlazeDS Source

BlazeDS is one of several open-source projects in a Subversion repository hosted by Adobe. Subversion is an open-source revision control system used for many open-source projects. If you haven't used it before, please see the official documentation.

View the BlazeDS Source Tree

If you just wish to browse around the BlazeDS source tree, go straight to the public repository here.

BlazeDS Source Tree Organization

Within the project are directories named trunk, branches, and tags, as is standard for Subversion projects.

The trunk is generally work-in-progress on the version under current development. The trunk should build and pass basic tests but may be unstable and unsuitable for use.

Branches are created when projects need to stabilize code for a release. The BlazeDS 4 code may be found in branches/4.x and BlazeDS 3 code may be found in branches/3.x.

Tags record the code that shipped as a specific release, or other milestones in a project. The code which shipped as the 4.0 release has been tagged as tags/4.0.0.

Access the BlazeDS Source

Most users of the source code probably don't need to have day to day access to the source code as it changes. For these users we provide a zip file of the latest stable release.

  • To download a zip file of the source of the latest stable release, go here


Checking out Source Code

If you feel that you need access to the source tree to get a local copy of the latest and greatest code, you will need a Subversion client. The BlazeDS team has had good experience with TortoiseSVN on Windows and SmartSVN on Macintosh, both of which are GUI clients. (This is not an official endorsement of these products by Adobe.) Of course, you can use whatever client you prefer, including Subversion's official command-line tool svn.

NOTE: The Subversion repository should only be used if you want to be on the bleeding-edge of the development effort. The code contained in them may fail to work, or it may even eat your hard drive.

When you access the repository with a Subversion client, the BlazeDS project is at the URL http://opensource.adobe.com/svn/opensource/blazeds.

To get the source code, do a "checkout" of the trunk or some branch or tag into a local directory on your machine. For example, to get the code in the trunk, checkout from the URL http://opensource.adobe.com/svn/opensource/blazeds/trunk. Using the command-line client, you would execute

svn checkout http://opensource.adobe.com/svn/opensource/blazeds/trunk <local-directory>

To get the code that was used to build the BlazeDS 4 release, checkout from the URL http://opensource.adobe.com/svn/opensource/blazeds/tags/4.0.0:

svn checkout http://opensource.adobe.com/svn/opensource/blazeds/tags/4.0.0 <local-directory>

To get the code that was used to build the BlazeDS 3 release, checkout from the URL http://opensource.adobe.com/svn/opensource/blazeds/tags/3.0.0:

svn checkout http://opensource.adobe.com/svn/opensource/blazeds/tags/3.0.0 <local-directory>

Warning: You probably don't want to check out the entire blazeds directory, as you'll get every branch and tag, each of which is comparable in size to the trunk.

Access rights

Everyone has read-only access to the BlazeDS project. If you want to contribute to the BlazeDS project, refer to the BlazeDS page on Submitting A Patch.

Change notifications

If you'd like to keep up-to-date on changes to the BlazeDS project, you may subscribe to the Commits forum.


:
Posted by 라면스프
2011. 5. 18. 15:44

이펙트 트리거 종류 Enjoy/FLEX2011. 5. 18. 15:44

출처 : http://loudon23.blog.me/30020039980


이펙트 트리거

 

addedEffect : 컴포넌트가 컨테이너에 child로 추가될 때

removedEffect : 컴포넌트가 컨테이너로 부터 제거될 때

creationCompleteEffect : 컴포넌트가 새로 생성 되었을 때

 

focusInEffect : 컴포넌트가 포커스를 얻었을 때

focusOutEffect : 컴포넌트가 포커스를 잃었을 때

 

showEffect : 컴포넌트 visible 속성이 false에서 true로 바뀌어 보이게 되었을 때

hideEffect : 컴포넌트 visible 속성이 true에서 false로 바뀌어 보이게 되었을 때

resizeEffect : 컴포넌트 크기가 변경 되었을 때

moveEffect : 컴포넌트가 이동 할 때

 

rollOverEffect : 컴포넌트 위에 마우스가 올라가 갔을 때

rollOutEffect : 컴포넌트 위에 있던 마우스가 컴포넌트 밖으로 나갔을 때

mouseDownEffect : 컴포넌트에 마우스 버튼으로 눌렀을 때

mouseUpEffect : 컴포넌트에 눌러진 마우스 버튼을 놓았을 때

 

[출처] 이펙트 트리거 종류|작성자 루든

:
Posted by 라면스프