Dec 5, 2006 6:54:28 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: ....

메시지가 뜬다면 .... tcnative-1.dll 파일이 서버에 존재하지 않아서 그런것임.

http://tomcat.heanet.ie/native/1.1.12/binaries/win32/
(2008.05.29일 현재 최신버전)

파일을 다운받아 적당한 곳(Path설정된 곳)에 위치 시키면 됩니다.

======================================================================================
아래글은 참조 블로그 입니다.
======================================================================================
톰켓 5.5.20을 사용해서 개발을 진행하던중...

Dec 5, 2006 6:54:28 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: ....

톰켓 시작시 항상 나오는 찜찜한 정보...
제대로 동작은 하는데 뭔지 모를 찜찜함... ㅡㅡ;;

Dec 29, 2006 1:15:53 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: Failed shutdown of Apache Portable Runtime

이눔이 종료할때두 항상 나오는것이 아닌가...?? ㅡㅡ^

그냥 무시하고 살았는데
저게 도대체 왜 뜨는건지 궁금증이 밀려와서 디벼보기 시작했다.

시작시 정보는... 뭔가를 찾지 못한다..
종료시엔 내가 엄청 싫어하는... Fail.... 어쩌구 저쩌구.. @.@


그래서~ 소스를 디컴파일 하면서 쭈~~~~~~~~~~~~~~~~~~ㄱ 찾아가 보니...

JNI (Java Native Interface) 관련된 내용을 못찾는거던데...

"tcnative-1", "libtcnative-1"

요 두 파일을 시스템의 PATH에서 찾아보니 없댄다.

파일 검색을 해보니 진짜루 없는게 아닌가..? @.@

이상하다.... 해서 구글링을 해보니...

저넘을 따로 갖다놔야 된댄다. ㅡㅡ;;

http://tomcat.heanet.ie/native/1.1.6/binaries/

요기에서 내 로컬 개발서버인 윈도우즈에 맞는 DLL을 적당한 경로에
(난 JDK bin 디렉토리에 뒀다.) 복사하고

로컬 개발서버에선 깔끔하게 해결~!! ㅋㅋㅋ


개발서버인 리눅스엔 바이너리 복사 시도 실패. ㅡㅡ^

rpm 으로 설치 실패. ㅡㅡ++

소스 컴파일.. 성공.

하고 톰캣 실행 스크립트에 LD_LIBRARY_PATH에다가

경로 지정해줬더니 에러(?)가 안뜬다... ㅋㅋㅋ

짜슥들 좀 기본적으로 포함시켜두면 어디가 덧나나?? ㅡㅡ^

아무튼...

이제 깔끔하게 일 시작해 볼까~


그나저나...

리눅스쪽에 소스 설치하다가 알았는데...

APR (Apache Portable Runtime) 이넘... (http://apr.apache.org)

뭐하는 넘인지 나중에 좀 찾아봐야겠다.

소스 설치할때 이넘땜에 고생좀 했다.. ㅡㅡ;;

* 객체직렬화의 개념

 

자바 I/O 처리는 정수, 문자열, 바이트 단위의 처리만 지원했었다.

따라서 복잡한 객체의 내용을 저장/복원하거나, 네트워크로 전송하기 위해서는 객체의 멤버변수의

각 내용을 일정한 형식으로 만들어(이것을 패킷이라고 한다) 전송해야 했다.


객체직렬화는 객체의 내용(구체적으로는 멤버변수의 내용)을 자바 I/O가 자동적으로 바이트 단위로 변환하여, 저장/복원하거나 네트워크로 전송할 수 있도록 기능을 제공해준다.

즉, 개발자 입장에서는 객체가 아무리 복잡하더라도, 객체직렬화를 이용하면 객체의 내용을 자바 I/O가 자동으로 바이트 단위로 변환하여 저장이나 전송을 해주게 된다.

또한 이것은 자바에서 자동으로 처리해주는 것이기 때문에, 운영체제가 달라도 전혀 문제되지 않는다.

 

객체를 직렬화할때 객체의 멤버변수가 다른 객체(Serializable 인터페이스를 구현한)의 레퍼런스 변수인 경우에는 레퍼런스 변수가 가리키는 해당 객체까지도 같이 객체직렬화를 해버린다.

또 그 객체가 다른 객체를 다시 가리키고 있다면, 같은 식으로 객체직렬화가 계속해서 일어나게 된다.

이것은 마치 객체직렬화를 처음 시작한 객체를 중심으로 트리 구조의 객체직렬화가 연속적으로 일어나는 것이다.

 

 

* 도입이유

 

1. RMI의 도입

RMI는 원격객체통신을 지원해야 하기 때문에, 객체의 내용이 투명하게 이동할 수 있어야 한다

 

2. Beans

Beans는 설계시에 상태정보를 지정할 수 있는데, 이것을 마땅히 저장할 메커니즘이 없다.

이때 객체직렬화를 사용하면, 편하게 객체의 상태정보를 저장하는 것이 가능하다

 

3. 간단한 네트워크 프로그램이나 파일 프로그램은 객체직렬화를 사용하면, 코딩이 반으로 준다.

 

 

 

* 객체 직렬화의 과정


객체는 ObjectOutputStream의 writeObject() 메쏘드에 자신을 넘김으로써 직렬화 된다.
writeObject()메쏘드는 private 필드와 super 클래스로부터 상속받은 필드를 포함,
객체의 모든 것을 기록하게된다.
 
직렬화 해제는 직렬화와 반대의 과정을 거치게 되는데
ObjectInputStream의 readObject() 메서드를 호출함으로써
스트림으로부터 읽어 들이고 이를 직렬화 되기전의 객체로 다시 만들게 된다.

직렬화에 대한 간단한 예제이다.

ObjectOutputStream을 생성해서 writeObject() 메서드를 이용해서 객체를 직렬화하고,
ObjectInputStream을 생성해서 readObject() 메서드를 통해서 객체를 복원한다.
또한 SerializableClass가 Serializable을 implements한 것을 주의해서 보아야 한다.


----------------------------------------------------------------------------------

ObjectSerializableTest.java



import java.io.*;


public class ObjectSerializeTest {

public static void main(String[] args) throws Exception {


// 파일을 열어서 그곳에 객체를 직렬화시켜서 저장한다.
// 파일 출력스트림을 연다.
FileOutputStream fileout = new FileOutputStream("test.txt");


// 객체스트림을 열고, 객체스트림을 통해 객체를 파일에 저장
ObjectOutputStream out = new ObjectOutputStream(fileout);
out.writeObject(new SerializableClass("Serialize Test Program", 1014));


// 객체스트림을 닫는다.
out.close();


// 직렬화 된 객체를 저장된 파일로 부터 객체를 해제시켜 원래의 객체로 복원
// 파일 입력스트림으로부터 객체 입력스트림을 연다.
FileInputStream fileinput = new FileInputStream("test.txt");
ObjectInputStream in = new ObjectInputStream(fileinput);


// 객체 입력스트림으로부터 객체를 읽어온다.
SerializableClass sc = (SerializableClass)in.readObject();


// 객체스트림을 닫는다.
in.close();


// 스트림으로부터 읽어들인 객체의 내용을 출력
// 원래 생성되었던 객체와 같은 값을 갖는다는 것을 알수가 있다.
System.out.println("String : " + sc.Sstr);
System.out.println("Integer : " + sc.Sint);
}
}


// 하나의 문자열과 정수를 저장하고 있는 SerializableClass를
// Serializable을 implements 함으로써
// 스트림을 통해 직렬화되고 해제되어질 수 있다.

class SerializableClass implements Serializable {

public String Sstr;
public int Sint;


// 생성자
public SerializableClass(String s, int i) {
this.Sstr = s;
this.Sint = i;
}
}



-----------------------------------------------------------------
실행결과


String : Serialize Test Program
Integer : 1014





========================================================================================

자바는 객체지향언어이다.

즉, 가상머신 내에 존재하는 것은 모두 객체들로 이루어져 있습니다.

물론, 객체를 만들기 위한 클래스들도 있겠죠.

클래스의 형태를 보고 필요하다면 언제든지 객체를 만들어 낼 수 있습니다.

객체와 클래스의 관계를 논하지 않고서는 아무것도 할 수 없겠죠.

컴파일 한 후, 생성된 .class파일은 클래스의 모든 정보를 담고 있으며,

이 .class의 바이트는 가상머신에 Class클래스의 형태로 로딩 되어 집니다.

그리고, 로딩된 클래스의 정보를 보고 객체를 만들게 됩니다.

클래스는 데이터 타입이며 이 데이터타입이 있어야 그 모양을 보고 객체의 메모리를 생성할 수 있습니다.

 

특정 클래스의 객체를 만들었을 때 객체는 무엇으로 이루어져 있을까요?

객체는 멤버변수의 메모리의 크기와 같다.

객체는 멤버변수의 메모리만으로 이루어져 있습니다.

만약, 객체를 이용해서 메서드를 호출한다면 객체가 보유하고 있는 값과 호출할 메서드의 형태만 있으면 언제든지 호출 가능합니다.

메서드의 형태는 클래스의 정보가 있는 부분에 있을 것이고,

메서드 내에 멤버변수가 사용되어진다면, 그 값은 객체 내에 있으니 이 두 가지를 조합한다면 언제든지 메서드를 호출할 수 있습니다.

 

가상머신에 존재하는 객체메모리 그 자체를 저장하거나, 통째로 네트웍으로 전송하려고 합니다.

저장을 하든 네트웍으로 전송을 하든간에 객체는 일련의 바이트의 형태로 되어 있어야 합니다.

어떤 규칙에 의해서 객체 메모리를 한 줄로 늘어선 바이트의 형태로 만들고,

다시 객체의 형태로 복원하는 작업을 우리는 객체 직렬화라고 합니다

 

 

‘이름’, ‘부서’, ‘직책’ 이라는 속성을 가진 직원 클래스가 있고, 이 클래스를 이용하여 두 개의 객체 (직원1 객체와 직원2 객체)가 생성되어 메모리에 저장되어 있다면,

직원1 객체는 이름이 홍길동이고 부서는 총무부, 직책은 과장이라는 상태 정보를 저장하고 있습니다.

 

이러한 객체들이 저장 되어 있는 메모리는 휘발성이기 때문에,

컴퓨터의 전원을 종료하게 되면 객체의 상태 정보는 모두 사라집니다.

그래서 우리는 이 정보를 데이터베이스에 저장하거나 아니면 따로 기록해 두는 것입니다.

다시 객체로 만들려면 데이터베이스 내용을 검색해서 해당 내용을 찾아와서 객체의 형태로 다시 조합해야 합니다.

 

이러한 방법을 사용하는 대신, 객체 그 자체를 바로 저장하고 다시 불러왔을 때 원래의 객체 형태 그 자체라면 아주 효율적이겠죠.

 

정민철,영업부,부장 이라는 정보를 묶어서 소켓으로 전송한다면 다음과 같이 전송할 겁니다.

 

정민철|영업부|부장

 

이러한 방법으로 보내면 받는쪽에서는 “|”을 구분자로 해서 하나씩 분해해야 합니다.

만약 객체자체를 보낸다면 상황은 다릅니다. 다음과 같은 객체를 보낸다면

 

--------------------------------------------------------------

Employee.java

 

 

public class Employee {

   private String name;             // 이름

   private String dept;               // 부서

   private String duties;            // 직책

 

   public Employee (String name, String dept, String duties) {

       this.name = name;

       this.dept = dept;

       this.duties = duties;

   }// 생성자

 

public static void main(String[] args){

       Employee Emp = new Employee("조한서", "인사","차장");

     //Emp 자체를 네트웍으로 전송

   }

}

 

Emp 객체를 네트웍을 통해서 받았다면 바로 객체를 사용할 수 있다는 장점이 있습니다.

파싱할 필요도 없고, 특별한 작업 없이도 객체를 사용할 수 있는 방법론을 제공하는 것이 바로 객체 직렬화입니다.

이 개념이 RMI, Java Beans등의 핵심 기술이 됩니다.

 

객체 직렬화는 상당히 복잡한 과정을 필요로 하지만, 내부적으로 완벽하게 감추어져 있기 때문에 객체 직렬화를 직접 구현을 하는 것이 아니라 규칙에 맞게 사용하는 방법을 배우는 것이라고 보면 됩니다.

 

객체 직렬화에 대해서 정리하면

 

객체 직렬화는 객체의 상태를 보존하는 방법론을 제공한다.

파일 스트림, 네트워크 스트림 등과 함께 사용할 수 있는 확장성을 제공한다.

 

실제로 객체 직렬화 기술은 원격메소드호출(RMI : Remote Method Invocation)과 같은 기술에서 중요하게 사용이 됩니다.

RMI는 한쪽의 자바 가상 머신 내에 있는 객체가 멀리 떨어져 있는 원격지의 자바 가상 머신 내 객체를 네트워크를 통해 접근하고,

메서드를 호출 할 수 있게 해주는 기술입니다.

두 자바 가상 머신 사이에 연결된 바이트 스트림을 통해 메서드의 인자나 반환 값으로 객체를 주고 받기 위해서 객체 직렬화 기술이 사용됩니다.

또한, EJB라는 기술에서도 EJB 컨테이너의 성능 향상을 위해 사용됩니다.

 

객체 스트림에 저장될 객체는 Serializable이나 Externalizable 인터페이스를 구현 함으로써, 객체 자신이 저장될 의사가 있음을 반드시 밝혀야 합니다.

 

Serializable인터페이스는 아무 메서드도 가지고 있지않은 표시(태그) 인터페이스입니다. Serializable인터페이스를 구현한 객체는 객체 스트림 클래스들이 자동으로 필드들의 값을 저장하고 복구 해주지만,

Externalizable인터페이스를 구현한 객체는 객체를 표현할 필드들의 종류와 값을 writeExternal()메서드와 readExternal()메서드를 사용해서 직접 저장하고 복원하는 과정을 구현해야 합니다. 

 

 

* interface Serializable

 

객체직렬화가 필요한 객체는 반드시 Serializable 인터페이스르 구현해야 한다.

그러나, Serializable 인터페이스는 객체가 직렬화가 제공되어야 함을 자바가상머신(JVM)에 알려주는 역할만을 하는 인터페이스다.

따라서, Serializable 인터페이스를 지정하였다고 해도, 구현할 메서드는 없다.

 

보낼 객체가 직렬화 되어 있으면 전송은 특정 장치에 연결되어 있는 스트림이 모두 해결합니다.

우선 파일이나 네트웍에 스트림을 생성 한 후 객체를 보낼 수 있는 스트림으로 변환을 합니다.

그리고 직렬화되어 있는 객체를 보내면 됩니다.

그 순서를 정리하면 다음과 같습니다.

 

1. 네트웍이나 파일등에 스트림을 생성한다.

2. 생성된 스트림을 Object스트림으로 변환한다.

3. 입력과 출력스트림은 ObjectInputStream과 ObjectOutputStream이다.

4. 직렬화된 객체를 객체스트림을 통해서 전송한다.

    - ObjectOutputStream à writeObject(직렬화된객체)

5. 객체 스트림을 통해서 직렬화된 객체를 받는다.

    - ObjectInputStream à readObject()

 

이와 같은 순서로 객체 직렬화를 구현합니다.

스트림은 I/O에서 제공해 주기 때문에 보낼 객체만 생각하면 됩니다.

보낼 객체에 impelements Serializable만 붙이면 됩니다.

 

-------------------------------------------------------------

SerializableObject.java

 

 

import java.io.*;

 

public class SerialObject implements Serializable{

   private String name;        // 이름

   private String dept;          // 부서

   private String duties;       // 직책

   public SerialObject (String name, String dept, String duties) {

       this.name = name;

       this.dept = dept;

       this.duties = duties;

   }

   public String toString(){

       return name + ":" + dept + ":" + duties;

   }

}

 

임의의 파일에 객체 스트림을 연결하여 객체를 읽고 기록해 봅니다.

아래의 예는 객체를 기록한 후 다시 읽어내는 예제입니다.

 

----------------------------------------------------------------------

SerialObject.java

 

 

import java.io.*;

 

public class SerialObjectTest {

      

   public static void main(String[] args) throws Exception {

 

     FileOutputStream fileout = new FileOutputStream("test.txt");

      ObjectOutputStream out = new ObjectOutputStream(fileout);

       SerialObject se1 = new SerialObject("김언어", "개발부", "팀장");

       SerialObject se2 = new SerialObject("김서리", "자금부", "부장");

       SerialObject se3 = new SerialObject("이회계", "경리부", "차장");

       out.writeObject(se1);

       out.writeObject(se2);

       out.writeObject(se3);

       out.close();

 

       FileInputStream filein = new FileInputStream("test.txt");

       ObjectInputStream in = new ObjectInputStream(filein);

       SerialObject iso1 = (SerialObject)in.readObject();

       SerialObject iso2 = (SerialObject)in.readObject();

       SerialObject iso3 = (SerialObject)in.readObject();

       System.out.println(iso1.toString());

       System.out.println(iso2.toString());

       System.out.println(iso3.toString9));

       in.close();

   }

}

 

 

test.txt파일에 파일출력스트림을 생성합니다.

그리고 이 파일출력스트림을 Object출력스트림으로 변환합니다.

스트림을 열었다면 implements Serializable로 구현된 객체를 만들어야합니다.

위의 예제에서는 3개의 객체를 만들었습니다

그리고 이 객체를 test.txt파일에 객체가 3개이니 3번 기록 해야 합니다.

마지막으로 출력스트림을 닫습니다.

소스의 이 부분까지 수행되면 test.txt가 만들어지고 객체 3개가 순서대로 기록되게 됩니다.

 

입력된 객체를 읽어 내기 위해서 test.txt파일에 파일입력스트림을 생성합니다.

그리고 생성된 파일입력스트림을 Object입력스트림으로 변환합니다.

변환된 Object입력스트림으로 객체를 읽어냅니다.

앞에서 3개 입력했으니 3번만 읽어 내도록 합니다.

그리고 Object입력스트림으로 읽었을 때

반환형이 Object형이기 때문에 강제 Downcasting시켜야 합니다.

마지막으로 Object입력스트림을 닫으시면 모든 작업은 끝납니다.

 

 

Object스트림은 스트림의 한 종류입니다.

직렬화 된 객체를 보낼 수 있는 스트림이라고 말할 수 있습니다. 

객체를 객체출력스트림에 쓸 때는 ObjectOutputStream 클래스의 writeObject() 메서드를 사용합니다.

writeObject()의 원형의 다음과 같습니다.

 

public final void writeObject(Object obj) throws IOException

 

 writeObject()메서드는 인자로 넘어 온 객체가 Serializable인터페이스나 Externalizable 인터페이스를 구현했는지 검사합니다.

 

주어진 객체가 Serializable 인터페이스를 구현했다면,

writeObject()메서드는 자동으로 객체의 상태를 스트림에 기록해 줍니다.

만약 객체가 Serializable이나 Externalizable인터페이스 중 어느것도 구현하지 않았다면, NotSerializableException을 발생시킵니다.

 

스트림에 직렬화 되어있는 객체는 ObjectInputStream 클래스의 readObject() 메서드를 사용해서 복원 할 수 있습니다.

readObject()의 원형은 다음과 같습니다.

 

public final Object readObject() throws IOException, ClassNotFoundException

 

 readObject()메서드는 연결된 스트림으로부터 객체의 상태 정보를 읽어 내고,

writeObject()메소드와 마찬가지로 readObject()메서드 역시 객체가 Serializable 인터페이스를 구현했다면 스트림에 쓰여져 있던 객체의 상태 정보를 기반으로 자동으로 새로운 객체를 복원해 줍니다.

 

 

* transient 키워드

 

객체직렬화 전후에 보존하고 싶지 않은 멤버변수가 있을 경우에는, 해당 멤버변수에 transient 키워드를 사용함으로써 객체직렬화시 내용을 저장하지 않을 수 있다.

예를 들어 패스워드나 중요한 정보는 객체직렬화로 저장을 하게되면, 복원시에 누구라도 내용을 도로 알아낼 수가 있다.

따라서, 이러한 정보를 갖게되는 멤버변수는 transient 키워드를 사용해서 선언해주는 것이 좋다.

 

스트림을 이용해서 직렬화 할 때 객체의 모든 상태정보를 직렬화하게 됩니다.

하지만, 클래스를 디자인하다 보면 순간적으로 사용하고 버리는 필요없는 정보도 있습니다. 이러한 정보를 제외 시키기 위해서 transient키워드를 사용합니다.

 

클래스를 만들다 보면 중요하지는 않지만 전역 변수로 사용하기 위해서 어쩔 수 없이 멤버변수로 만드는 경우가 있습니다.

저장할 필요가 없다고 생각된다면 접근지정자 다음에 transient를 붙이면 직렬화에서

제외되어 버립니다.

 

객체를 직렬화 하는데 제외하겠다는 의미 이외에는 별다른 개념은 없습니다.

직렬화 될 필드가 static, transient로 선언되어 있으면 직렬화할 때 제외됩니다.

static변수는 공유메모리 개념을 가지고 있기 때문에 직렬화 할 때 제외 됩니다.

 

 

---------------------------------------------------------------------------------------------------------

TransientTest.java

 

 

import java.io.*;

 

public class TransientTest implements Serializable
{


     // 멤버변수
     private String name;
     transient String passwd;

 

 // 생성자
 public TransientTest(String s, String p)
 {
      name = s;
      passwd = p;
      System.out.println("생성자가 호출되었습니다: " + name);
 }

 

 // toString() 메서드를 오버라이드하여
 // println() 메서드에서 사용할때, 내용을 출력하도록 변경
 public String toString()
 {
      return "이름은 " + name+ " : 패스워드 : " + passwd;
 }

 

 public static void main(String args[])
 {
      TransientTest tt1, tt2;
      tt1 = new TransientTest("김가방","1234");
      tt2 = new TransientTest("이치민","0011");

  try
  {
       // 객체직렬화로 파일에 저장하기 위해
       // FileOutputStream에서 ObjectOutputStream 생성
       ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("TransientTest.ser"));

      

       // writeObject() 메서드를 사용하여 객체 저장
       out.writeObject(tt1);
       out.writeObject(tt2);
       out.close();

 

       // 객체직렬화로 파일에 저장된 객체를 복원하기 위해
       // FileInputStream에서 ObjectInputStream 생성
       ObjectInputStream in = new ObjectInputStream(new FileInputStream("TransientTest.ser"));

   

       TransientTest tt3, tt4;

 

       // 해당 스트림에서 readObject() 메서드를 호출
       tt3 = (TransientTest)in.readObject();
       tt4 = (TransientTest)in.readObject();

       System.out.println("다시 복원합니다");

 

        // 내용을 출력한다
       System.out.println(tt3);
       System.out.println(tt4);
  }catch(Exception e) {e.printStackTrace();}
 }
}

 

 

======================================================

출력내용

 

생성자가 호출되었습니다: 김가방
생성자가 호출되었습니다: 이치민
다시 복원합니다
이름은 김가방 : 패스워드 : null
이름은 이치민 : 패스워드 : null

-----------------------------

name 멤버변수는 그대로 복원이 되었으나,

transient로 되어있는 passwd 멤버변수는 null값이 들어있다.

 

 

 

* Externalizable

 

객체직렬화의 또 다른 방법으로는 Externalizable인터페이스를 사용하는 것입니다.

그 기본 개념은 Serializable과 같습니다.

Externalizable자체가 Serializable인터페이스를 상속한 인터페이스이기 때문입니다. 인터페이스는 인터페이스 끼리는 상속의 개념이 적용됩니다.

 

그래서 그 Externalizable의 원형은 다음과 같습니다.

 

public interface Externalizable extends Serializable {

   public void writeExternal(ObjectOutput out) throws IOException;

 

   public void readExternal(ObjectInput in) throws IOException,

                                                                             ClassNotFoundException;

}

 

Externalizable 인터페이스는 2개의 메서드를 구현해야만 사용 가능합니다.

그리고 Serializable보다 미세한 직렬화를 다루기 위해서 사용됩니다.

Serializable에서는 자동으로 데이터가 기록되지만

Externalizable에서는 기록하는 부분을 직접 제어합니다.

 

이 때 기록하는 부분은 writeExternal() 메서드에 구현을 하며

읽어내는 부분은 readExternal() 메서드에 만들어 줍니다.

writeExternal() 메서드에서 사용자가 임의로 기록하는 방법을 구현했다면

읽어내는 해답을 갖고 있는 것은 writeExternal()을 구현한 개발자 자신입니다.

거의 암호화의 개념에 가깝다.

 

 

-------------------------------------------------------------------------

ExternalObject.java

 

 

import java.io.*;

 

public class ExternalObject implements Externalizable {

 

   private int dept;               // 부서

   private String name;       // 이름

   private float duties;         // 직책

 

  public ExternalObject(){}

 

   public ExternalObject(int dept, String name, float duties) {

       this.dept = dept;

       this.name = name;

       this.duties = duties;

   }

   public void readExternal(ObjectInput in) throws IOException,

                                                                             ClassNotFoundException

{

       System.out.println("readExternal() 메서드입니다.");

       dept = in.readInt();

       name = (String)in.readObject();

       duties = in.readFloat();

   }

   public void writeExternal(ObjectOutput out) throws IOException {

       System.out.println("writeExternal() 메서드입니다.");

       out.writeInt(dept);

       out.writeObject(name);

       out.writeFloat(duties);

   }

   public String toString(){

       return dept + ":" + name + ":" + duties;

   }

}

 

 

매개변수로 넘어오는 ObjectOutput의 객체 out을 이용하여 기록하고 싶은 부분을 차례대로 write해주고 있습니다.

물론 필요로 하는 대부분의 write메서드는 이미 존재합니다.

여기서는 간단히 int, String, float만을 기록하였지만

ObjectOutput 인터페이스가 제공해주는 writeBoolean, writeByte, writeBytes, writeChar, writeChars, writeDouble, writeFloat, writeInt, writeLong, writeShort, writeUTF 메서드들을 전부 사용할 수 있습니다.

그리고, 다시 이것을 읽어 오는 부분은 기록한 차례대로 읽어오면 됩니다.

 

정확하게 순서를 맞추어 호출해 주어야 합니다.

만약 이것의 순서를 바꾼다면  에러를 만나게 될 것입니다.

그리고 마지막으로 직렬화된 데이터를 읽어들여서 객체를 만들기 위해 인자없는 생성자가 필요합니다.

이것을 만들어주지 않으면 에러메시지에서 인자없는 생성자를 요구할 것입니다

 

 

---------------------------------------------------------------------------

ExternalObjectTest.java

 

 

import java.io.*;

 

public class ExternalObjectTest {

      

   public static void main(String[] args) throws IOException, ClassNotFoundException{

 

       FileOutputStream fileout= new FileOutputStream("exTest.txt");

       ObjectOutputStream out= new ObjectOutputStream(fileout);

       ExternalObject eo1 = new ExternalObject(1, "김사양", 170.25f);

       ExternalObject eo2 = new ExternalObject(2, "이거지", 190.01f);

       ExternalObject eo3 = new ExternalObject(3, "삼다수", 180.34f);

       out.writeObject(eo1 );

       out.writeObject(eo2 );

       out.writeObject(eo3 );

       out.close();

 

       FileInputStream filein = new FileInputStream("exTest.txt");

       ObjectInputStream in = new ObjectInputStream(filein);

       ExternalObject eso1 = (ExternalObject)in.readObject();

       ExternalObject eso2 = (ExternalObject)in.readObject();

       ExternalObject eso3 = (ExternalObject)in.readObject();

       System.out.println(eso1.toString());

       System.out.println(eso2.toString());

       System.out.println(eso3.toString());

       ois.close();

   }

}

Adobe Flex 2 제품군에는 개발자가 서비스 지향 RIA(리치 인터넷 애플리케이션)를 제작 및 관리하는 방식에 대한 몇 가지 중요한 변경 사항이 적용되었습니다. Flex 패키징에 적용된 변경 사항으로 인해 서버측 구성 요소의 유무에 관계없이 Flex 애플리케이션을 제작하고 배포할 수 있지만 Flex Data Services의 여러 가지 새로운 기능을 이용하면 더욱 가치 있는 작업을 수행할 수 있습니다. 이 문서에서는 Flex Data Services 2의 새로운 기능에 대해 간단히 설명하고 특히 RPC(원격 프로시저 호출) 서비스가 Flex 1.5와 최신 버전의 Flex에서 어떻게 다른지에 대해 중점적으로 설명합니다.

Flex Data Services 2 메시징 프레임워크에는 RPC 서비스 요청을 강력하게 만드는데 도움이 되는 몇 가지 새로운 서비스 기능이 들어 있습니다. 첫째, 각 채널은 요청을 전송하기 전에 서버와 성공적으로 통신할 수 있는지를 확인합니다. 둘째, 개발자는 각 엔드포인트에 대해 여러 채널을 지정할 수 있기 때문에 보다 유연한 구성이 가능하며 첫 번째 채널을 사용할 수 없는 경우에 장애 복구가 가능합니다. 메시징 프레임워크는 클러스터된 환경도 지원하기 때문에 RPC 서비스에서 중복 환경을 활용하여 강력한 서비스를 제공할 수 있습니다.

또한 Flex Data Services 2는 애플리케이션의 관리 성능을 향상시켜 주는 다양한 기능을 제공합니다. 개발자는 서비스별 구성 파일을 통해 서비스에 대상을 추가하거나 제거할 수 있으며, 채널 엔드포인트를 구성하고, 보안 설정을 통해 서비스에 대한 액세스를 제어하고, 강력한 애플리케이션을 위한 클러스터를 정의하고, 디버깅 지원을 위한 로깅을 세밀하게 조정할 수 있습니다. 또한 개발자는 새로운 구성 형식을 통해 기술 요구 사항이 변경됨에 따라 새로운 채널, 서비스, 어댑터, 로그인 명령 및 로깅 대상을 추가할 수 있습니다.

Flex 1.5는 RemoteObject, HTTPServiceWebService MXML 태그를 통해 원격 프로시저에 비동기 호출을 보내는 세 가지 API를 제공합니다. 이러한 서비스를 RPC 서비스라고 하며 개발자는 이를 사용하여 SOA(서비스 지향 아키텍처) 애플리케이션을 구축할 수 있습니다. Flex Data Services 2는 이러한 RPC 서비스를 계속 지원하며 새로운 기능 및 새로운 프로그래밍 모델을 제공하는 두 가지 새로운 데이터 서비스를 제공합니다. 모든 서비스는 새로운 버전의 ActionScript(ActionScript 3.0)에서 제공하는 공통 메시징 아키텍처를 기반으로 합니다. 이 문서에서는 Flex 1.5와 Flex 2 간의 차이점에 대해 설명하고 Flex Data Services 2 RPC 서비스에서 이러한 향상된 기능이 어떻게 활용되는지에 대해 설명합니다.


RPC 서비스와 메시징 아키텍처

Flex 2의 새로운 메시징 아키텍처에는 RPC 서비스에 대한 몇 가지 새로운 개념이 도입되었습니다. 이 섹션에서는 Flex 1.5와의 중요한 차이점에 대해 설명하고 Flex 2에서 상응하는 기능에 대해 간단히 설명합니다.

Flex 1.5에서 개발자는 MXML 태그를 사용하여 RPC 서비스에 연결합니다. 개발자는 요청을 전송할 엔드포인트와 서비스 이름 등과 같은 몇 가지 속성을 지정합니다. Flex 1.5에서 각각의 RPC 서비스는 서로 다른 기술을 사용하기 때문에 각 서비스마다 구성 옵션과 용어가 다릅니다. 예를 들어 RemoteObject 태그는 명명된 또는 명명되지 않은 소스를 지정하고 AMF(Action Message Format) 게이트웨이에 연결하지만 HTTPServiceWebService 태그는 명명된 서비스 또는 원시 URL을 사용하고 텍스트 기반 쿼리 매개 변수 또는 XML을 사용하여 HTTP 프록시에 연결합니다.

Flex 2는 이런 모델에 몇 가지 향상된 기능을 새로 추가하여 여러 채널 간에 일관성 유지를 강화하고 개발자에게는 보다 큰 유연성을 제공합니다. 클라이언트측에서 개발자는 MXML 태그나 순수한 ActionScript API를 사용하여 서비스 연결을 선언할 수 있습니다. 연결이 클라이언트측 전용인 경우 서비스의 URI는 매개 변수로 지정됩니다. Flex Data Services를 사용하여 연결을 구성하는 경우 개발자는 원하는 서비스와 연결된 논리적 대상을 지정할 수 있습니다. 서비스란 매체를 통한 웹 서비스 호출이나 메시징 통합 등과 같은 다양한 고유 기능을 나타냅니다. 서버측에서 모든 대상은 구성 파일을 통해 구성됩니다. 대상에는 대상이 연결되는 엔드포인트에 대한 정보, 통신에 사용되는 채널, 모든 연결에 사용되는 다양한 메시징 옵션이 포함됩니다. 채널이란 일반적으로 채널에 폴링 사용 여부 및 원하는 폴링 간격 등과 같은 몇 가지 옵션과 프로토콜을 지정하는 통신 메커니즘을 나타냅니다.

제공된 다양한 서비스와의 모든 통신은 메시지를 적절한 서비스로 연결하는 공통 메시지 브로커에 의해 중재됩니다. 메시지 브로커는 메시지 유형과 선택한 대상을 사용하여 적합한 서비스를 선택하고 서비스에서 메시지를 처리할 수 있도록 합니다. RemoteObject 메시지는 Remoting Service로 라우팅되고 HTTPServiceWebService 메시지는 Proxy Service로 라우팅됩니다. 표 1에서는 Flex 1.5의 서비스 개념과 Flex Data Services 2의 서비스 개념을 비교해서 보여줍니다.

표 1. Flex 1.5와 Flex Data Services 2의 개념 비교
Flex 1.5 서비스 개념 Flex Data Services 2 서비스 개념

명명된 서비스 및 명명되지 않은 서비스

Flex 1.5에서 개발자는 주로 서비스에 이름을 제공하여 앨리어스 역할을 수행하도록 하지만 클라이언트에서도 명명되지 않은 방식으로 서비스의 세부 정보(예: 타사 URL이나 객체의 소스)를 제공할 수 있습니다.

대상

대 상은 Flex 1.5의 명명된 서비스에 해당합니다. 이제 서비스란 용어는 포괄적인 기능을 나타내며, 대상은 궁극적인 엔드포인트를 나타냅니다. 모든 요청은 관련 서비스(Remoting Service, Proxy Service, Message Service 및 Data Service)의 대상으로 전송되어야 합니다.

프록시

HTTPServiceWebService 요청에 대한 목표 엔드포인트는 일반적으로 원격 타사 서비스입니다. 하지만 Flash® Player의 보안 샌드박스는 애플리케이션이 로드된 도메인으로 요청을 제한합니다. Flex 1.5에서는 각각의 원격 사이트에서 crossdomain.xml 정책 파일을 요청하지 않도록 하기 위해서 요청을 적합한 엔드포인트로 중계할 수 있는 내장 Proxy Servlet이 제공되었습니다.

Proxy Service

HTTPServiceWebService에서는 메시지 브로커를 사용하여 Proxy Service를 통해 요청을 중계하지만 보안 샌드박스 제한은 여전히 모든 서비스에 적용됩니다.

Proxy Service는 더 이상 기본값으로 사용되지 않으며, useProxy 속성의 기본값은 false입니다. useProxyfalse로 설정된 경우 메시지 브로커는 연결되지 않고 destination 속성이 사용되지 않습니다. 대신 개발자는 HTTPService 태그에 대한 url 속성을 설정하거나 WebService 태그에 대한 wsdl 속성을 지정해야 합니다. 개발자는 특별한 직접 채널을 선택하여 타사 엔드포인트에 대한 비메시징 기반 요청을 만듭니다.

프록시를 사용하려면 개발자는 HTTPService 또는 WebService에서 useProxytrue로 설정해야 합니다. HTTPService 또는 WebService에서 대상을 설정하면 useProxy가 자동으로 true로 설정됩니다.

Proxy Service를 사용할 때는 모든 채널에서 요청을 만들 수 있습니다. 채널은 메시지 브로커에 엔드포인트로 등록됩니다. HTTP 기반 채널은 메시지를 메시지 브로커 서블릿으로 전송합니다. RTMP(Real Time Message Protocol) 기반의 채널은 메시지를 전용 TCP/IP 포트로 전송합니다. 메시지 브로커는 이러한 포트에서 수신 대기 중인 소켓을 관리합니다.

AMF 게이트웨이

RemoteObject 요청에 대한 엔드포인트는 AMF 게이트웨이 서블릿입니다.

Remoting Service

RemoteObject에 대한 전용 채널은 없습니다. Remoting Service에 대한 요청은 모든 채널에서 만들 수 있습니다.


RPC 서비스 구성

Flex 1.5에서 컴파일러 및 런타임 서비스에 대한 구성 설정은 단일 구성 파일인 flex-config.xml에 포함되어 있습니다. 이 구성 파일에서는 RemoteObject 태그에 대한 <remote-objects>, WebService 태그에 대한 <web-service-proxy>HTTPService 태그에 대한 <http-service-proxy> 등의 세 가지 섹션이 RPC 서비스에 사용됩니다. Flex는 컴파일 시에 서비스 구성 정보를 사용하여 MXML 태그에 대한 코드 및 태그 속성의 유효성 검사를 위한 코드를 생성합니다. 다음 샘플에서는 Flex 1.5 구성 파일인 flex-config.xml의 구조를 보여줍니다.

 <flex-config>
<debugging />
<compiler />
<cache />
<flash-player />
<web-service-proxy />
<http-service-proxy />
<remote-objects />
<logging />
<fonts />
</flex-config>

Flex 1.5 AMF 게이트웨이에는 자체 구성 파일인 gateway-config.xml도 있습니다. 개발자는 이 파일을 사용하여 RemoteObject 요청을 처리하는 서비스 어댑터, 사용자 정의 서비스 보안을 위한 로그인 명령 등을 포함하여 몇 가지 기능을 사용자 정의할 수 있습니다. 다음의 코드에서는 Flex 1.5 RemoteObject 구성 파일인 gateway-config.xml의 구조를 보여줍니다.

 <gateway-config>
<service-adapters />
<logger />
<security />
<serialization />
<translator />
<redirect-url />
<lowercase-keys />
</gateway-config>

Flex Data Services 2에서는 별개의 구성 파일인 services-config.xml에 서비스 관련 구성 정보가 저장됩니다. Flex 1.5에서 서비스와 관련된 세 가지 섹션이 flex-config.xml에서 제거되었습니다. 그러나 컴파일러 특정 구성 설정은 이 파일에 그대로 유지됩니다. 캐싱 및 Flash Player 감지 등과 같은 기타 웹 계층 구성 설정은 flex-server-config.xml 파일에 저장됩니다. Flex 1.5 gateway-config.xml 파일은 더 이상 사용되지 않습니다. 새로운 공통 services-config.xml 파일은 모든 관련 게이트웨이 기능을 포함하며 설정을 모든 서비스에 적용합니다.

개발자는 services-config.xml 구성 파일을 사용하여 외부 파일로부터 개별적인 서비스 정의를 포함시킬 수 있습니다. 따라서 서비스 특정 대상을 격리시키고 기본 서비스 구성 파일의 크기를 줄일 수 있게 되며 결과적으로 보안, 채널 및 로깅 설정 등과 같은 공통 섹션에 쉽게 액세스할 수 있습니다. 다음 샘플에서는 각 서비스가 개별적인 include 파일에 포함되어 있는 Flex Data Services 2 구성 파일인 services-config.xml의 일반적인 구조를 보여줍니다.

 <services-config>
<services>
<service-include file-path="remoting-service.xml" />
<service-include file-path="proxy-service.xml" />
</services>
<security />
<channels />
<clusters />
<logging />
<system />
</services-config>

Flex 애플리케이션에서 Flex Data Services가 사용되는 경우 컴파일 시에 services-config.xml 구성 파일이 필요합니다. RPC 서비스의 경우에 이것은 RemoteObject나 프록시 기반 WebService 또는 HTTPService를 사용하는 모든 애플리케이션에 적용되는 사항입니다.

mxmlc 컴파일러는 flex-config.xml 파일 또는 명령줄 스위치를 사용하여 서비스 구성 파일을 지정할 수 있습니다. 각 서비스 대상에 대해 사용할 채널을 클라이언트에 알려주는 코드를 생성해야 하기 때문에 컴파일 시에 서비스 구성 정보가 반드시 필요합니다. 다음 구성 코드는 flex-config.xml을 사용하여 mxmlc 컴파일러를 Flex Data Services 2 구성 파일에 지정합니다.

 <flex-config>
<compiler>
<services>
services-config.xml
</services>
...
</compiler>
</services-config>

다음 구성 코드는 명령줄을 사용하여 mxmlc 컴파일러를 Flex Data Services 2 구성 파일에 지정합니다.

   mxmlc --load-config=flex-config.xml --services=services-config.xml MyApp.mxml

표 2에서는 Flex 1.5와 Flex Data Services 2의 구성상 차이점을 보여줍니다.

Flex 1.5와 Flex Data Services 2의에서 구성상의 차이점

Flex 1.5 서비스 구성

게이트웨이 URL 및 프록시 URL

다음에 대한 flex-config.xml의 사용:

  • HTTPService, WebService

{context.root}/flashproxy

  • RemoteObject

mxmlc 명령줄 스위치

  • HTTPService, WebService

-proxyurl=/myapp/flashproxy

  • RemoteObject

-gatewayurl=/myapp/amfgateway

Flex Data Services 2 서비스 구성

채널

서 비스는 모든 채널 엔드포인트를 사용하여 메시지를 처리합니다. 서비스 특정 엔드포인트 설정은 필수가 아니며 대신 개발자가 새 채널을 만들 수 있습니다. 채널은 서비스 구성 파일인 services-config.xml에 정의되어야 하며, 채널은 서비스와 독립적으로 정의됩니다.

<channel-definition id="my-amf" ...>
<endpoint uri="http://www.abc.com/messagebroker/amf" ... />
</channel-definition>

한 서비스에 대해 다음과 같은 기본 채널 집합을 설정할 수 있습니다.

 <service id="remoting-service" ...>
...
<default-channels>
<channel ref="my-amf"/>
</default-channels>
...
</service>

또한 대상은 고유 채널 목록을 지정하여 해당 서비스의 기본값을 무시할 수 있습니다.

 <destination id="MyManager">
<channels>
<channel ref="my-amf"/>
</channels>
...
</destination>

개별 채널은 명령줄에 지정할 수 없습니다. 그러나 mxmlc 명령줄 스위치를 통해 컴파일러를 완전한 서비스 구성 파일에 지정할 수 있습니다.

   --services=/flex/services-config.xml

Flex 1.5 서비스 구성

서비스 화이트 리스트

화이트 리스트는 클라이언트에 사용할 수 있는 서비스를 제한하는 데 사용됩니다.

HTTPServiceWebService 서비스는 궁극적인 타사 엔드포인트의 URL을 기반으로 화이트 리스트에 지정할 수 있습니다.

 <whitelist>
<unnamed>
<url>
http://www1.abc.com/*
</url>
<url>
https://www1.abc.com/*
</url>
</unnamed>
<named>
<service name="MyManager">
<url>
http://www.abc.com/mysvc/10/
</url>
</service>
</named>
</whitelist>

RemoteObject 객체는 원격 객체의 기본 소스를 기반으로 화이트 리스트에 지정할 수 있습니다.

 <whitelist>
<unnamed>
<source>*</source>
</unnamed>
<named>
<object name="WeatherService">
<source>
samples.WeatherService
</source>
<type>stateless-class</type>
</object>
</named>
</whitelist>

Flex Data Services 2 서비스 구성

서비스 대상

서비스에 대상을 추가하는 작업은 화이트 리스트에 어떤 항목을 추가하는 것과 같습니다.

Proxy Service 대상은 URL 패턴과 SOAP 엔드포인트를 지정하여 Flex 1.5의 명명되지 않은 서비스에 동일한 기능을 제공할 수 있습니다. 서비스의 기본 URL은 url 속성에 정의됩니다. 동적 또는 클라이언트 제공 URL은 dynamic-url 속성에 정의됩니다.

 <destination id="flickr">
<properties>
<url>
http://www.abc.com/mysvc/10/
</url>
<dynamic-url>
http://www1.abc.com/*
</dynamic-url>
<dynamic-url>
https://www1.abc.com/*
</dynamic-url>
</properties>
</destination>

defaultHttpdefaultHttps 대상이 Proxy Service에 대해 구성되어 있으므로 개발자는 대상을 지정하지 않고도 HTTPServiceWebService 태그를 사용할 수 있습니다. 하지만 defaultHttp 대상을 사용하는 HTTP 기반 URL과 defaultHttps를 사용하는 HTTPS 기반 URL을 사용하는 기본 대상에 대해서는 dynamic-url을 구성해야 합니다.

Java 어댑터를 사용하는 Remoting Service 대상은 더 이상 클라이언트에 소스를 지정할 수 없습니다. 개발자는 서버에서 각 Java 소스에 대해 고유한 대상을 등록해야 합니다.

 <destination id="WeatherService">
<properties>
<source>
samples.WeatherService
</source>
<stateful>false</stateful>
</properties>
</destination>

Flex 1.5 서비스 구성

프록시 및 AMF 게이트웨이 로깅

Flex 1.5에서 개발자는 서버의 gateway-config.xml 파일에서 로깅 설정을 수정하여 AMF 요청을 디버깅할 수 있습니다. 프록시 요청은 웹 계층 컴파일러에서 사용되는 기본 flex-config.xml 파일에서 로깅 설정을 수정하여 디버깅할 수 있습니다.

Flex Data Services 2 서비스 구성

로깅

메시지 브로커는 모든 서비스에 대한 통합 로깅 시스템을 갖고 있습니다. 개발자는 services-config.xml의 로깅 섹션을 이용하여 로깅 수준을 사용자 정의하고 정보를 특정 범주로 제한할 수 있습니다.

Flex 1.5 서비스 구성

클라이언트 로깅

Flex 1.5에서 개발자는 flex-config.xml의 디버깅 섹션에서 http-service-proxy-debug, web-service-proxy-debug 또는 remote-object-debug 설정을 true로 설정하여 클라이언트에서 서비스 요청을 디버깅할 수 있습니다. 개발자는 Flex Builder™ Network Monitor, Flash Remoting NetConnection Debugger 및 사용자 디렉토리에 있는 flashlog.txt 파일에 저장된 추적 정보의 디버깅 Flash Player 출력을 사용하여 클라이언트 로깅 정보를 확인할 수 있습니다.

Flex Data Services 2 서비스 구성

클라이언트 로깅 API 및 로그 대상

Flex 2의 mx.logging 패키지에는 새로운 클라이언트 로깅 라이브러리가 포함되어 있습니다. 모든 서비스는 이 클라이언트 로깅 API를 사용하여 정보를 보고합니다. 개발자는 로그 이벤트의 수준을 지정하고 이벤트의 범주를 필터링할 수 있습니다. 개발자는 로깅 대상을 활성화하여 특정 위치에 있는 정보를 볼 수 있습니다. 가장 일반적으로 사용되는 대상은 TraceTarget(mx.logging.targets 패키지)이며, 이 대상은 trace() 함수를 사용하여 정보를 보고합니다. Flash Player의 디버깅 버전은 추적 정보를 사용자 디렉토리에 있는 flashlog.txt 파일로 출력합니다.


Flex 1.5 서비스 구성

프록시 및 AMF 게이트웨이 로깅

Flex 1.5에서 개발자는 서버의 gateway-config.xml 파일에서 로깅 설정을 수정하여 AMF 요청을 디버깅할 수 있습니다. 프록시 요청은 웹 계층 컴파일러에서 사용되는 기본 flex-config.xml 파일에서 로깅 설정을 수정하여 디버깅할 수 있습니다.

Flex Data Services 2 서비스 구성

로깅

메시지 브로커는 모든 서비스에 대한 통합 로깅 시스템을 갖고 있습니다. 개발자는 services-config.xml의 로깅 섹션을 이용하여 로깅 수준을 사용자 정의하고 정보를 특정 범주로 제한할 수 있습니다.

Flex 1.5 서비스 구성

클라이언트 로깅

Flex 1.5에서 개발자는 flex-config.xml의 디버깅 섹션에서 http-service-proxy-debug, web-service-proxy-debug 또는 remote-object-debug 설정을 true로 설정하여 클라이언트에서 서비스 요청을 디버깅할 수 있습니다. 개발자는 Flex Builder™ Network Monitor, Flash Remoting NetConnection Debugger 및 사용자 디렉토리에 있는 flashlog.txt 파일에 저장된 추적 정보의 디버깅 Flash Player 출력을 사용하여 클라이언트 로깅 정보를 확인할 수 있습니다.

Flex Data Services 2 서비스 구성

클라이언트 로깅 API 및 로그 대상

Flex 2의 mx.logging 패키지에는 새로운 클라이언트 로깅 라이브러리가 포함되어 있습니다. 모든 서비스는 이 클라이언트 로깅 API를 사용하여 정보를 보고합니다. 개발자는 로그 이벤트의 수준을 지정하고 이벤트의 범주를 필터링할 수 있습니다. 개발자는 로깅 대상을 활성화하여 특정 위치에 있는 정보를 볼 수 있습니다. 가장 일반적으로 사용되는 대상은 TraceTarget(mx.logging.targets 패키지)이며, 이 대상은 trace() 함수를 사용하여 정보를 보고합니다. Flash Player의 디버깅 버전은 추적 정보를 사용자 디렉토리에 있는 flashlog.txt 파일로 출력합니다.


RPC 서비스 MXML API에 대한 변경 사항

Flex 2의 RPC 서비스 API는 기본적으로 Flex 1.5와 같습니다. 그러나 공통 메시징 아키텍처를 이용하게 됨으로써 서비스 통신 및 명명 규칙과 관련된 몇 가지 속성에 변경 사항이 있습니다. 표 3에서는 Flex 1.5에서 Flex Data Services 2로 버전업되면서 MXML API에 어떤 변경 사항이 있는지를 간단히 보여줍니다.

표 3. Flex 1.5에서 Flex Data Services 2로 버전업되면서 MXML API에 적용된 변경 사항 개요
Flex 1.5 MXML API Flex Data Services 2 MXML API

mx:RemoteObject

  • source 속성은 명명되지 않은 원격 객체에서 사용됩니다. 이 속성은 화이트 리스트 구성에서 명명된 객체를 등록하지 않고 RemoteObject에 대한 동적 소스 이름을 정의합니다.
  • named 속성은 명명된 원격 객체에서 사용됩니다. 이 속성은 등록된 객체 소스에 앨리어스를 제공합니다.
  • protocol 속성은 AMF 게이트웨이에 연결할 때 HTTP와 HTTPS 중 어떤 프로토콜을 사용할지를 결정합니다.
  • 개발자는 endpoint 속성을 사용하여 AMF 게이트웨이의 사용자 정의 위치를 지정할 수 있습니다.

mx:RemoteObject

  • source 속성은 Remoting Service Java Adapter에 의해 무시됩니다. ColdFusion은 CFC 어댑터에서 클라이언트 지정 소스를 지원합니다.
  • named 속성은 더 이상 사용되지 않으며 대신 destination 속성을 사용해야 합니다.
  • protocol 속성은 지원되지 않습니다. 메시지 브로커에 연결하는 데 사용되는 프로토콜은 대상에 대해 선택된 채널에 따라 달라집니다.
  • endpoint 속성은 RemoteObject의 MXML API에 대해서만 지원됩니다. Flex 2에서는 개발자가 이 속성을 사용하여 컴파일 시에 서비스 구성 파일을 참조하거나 ChannelSet을 프로그래밍 방식으로 만들지 않고도 RemoteObject 대상의 엔드포인트를 신속하게 지정할 수 있습니다. 또한 RemoteObject 서비스에 이미 ChannelSet이 설정되어 있는 경우 기존 ChannelSet을 무시합니다. endpoint 속성은 Flex Data Services 2 또는 ColdFusion 7.0.2와 같이 Flex 2와 호환되는 엔드포인트여야 합니다. 엔드포인트 URL이 https로 시작하는 경우 SecureAMFChannel이 사용되고, 그렇지 않으면 AMFChannel이 사용됩니다.

mx:WebService

mx:HTTPService

  • protocol 속성은 프록시 또는 타사 엔드포인트에 연결할 때 HTTP와 HTTPS 중 어떤 프로토콜을 사용할지를 결정합니다.
  • serviceName 속성은 명명된 프록시 웹 서비스에서 사용됩니다.

모든 서비스

개발자는 WebService 또는 RemoteObject 작업이나 HTTPService 호출에 대한 result 속성을 사용하여 서비스에서 반환된 마지막 결과에 바인딩할 수 있습니다.

mx:WebService

mx:HTTPService

  • protocol 속성은 지원되지 않습니다. 메시지 브로커에 연결하는 데 사용되는 프로토콜은 대상에 대해 선택된 채널에 따라 달라집니다.
  • serviceName 속성은 더 이상 사용되지 않으며 대신 destination 속성을 사용해야 합니다.

모든 RPC 서비스

개발자가 결과 이벤트 핸들러를 지정할 수 있게 해주는 MXML result 이벤트 속성과 이름 충돌이 발생하지 않도록 WebService 또는 RemoteObject 작업이나 HTTPService 호출에 대한 result 속성 이름이 lastResult로 변경되었습니다.


RPC 서비스에서 채널 사용

채널은 클라이언트의 메시지를 메시지 브로커의 엔드포인트로 전달하는 역할을 수행합니다. 메시지를 전달하는 데 사용되는 프로토콜은 채널에 따라 다릅니다. 또한 채널은 ActionScript 3.0을 사용하는 Flex 애플리케이션에서 사용되는 유형인 클라이언트의 데이터 유형을 지원할 수 있어야 합니다. 채널은 요청을 직렬화(serialize)하고 응답을 역직렬화(deserialize)하는 클라이언트 구현과 요청을 역직렬화하고 응답을 직렬화하는 엔드포인트에서의 서버 구현으로 구성됩니다. Flex Data Services 2에는 서비스 기반 애플리케이션의 다양한 요구 사항을 지원하기 위한 몇 가지 채널이 제공됩니다.

  • AMF 채널: AMF는 ActionScript 객체를 효율적으로 직렬화하기 위해 사용되는 바이너리 메시지 형식입니다. AMFChannel은 Flash Player용 flash.net.NetConnection 클래스를 사용하여 HTTP를 통해 AMF 형식의 메시지를 AMFEndpoint로 비동기적으로 전송합니다. Flash Player 8.5에서는 AMF 3으로 알려진 새로운 버전의 AMF를 도입하여 새로운 ActionScript 3.0 언어를 제공하지만 이전 버전인 AMF 0도 계속 지원됩니다. 새로운 ActionScript 3 데이터 유형에 대한 지원 외에도 AMF 3에서는 공통적으로 발생하는 클래스 설명과 참조 문자열을 직렬화하여 보다 간결한 인코딩 형식을 사용하고 중복된 정보를 줄입니다. NetConnection(및 AMFChannel)은 기본적으로 AMF 3을 사용합니다. AMFChannel은 HTTP를 통한 바이너리 정보 사용이 가능하고 보안을 위해 암호화 기능을 사용할 필요가 없는 환경에서 모든 RPC 서비스에 대해 권장되는 채널입니다.
  • 보안 AMF 채널: 이 채널은 AMFChannel와 동일하지만 HTTPS를 사용하여 AMF 형식의 메시지를 AMFEndpoint로 전송하는 점이 다릅니다.
  • RTMP 채널: RTMP 도 AMF를 사용하여 ActionScript 객체를 직렬화하지만 RTMPEndpoint와의 영구적인 연결을 유지 관리하고 실시간 통신이 가능합니다. RPC 서비스는 단일 클라이언트/서버 요청/응답 모델을 사용하여 비동기적으로 만들어지기 때문에 실시간 통신은 필요하지 않습니다.
  • HTTP 채널: 이 채널은 flash.net.URLLoader를 사용하여 XML 형식의 메시지를 HTTP를 통해 HTTPEndpoint로 비동기적으로 전송하는 텍스트 기반 채널입니다. XML 형식은 강력한 형식의 ActionScript 3.0 데이터를 지원하며 공통적으로 발생하는 객체, 클래스 정의 및 문자열에 대한 참조별 직렬화와 같은 AMF 3의 다양한 최적화 기술을 포함합니다. 이 채널은 텍스트 전용 통신 요구 사항이 있는 환경에서 유용합니다.

    참고: flash.utils.IExternalizable 인터페이스는 아직 HTTPChannel에서 완전히 지원되지 않습니다. 따라서 객체 참조를 복구할 필요가 있는 mx.utils.ObjectProxymx.collections.ArrayCollection 인스턴스는 이 채널을 사용하여 직렬화하면 안 됩니다.

  • Secure HTTP 채널: 이 채널은 HTTPChannel 클래스와 동일하지만 HTTPS를 사용하여 메시지를 HTTPEndpoint에 전송한다는 점이 다릅니다.

ActionScript 3.0 데이터 유형 및 직렬화(serialization)

Flex 2 및 ActionScript 3.0에는 RemoteObject 및 Remoting Service를 사용하는 개발자에게 유용한 몇 가지 새로운 데이터 유형(Flex 애플리케이션에서 사용할 수 있는 데이터 유형)이 포함되어 있습니다.

XML

ActionScript 3.0에는 E4X 구문을 지원하는 새로운 내장 XML 데이터 유형이 포함되어 있습니다. 이러한 API는 매우 강력하고 유용한 기능을 제공합니다. flash.xml 패키지에서는 ActionScript 2에서 제공되는 기존의 XMLDocumentXMLNode 클래스도 사용할 수 있습니다. 클라이언트 XMLflash.xml.XMLDocument 인스턴스는 모두 Java org.w3c.dom.Document 인스턴스와 같은 메시지 엔드포인트에 의해 역직렬화됩니다. org.w3c.dom.Document의 서버 인스턴스는 새로운 XML 데이터 유형의 인스턴스로 클라이언트에서 역직렬화됩니다. 그러므로 개발자는 서버를 통해 왕복하는 객체의 경우 모든 flash.xml.XMLDocument 데이터가 XML로 반환된다는 점에 주의해야 합니다.

강력한 형식의 객체

Flex 1.5에서 사용자는 Object.registerClass를 사용하여 사용자 정의 클라이언트 및 서버 데이터 유형을 매핑했습니다. ActionScript 3.0에서 이 기능은 flash.net.registerClassAlias로 변경되었습니다. 이 API는 클라이언트 클래스에 대해 앨리어스를 등록합니다. 그러면 클래스의 인스턴스가 직렬화될 때 앨리어스가 포함됩니다. 등록된 앨리어스가 없는 경우 인스턴스는 익명 객체로 전송됩니다. 또한 앨리어스를 사용하면 클라이언트에서 클라이언트 클래스를 다른 이름의 서버 클래스로 매핑할 수도 있습니다. 하지만 개발자는 혼란을 피하기 위해 동일한 이름을 사용하는 것이 가장 좋습니다. 인스턴스가 올바르게 역직렬화되도록 하려면 인스턴스가 서버에 전송되거나 클라이언트에서 수신되기 전에 클라이언트 클래스 앨리어스를 등록해야 합니다.

Flex 2 MXML 컴파일러에는 클래스의 느슨한 초기화(lazy-initialization) 및 종속성 기반 링커(linker)와 같은 몇 가지 최적화 기술이 포함되어 있습니다. 여기서 registerClassAlias에 대한 호출은 데이터 요청이 발생하기 전에 수행되어야 하며, 클라이언트 클래스에 대한 종속성은 컴파일된 애플리케이션에 연결되도록 코드에 작성되어야 합니다. 이러한 프로세스를 보다 쉽게 수행할 수 있도록 mxmlc 컴파일러에는 RPC 서비스에서 클래스를 즉시 사용할 수 있도록 보장하는 특별한 [RemoteClass] 메타데이터 태그에 대한 지원이 포함되어 있습니다. ActionScript 3.0 구문의 다음 코드에서는 Flex 2 애플리케이션에서 원격 클래스를 매핑합니다.

   package com.mycompany
{

[RemoteClass(alias="com.mycompany.Employee")]
public class Employee
{

}

}

Number, int 및 uint

ActionScript 3.0에서는 배정밀도 부동 소수점 Number 유형(int(부호 있는 정수) 및 uint(부 호 없는 정수)) 외에도 두 가지 새로운 정수 유형이 제공됩니다. 새로운 AVM+(ActionScript Virtual Machine)는 정수를 가변 길이로 인코딩된 29비트 정수로 보관하며, 더 큰 정수 값은 Number를 사용하여 보관합니다. intuint 유형은 서버에서 java.lang.Integer를 사용하여 역직렬화됩니다. Number는 서버에서 계속해서 java.lang.Double로 역직렬화됩니다. Remoting Service의 Java 어댑터는 메서드를 호출하고 강력한 형식의 인스턴스를 호출할 때 느슨한 유형의 마샬링(marshalling) 규칙을 사용하기 때문에 모든 숫자는 사용자의 API에 필요한 형식으로 올바르게 캐스팅됩니다.

사용자 정의 직렬화 및 flash.utils.IExternalizable

ActionScript 3.0에는 개발자가 자신만의 강력한 형식의 클래스에 대한 직렬화를 제어할 수 있게 해주는 새로운 인터페이스가 포함되어 있습니다. flash.utils.IExternalizable을 구현하는 인스턴스는 readExternalwriteExternal 메서드의 구현에 따라 직렬화됩니다. 클라이언트 클래스는 등록된 앨리어스가 있어야 하며, 해당 서버 클래스는 인스턴스를 역직렬화하는 데 사용할 수 있어야 합니다. 이 유형에 대한 직렬화 형식은 완전히 사용자 정의가 가능하기 때문에 직렬화를 올바르게 수행하기 위해 서버 클래스를 사용할 수 있어야 합니다.

데이터 바인딩 및 MXML 구성 요소

서 비스가 Flex 2 구성 요소에 데이터 공급자로 참여하기 위해서는 데이터 유형이 올바른 이벤트로 전달되어 데이터 바인딩과 변경 사항의 전달을 지원해야 합니다. 따라서 데이터 바인딩을 쉽게 수행하도록 데이터 유형 직렬화 규칙이 일부 변경되었습니다.

<mx:Model/>

MXML Model 태그를 사용하면 일반 객체 속성을 사용하여 데이터 바인딩 작업을 수행할 수 있습니다. Model 태그는 서버에서 java.util.HashMap으로 역직렬화되는 ActionScript 유형인 mx.utils.ObjectProxy로 지원됩니다.

참고: mx.utils.ObjectProxy 클래스는 flash.utils.IExternalizable을 구현하므로 이 유형은 아직 HTTPChannel 클래스에 의해 완전히 지원되지 않습니다. 다른 유형과 IExternalizable 유형의 컨텐츠 사이에서 객체 참조는 유지되지 않습니다.

mx.collections.ArrayCollection

컬 렉션은 Flex 2에서 포괄적으로 사용됩니다. 컬렉션은 컬렉션 구조의 변경 사항이 Flex 구성 요소(특히 UI 구성 요소)에 반영되고 구성 요소의 변경 사항이 컬렉션 구조에 반영될 수 있도록 배열이 올바른 이벤트로 전달될 수 있는 이벤트 프레임워크를 제공합니다. 이제 Flex Data Services는 클라이언트 mx.collections.ArrayCollection 인스턴스를 서버의 java.util.ArrayList로 매핑하고 서버측 java.util.Collection 구현은 클라이언트의 mx.collections.ArrayCollection으로 매핑합니다. 서버로부터의 응답에 원시 클라이언트 Array가 필요한 경우 원시 Java 배열(예: java.lang.Object[])을 반환할 수 있습니다. 또한 클라이언트 ActionScript Arrays는 서버에서 원시 java.lang.Object[] 배열로 역직렬화됩니다.

참고: mx.collections.ArrayCollectionflash.utils.IExternalizable을 구현합니다. 여기서 이 유형은 아직 HTTPChannel 클래스에 의해 완전히 지원되지 않습니다. 다른 유형과 IExternalizable 유형의 컨텐츠 사이에 객체 참조는 유지되지 않습니다.


Number, int 및 uint

ActionScript 3.0에서는 배정밀도 부동 소수점 Number 유형(int(부호 있는 정수) 및 uint(부 호 없는 정수)) 외에도 두 가지 새로운 정수 유형이 제공됩니다. 새로운 AVM+(ActionScript Virtual Machine)는 정수를 가변 길이로 인코딩된 29비트 정수로 보관하며, 더 큰 정수 값은 Number를 사용하여 보관합니다. intuint 유형은 서버에서 java.lang.Integer를 사용하여 역직렬화됩니다. Number는 서버에서 계속해서 java.lang.Double로 역직렬화됩니다. Remoting Service의 Java 어댑터는 메서드를 호출하고 강력한 형식의 인스턴스를 호출할 때 느슨한 유형의 마샬링(marshalling) 규칙을 사용하기 때문에 모든 숫자는 사용자의 API에 필요한 형식으로 올바르게 캐스팅됩니다.

사용자 정의 직렬화 및 flash.utils.IExternalizable

ActionScript 3.0에는 개발자가 자신만의 강력한 형식의 클래스에 대한 직렬화를 제어할 수 있게 해주는 새로운 인터페이스가 포함되어 있습니다. flash.utils.IExternalizable을 구현하는 인스턴스는 readExternalwriteExternal 메서드의 구현에 따라 직렬화됩니다. 클라이언트 클래스는 등록된 앨리어스가 있어야 하며, 해당 서버 클래스는 인스턴스를 역직렬화하는 데 사용할 수 있어야 합니다. 이 유형에 대한 직렬화 형식은 완전히 사용자 정의가 가능하기 때문에 직렬화를 올바르게 수행하기 위해 서버 클래스를 사용할 수 있어야 합니다.

데이터 바인딩 및 MXML 구성 요소

서 비스가 Flex 2 구성 요소에 데이터 공급자로 참여하기 위해서는 데이터 유형이 올바른 이벤트로 전달되어 데이터 바인딩과 변경 사항의 전달을 지원해야 합니다. 따라서 데이터 바인딩을 쉽게 수행하도록 데이터 유형 직렬화 규칙이 일부 변경되었습니다.

<mx:Model/>

MXML Model 태그를 사용하면 일반 객체 속성을 사용하여 데이터 바인딩 작업을 수행할 수 있습니다. Model 태그는 서버에서 java.util.HashMap으로 역직렬화되는 ActionScript 유형인 mx.utils.ObjectProxy로 지원됩니다.

참고: mx.utils.ObjectProxy 클래스는 flash.utils.IExternalizable을 구현하므로 이 유형은 아직 HTTPChannel 클래스에 의해 완전히 지원되지 않습니다. 다른 유형과 IExternalizable 유형의 컨텐츠 사이에서 객체 참조는 유지되지 않습니다.

mx.collections.ArrayCollection

컬 렉션은 Flex 2에서 포괄적으로 사용됩니다. 컬렉션은 컬렉션 구조의 변경 사항이 Flex 구성 요소(특히 UI 구성 요소)에 반영되고 구성 요소의 변경 사항이 컬렉션 구조에 반영될 수 있도록 배열이 올바른 이벤트로 전달될 수 있는 이벤트 프레임워크를 제공합니다. 이제 Flex Data Services는 클라이언트 mx.collections.ArrayCollection 인스턴스를 서버의 java.util.ArrayList로 매핑하고 서버측 java.util.Collection 구현은 클라이언트의 mx.collections.ArrayCollection으로 매핑합니다. 서버로부터의 응답에 원시 클라이언트 Array가 필요한 경우 원시 Java 배열(예: java.lang.Object[])을 반환할 수 있습니다. 또한 클라이언트 ActionScript Arrays는 서버에서 원시 java.lang.Object[] 배열로 역직렬화됩니다.

참고: mx.collections.ArrayCollectionflash.utils.IExternalizable을 구현합니다. 여기서 이 유형은 아직 HTTPChannel 클래스에 의해 완전히 지원되지 않습니다. 다른 유형과 IExternalizable 유형의 컨텐츠 사이에 객체 참조는 유지되지 않습니다.


출처 : http://www.adobe.com/kr/devnet/flex/articles/rpc_service.html

================================================
ニッシンのSEAFOOD NOODLEは おいしいですよ。
================================================
友達(ともだち)の勧(すす)めでインターネットで購入(こうにゅう )したラーメンが今日到着(とうちゃく)した。
ニッシンのSEAFOOD NOODLEだが、豚肉(ぶたにく)の汁(じゅう)が本当においしかった。
流通期限(りゅうつうきげん)が2週間くらい残って価格(かかく)も1000ウォン!もちろん、商品に問題はなかったよ。
10個(こ)かっだんですけど, もう5個食べ、半分(はんぶん)になって むねが痛いたみですよ。
今後(こんご)日本の他(た)のインスタント食品(しょくひん)を食べて見るべきだろう。
================================================
知らない 單語
================================================
勧(すす)め 권유, 권고
購入(こうにゅう) 구입
豚肉(ぶたにく) 돼지고기
汁(じゅう) 즙, 액체, 국물
流通(りゅうつう) 유통
期限(きげん) 기한
価格(かかく) 가격, 값
半分(はんぶん) 절반
むねが痛(いた)む 가슴이 아프다. 몹시 슬프다.
今後(こんご) 차후, 이후, 나중에
食品(しょくひん) 식품
べき  ~하는 것이 당연하다 ~하는 것이 올바르다
だろ-う  말하는 이의 추량·의문 등을 나타냄. …할 것이다. …하겠지.
================================================

'etc > old' 카테고리의 다른 글

객체 직렬화(Serializable)  (0) 2008.05.29
Flex Data Services 2에서 RPC 서비스 사용  (0) 2008.05.28
mysql에서 쿼리 사용방법  (0) 2008.05.28
문자열 형변환 예시  (0) 2008.05.27
携帯電話は必要悪(ひつようあく)だ  (0) 2008.05.27

* 질의 실행
mysql> source [파일명]
mysql> source /hosting/backup.sql

이 명령어는 외부에 있는 쿼리(파일)을 실행하는 명령어 입니다.
해당 파일안에는 쿼리문이 들어있어야 합니다.
이 명령어는 쉘상에서 사용하는 mysql ........... < [파일명] 과 같은 결과 입니다.

파일명을 쓸때에는 경로와 함께 적을 수 있으며, 따옴표를 사용하지 않는점을 주의하십시요

* 쉘프롬프트상에서
mysql -u 사용자 -p DB명 < 질의파일

* 프롬프트상에서 질의 실행
mysql mysql -u root -pxxxx -e
> "INSERT INTO db VALUES(
> 'localhost', 'aaa', 'aaa',
> 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y')"

출처는 : 지식인 검색
http://kin.naver.com/detail/detail.php?d1id=1&dir_id=10110&eid=InxS7T26W2kb+hhTRnqS1re1K8Tmb2Q4&qb=bXlzcWwgLnNxbA==&pid=fvwFPsoQsDlssvutbPGsss--102096&sid=SDwiMvIhPEgAAAG@IQo

    // LPCTSTR 정의
    char  buf[] = "1234";

    // LPCTSTR -> CString
    CString s(buf);

    // CString -> BSTR
    BSTR  bstr = s.AllocSysString();
    SysFreeString( bstr ); <-- 반드시 해주어야 한다.

    // "1234" -> BSTR
    BSTR bstr = L"1234";
    SysFreeString( bstr ); <-- 반드시 해주어야 한다.

    // BSTR -> CString





▶ CString -> BYTE

BYTE*   temp;
CString   cmd;
에서 cmd 의 값을 temp에 할당하려 할때.


temp=new BYTE[255];
temp=(LPBYTE)(LPCSTR)cmd;
delete []temp;


or


CString str = _T("abcd");
BYTE* pbyte = new BYTE[256];
int nSize;
nSize = str.GetLength();
CopyMemory( pbyte, str.GetBuffer(nSize), nSize );
pbyte[nSize] = 0;


or


strcpy(szNamePlace,(LPCTSTR)name);

or


CString str = "string";
BYTE* pByte;
pByte = (BYTE*)(LPTSTR)(LPCTSTR)str;


▶ BYTE -> CString

CString testString;
BYTE    testByte;
testString.Format( "%s", testByte );


▶ CString -> BYTE *

CString name = "몽룡이";
 BYTE byte[26] = {0};
 BYTE bName[26] = {0x0,};

 sprintf((char*)byte, "%s", name);
 
 memcpy(bName, byte, 26);


CString strTmp1, strTmp2;
 strTmp1 = "";
 strTmp2 = "";

 for(int i=0; i<26; i++) {
     strTmp1.Format("%02X ", bName[i]);
     strTmp2 += strTmp1;
 }
 MessageBox(strTmp2, "", 0);


26바이트의 크기의 이름이다. 남는 공간은 0으로 채워진다


▶  CString -> int

 CString의 문자열을 바로 숫자로 바꾸는것은
 아직 보지 못했습니다.
 아마 atoi()나 atod()의 C함수를 사용해야 될것 같네요.
 도움말을 참고하세요.


▶  int -> CString

 CString str;
 int i = 6;
 str.Format("%d",i);    // str에 6의 문자가 들어갑니다.


▶  BYTE -> int, int -> BYTE
 
 바로 형변환으로 가능합니다.
 
 bt = (BYTE)i;          // 주의 : 작은 크기로 들어가기 때문에
                        // 255 이상의 값은 엉뚱하게 동작하겠지요.
 i = (int)bt;


CString  => char* 변환

char * ch;
CString *str;

1) ch = (LPSTR)(LPCSTR)str;

2) ch = str.GetBuffer(str.GetLength());
3) wsprintf( ch, "%s", str);



char*  =>  CString 변환

1) str = (LPCSTR)(LPSTR)ch;
2) str = ch;



참고)

LPSTR 은 char* 입니다.

LPSTR : char stirng의 32비트 포인터, char* 와 같다.

LPCTSTR : Constant character String의 32비트 포인터

UINT : 32비트 unsigned형 정수
DWORD : unsigned long int형

BYTE : 8비트 unsigned 정수



1.CString 클래스의 GetBuffer()는 CString을 char *로 바꿔줍니다.

ex) CString strTemp = _T("test");
     char *getTemp=NULL;

     getTemp = malloc(strTemp.GetLength()+1);
     strcpy(getTemp, strTemp.GetBuffer(strTemp.GetLength());
     printf("결과:%sn", getTemp);

     free(getTemp);

2. operator LPCTSTR ()도 마찬가지입니다.

ex) CString strTemp = _T("test");
     char *getTemp = (LPSTR)(LPCSTR)strData;


CString -> BYTE*

CString str="1234";

BYTE *pbyte;

pbyte = (BYTE(LPSTR)(LPCSTR)str;




CString str = _T("abcd");

BYTE* pbyte = new BYTE[256];

int nSize;

nSize = str.GetLength();

CopyMemory( pbyte, str.GetBuffer(nSize), nSize );

pbyte[nSize] = 0;

 

 

CString  => char* 변환

char * ch;
CString *str;

1) ch = (LPSTR)(LPCSTR)str;

2) ch = str.GetBuffer(str.GetLength());
3) wsprintf( ch, "%s", str);

char*  =>  CString 변환

1) str = (LPCSTR)(LPSTR)ch;
2) str = ch;



참고)

LPSTR 은 char* 입니다.

LPSTR : char stirng의 32비트 포인터, char* 와 같다.

LPCTSTR : Constant character String의 32비트 포인터

UINT : 32비트 unsigned형 정수
DWORD : unsigned long int형

BYTE : 8비트 unsigned 정수


참고 : CString을 const char* 형태로 변경 -> (LPTSTR)(LPCTSTR)CString


LPCSTR :  A 32-bit pointer to a constant character string.
LPSTR :  A 32-bit pointer to a character string.
LPCTSTR :  A 32-bit pointer to a constant character string that is portable for Unicode and DBCS.
LPTSTR :  A 32-bit pointer to a character string that is portable for Unicode and DBCS.


출처 : http://tong.nate.com/redyoon/34780867

'etc > old' 카테고리의 다른 글

ニッシンのSEAFOOD NOODLEは おいしいですよ。  (0) 2008.05.28
mysql에서 쿼리 사용방법  (0) 2008.05.28
携帯電話は必要悪(ひつようあく)だ  (0) 2008.05.27
FlashExternalInterface.cpp  (0) 2008.05.26
Blaze DS 설치  (0) 2008.05.26
=======================================================
携帯電話は必要悪(ひつようあく)だ
=======================================================
日本は、子供を有害情報(ゆうがいじょうほう)から守(まも)るため、
小中学生(しょうちゅうがくせい)が携帯電話(けいたいでんわ)を持(も)つことがないように
関係者(かんけいしゃ)に協力(きょうりょく)を促(うなが)している。
韓国もこれと似(に)たような例(れい)として、電話料金(りょうきん)の制限制度(せいげんせいど)があります。
無理(むり)な料金のお支払(しはら)いに多額(たがく)の料金を支払うことによる被害を増(ふ)えて、
政府(せいふ)が作った政策(せいさく)の一つである。
即(すなわ)ち携帯電話は、人生において必要悪(ひつようあく)だと思います。
=======================================================
知らない 單語
=======================================================
政府(せいふ) 정부
増(ふ)える 늘다. 늘어나다. 증가하다. 불어나다.
被害(ひがい) 피해
多額(たがく) 다액. 고액. 액수가 많음.<-> 少額(しょうがく)
支払(しはら)い지불. 지급.
制度(せいど)제도
制限(せいげん) 제한
促(うなが)す (진행을) 촉진시키다. 재촉하다. 독촉하다. 촉구하다.
協力(きょうりょく)협력
関係者(かんけいしゃ) 관계자
持(も)つ (손에) 들다. 지속하다. 지탱하다. 견디다.
有害情報(ゆうがいじょうほう) 유해정보
政策(せいさく) 정책
必要悪(ひつようあく) 필요악
即(すなわ)ち = つまり 즉
=======================================================

'etc > old' 카테고리의 다른 글

mysql에서 쿼리 사용방법  (0) 2008.05.28
문자열 형변환 예시  (0) 2008.05.27
FlashExternalInterface.cpp  (0) 2008.05.26
Blaze DS 설치  (0) 2008.05.26
暇な時間の使用(しよう)  (0) 2008.05.23

Flash 와 App간 통신 방법 3가지를 소개했었는데, AS3로 넘어오면서 watch명령이 없어져서 기존에 사용하던 fscommand/setVariable 방법을 사용할수 없어졌습니다. watch 명령이 아주 비효율적이라 아예 없앴다고 합니다. LocalConnection 방법은 편법성으로 사용자들이 알아낸 방법이므로, ExternalInterface로 Flash와 APP간 통신을 구현했습니다.


1. Application에서 Flash 함수 호출

Actionscript3 소스:
ExternalInterface.addCallback("callFromApp", function(a, b) { return "ok:"+a+","+b; });


C++ 소스:
string invXml = ExternalInterface::MakeInvokeXml("callFromApp", arg1, arg2);
string ret = ExternalInterface::ParseResultXml(m_cFlash.CallFunction(invXml.c_str()).GetBuffer(0));


2. Flash에서 Application 호출

Actionscript3 소스:
ExternalInterface.call("testfunc", "hello", 1, true, 1==2, 1.1);

C++ 소스:
void CFlashTestApp::OnFlashCallShockwaveflash1(LPCTSTR request)
{
   string cmd;
   vector<string> args;

   if (ExternalInterface::ParseInvokeXml(request, cmd, args)) {
      // 함수콜 처리하기~
   }
}


--
Flash와 APP간 통신은 모두 XML을 통해서 이루어집니다.
1. 어플에서 XML을 만들고 파싱해야합니다.
2. 외부 XML 파서를 쓸수 있지만, 사용하는 XML이 복잡하지 않아서 자체 XML 파서를 만들었습니다.
3. Flash에서는 type이 있지만, C++에서는 모두 string으로 받도록 했습니다. C++에서 보낼때도 모두String인자로 보냅니다. 어차피 XML이 문자열로 되어 있으므로, string으로 처리해도 퍼포먼스에 크게 영향이 없을것으로생각되고, Variant를 C++에서 구현하는것은 복잡하고 짜증나는 작업이죠.
4. ActionScript에서 전달한 인자 중 복잡한 자료구조는 파싱하지 못하고,   String, Number,Boolean등과 1차 Array만 파싱하도록 했습니다. C++에서는 인자 받은걸 순서대로 vector에 넣어서 처리를단순화했습니다. Array안에 Array등을 처리하려면 C++에서도 복잡한 자료구조가 필요하고, 그러면 함수처리하는 부분도복잡해질듯해서 단순화했습니다.
5. STL string을 이용해서 파싱했습니다.


XML 파싱 함수들 입니다.

string peek_element(const string &xml);
xml에 포함된 첫 element를 가져옵니다. peek = 엿보기?

bool parse_element(const string &name, string &xml, string &attrs, string &inner);

xml에 포함된 첫 element를 파싱해서 attribute부분과 innerXml부분으로 나누어줍니다. xml에서는 파싱한 부분을 제거합니다.
   name = a
   xml = <a attr="haha">aab</a><b>zzz</b>
이런식으로 호출되면...
   attrs = attr="haha"
   inner = aab
   xml = <b>zzz</b>
이런식으로 값이 바뀝니다.

bool parse_attributes(const string &attrs, StringMap &attrMap);
<element attr1="val1" attr2="val2">
위에 같은 xml attributes을 파싱해서 attrMap에 insert합니다. "attr1"→"val1", "attr1"→"val2"

string xml_encode(const string &x); // <, &, > → &lt;, &amp;, &gt;

string xml_decode(const string &x);
// &lt;, &amp;, &gt; → <, &, >

Flash -> Application XML 예제
ExternalInterface.call("testfunc", "hello", 1, true, 1==2, 1.1);

<invoke name="testfunc" returntype="xml">
   <arguments>
       <string>hello</string>
       <number>1</number>
       <true/>
       <false/>
       <number>1.1</number>
   </arguments>
</invoke>


Flash -> Application XML 파싱 소스:
// external interface 파싱
bool parse_arg(string &xml, string &val)
{
   string attrs, i;
   if (parse_element("string", xml, attrs, i)) {
       val = i;
   } else if (parse_element("number", xml, attrs, i)) {
       val = i;
   } else if (parse_element("true", xml, attrs, i)) {
       val = "true";
   } else if (parse_element("false", xml, attrs, i)) {
       val = "false";
   } else if (parse_element("boolean", xml, attrs, i)) {
       val = i;
   } else {
       return false;
   }
   return true;
}

void parse_args(string &xml, vector<string> &args)
{
   string val;
   while (1) {
       if (parse_arg(xml, val)) {
           args.push_back(val);
       } else {
           break;
       }
   }
}

bool ParseInvokeXml(const string &_xml, string &cmd, vector<string> &args)
{
   string xml=_xml;
   string attrs;
   string innerXml;

   parse_element("invoke", xml, attrs, innerXml);

   StringMap attrMap;
   parse_attributes(attrs, attrMap);

   StringMap::const_iterator f = attrMap.find("name");

   if (f != attrMap.end()) {
       cmd = f->second;
       string elm = peek_element(innerXml);
       string p, i;
       if (parse_element("arguments", innerXml, attrs, i)) {
           innerXml = i;
           if (parse_element("array", innerXml, attrs, i)) {
               innerXml = i;
               while (parse_element("property", innerXml, attrs, i)) {
                   parse_args(i, args);
               }
           } else {
               parse_args(innerXml, args);
           }
       }
   }
   return true;
}

'etc > old' 카테고리의 다른 글

문자열 형변환 예시  (0) 2008.05.27
携帯電話は必要悪(ひつようあく)だ  (0) 2008.05.27
Blaze DS 설치  (0) 2008.05.26
暇な時間の使用(しよう)  (0) 2008.05.23
철콘 근크리트 (鐵コン筋クリ-ト: Tekkon Kinkreet, 2006)  (0) 2008.05.22
초간단 버전임.

1. blaze DS 다운 받기
블레이즈 DS다운로드 주소 => 대략 123메가 (blazeds_turnkey_3-0-0-544.zip 기준)
http://download.macromedia.com/pub/opensource/blazeds/blazeds_turnkey_3-0-0-544.zip

안된다면 아래 주소로 접속하여 따라가서 다운 받는다.
http://opensource.adobe.com/wiki/display/blazeds/BlazeDS

2. 압축 해제

3. 설치폴더\tomcat\bin\startup.bat 실행
=> 톰캣 기동시 You must start the samples database before you can run the samples. 라는 말이 뜨는데
DB테스트를 하려면 설치폴더\sampledb\startdb.bat를 실행시키라는 말임.
[예외처리 - 패스설정]

=> 만약 (영어로) JRE_PATH 또는 JDK_PATH가 설정되지 않았다고 나왔을 경우는
내컴퓨터 - 속성 - 고급 - 환경변수 - 시스템 변수 - 새로 만들기
변수 이름 : JRE_PATH or JDK_PATH
변수 값 : JRE또는 JDK가 설치된 경로를 알맞게 지정해 주면 된다.
[예외처리 - 포트충돌]
=> 기본 사용 포트는 8400인데.. 충돌시 해당 포트를 사용하는 프로그램을 잠시 멈추거나
\tomcat\conf\server.xml에서 8400 이 부분을 다른 포트로 교체하여 적어주면 된다.

4. http://locahost:8400/ 으로 접속한다.
(아래와 같은 그림을 보면 설치 완료)

사용자 삽입 이미지




















참고 톰캣과 샘플 디비 종료할때는 xxxStop.bat를 누르면 됩니다 ㅡ,.ㅡ;;

계속 Continue 해서 공부해야징...
=======================================================
暇な時間の使用(しよう)
=======================================================
1位    男 : テレビやビデオを見る
    女 : テレビやビデオを見る

2位    男 : 友達(ともだち)と会う
    女 : 電話で話す

3位    男 : 電話で話す
    女 : 音楽聴(き)く

4位    男 : 音楽聴(き)く
    女 : ショッピングする

5位    男 : 運動する
    女 : 友達(ともだち)と会う

新聞に出てきた。 私は暇な時間には、インターネットのゲーム(スタークラフト)を楽しんだりするのに..

(インターネットのゲームだという6位にラエンケウドエム)それでも、友人とともに、カラオケに行くか、

サプギェオプサルに焼酎(しょうちゅう)を飲みながら、色(いろ)んな話(はなし)をするのが大好き。

=======================================================
知らない 單語
=======================================================
ともに 함께, 같이
焼酎(しょうちゅう) 소주
=======================================================
質問(しつもん)
=======================================================
聴(き)くと聞(き)くは なにが 違(ちが)いますか。
友人(ゆう‐じん)。友達(ともだち)。朋友(ほうゆう)。差は 何ですか。
=======================================================

'etc > old' 카테고리의 다른 글

FlashExternalInterface.cpp  (0) 2008.05.26
Blaze DS 설치  (0) 2008.05.26
철콘 근크리트 (鐵コン筋クリ-ト: Tekkon Kinkreet, 2006)  (0) 2008.05.22
私(わたし)の 日常(にちじょう)  (0) 2008.05.21
2008年 5月 19日 月曜日  (0) 2008.05.20

+ Recent posts