이 ArrayCollection 참 이상하네요-_-;
참 다루기 힘드네요. ^^









우선 http://localhost:8080/list.jsp 하면 아래와 같은 형태를 출력한다고 칩시다.

[code]<?xml version="1.0" encoding="UTF-8"?>
<result_set>
 <record>
  <id>mudchobo</id>
  <username>성종천</username>
 </record>
 <record>
  <id>idoori</id>
  <username>임두리</username>
 </record>
</result_set>
[/code]
잘 보시면 result_set태그안에 record태그가 2개가 있네요.
요 데이터를 가져와서 ArrayCollection에 저장하고 싶습니다.
그러면 이렇게 하면 됩니다. HTTPService의 result속성이 resultHandler라고 칩시다.
[code]public var recordAC:ArrayCollection;

public function resultHandler(event:ResultEvent):void {
 recordAC = (event.result.result_set.record is ArrayCollection) ?
     event.result.result_set.record as ArrayCollection :
     new ArrayCollection(ArrayUtil.toArray(event.result.result_set.record));
}
[/code]
저렇게 하는 이유는....만약 record가 1개라고 칩시다.
그러면 event.result.result_set.record as ArrayCollection 해버리면 recordAC변수에 null이 들어갑니다.
Array로 인식안하고 하나의 객체로 인정해서 ArrayCollection으로 변환을 못하는 것 같습니다-_-;
사실 왜그런지 정확한 이유는 모르겠군요. 디버그를 해보니까 record가 2개면 record에 [0], [1] 이렇게 나뉘는데 record가 1개면 [0], [1]이런거 없고 바로 id, username 이렇게 나오더군요. 배열로 생각안하고 그냥 객체로 생각해서 저런 것 같습니다-_-;

그래서 저렇게 변환이 가능한지 물어보면 되고, 1개의 record가 있으면 변환이 불가능하기 때문에
ArrayUtil.toArray를 쓰면 됩니다.

그리고 저렇게 해줘야하는 이유가 그냥 ArrayUtil.toArray로 받아오면 나중에 해당 객체를 가져올 때 이상해지더라구요-_-; recordAC.getItemAt(0); 해서 0번째 Object를 가져오면 Object를 열어보면 [0][1] 이 있어서 배열이 들어가 있어요. 그래서 배열로 된 건 ArrayUtil.toArray로 가져오면 안되더라구요 ^^

저렇게 as ArrayCollection으로 가져오면 var obj:Object = recordAC.getItemAt(0); 한다음에
obj.name 하면 name속성에 접근할 수 있어요^^

 
Posted by 머드초보
,
 
faultCode:Client.CouldNotDecode faultString:'Error #1090: XML 파서 실패: 요소가 잘못되었습니다.' faultDetail:'null' 요런 에러를 냅니다.



물론 http://localhost:8080/모모모.jsp 을 실행했을 때 xml형태도 제대로 안나오겠죠.
그니까 <content></content>  요 태그안에 <>& 등 기존에 html등에서 쓰지 못했던 것 있죠?

이 값이 만약 db에 들어있어서 이값을 가지고 와서 저 태그안에다가 넣는 문법이 있으면
<content><>&</content> 하면 에러가 나겠죠!

[code]<content>${list.content}</content>
[/code]
이런식으로 코딩되어 있다면 위험하더군요-_-;
저도 얼마전에 어떤분이 제가 샘플로 올린 게시판을 보고 알았는데요.
누가 글쓸 때 <html>등의 코드를 content부분에 써놨더라구요-_-;
이게 그냥 db에 저장이 되긴 됐는데 나중에 불러오려고 할 때 xml형태를 리턴하기 때문에 문제가 생기더라구요^^
그래서 저부분을.....
[code]<content><![CDATA[${list.content}]]></content>
[/code]
요렇게 바꿔주면 됩니다.
<![CDATA[]]> 요 태그 안에 있는 놈들은 xml파서가 파싱하지 않습니다.
 
Posted by 머드초보
,
 

아...계속 게시판만 만드네요-_-; 그래도 데이터연동의 가장 기본이 되는것을 해야하니깐-_-;

테스트환경은 TOMCAT6.0 + JDK 6.0 + Struts 1.3.8 + iBATIS 2.3.0 + Flex3 Beta 2 에서 했습니다.

저번엔 RemoteObject로 삽질했는데 이제 HTTPService로 삽질하네요.
우선 RemoteObject는 해당클래스를 직접 호출해서 가져다가 쓰는 것이구요.
HTTPService는 말그대로 http를 통해 주소값을 넣으면 그것을 실행하게 되는 것인데요.
그 실행해서 나오는 값이 xml형태이면 xml태그에 있는 값을 가져올 수 있습니다.

그렇다는 얘기는 서버단에서는 Struts와 iBATIS를 통해서 DB와 연동해서 데이터를 xml형태로 리턴해주면 그것을 FLEX에서 값을 가져다가 DataGrid에 넣든 쇼를 하든 할 수 있다는 얘기죠.

그리 대단한 건 아니지만, HTTPService로 삽질하시는 분들께 도움이 되고자-_-;

invalid-file

Struts + iBATIS를 이용한 xml을 리턴하는 게시판입니다.

즉 http://localhost:8080/FlexBoard/list.do 을 실행하게 되면 결과값이 xml코드를 리턴한다는 얘기죠.
그런식으로 나타낸 xml코드를 flex에서 가져다가 DataGrid에 넣도록 되어있습니다.

invalid-file

Flex Project Archive로 export한 프로젝트입니다.

이거는 저 위에 있는 FlexBoard.war에 포함되어있는 swf를 만들어주는 프로젝트입니다.
즉, 그냥 서버단에서 리턴하는 xml을 가져와서 DataGrid에 넣기도하고, http서비스를 이용하여 파라메터를 던져서 해당 DB를 컨트롤하기도 하고 그런거하는 겁니다.


DB구조는.....
CREATE TABLE `Board` (
  `b_id` int(11) NOT NULL auto_increment,
  `b_name` varchar(10) NOT NULL,
  `b_pwd` varchar(10) NOT NULL,
  `b_title` varchar(30) NOT NULL,
  `b_content` mediumtext NOT NULL,
  PRIMARY KEY  (`b_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=euckr AUTO_INCREMENT=115 ;
입니다-_-;

설명은 나중에-_-; 아.....졸려-_-;
 
Posted by 머드초보
,
 

클라이언트입니다.

그냥 Socket이랑 조금 틀립니다.

그냥 소켓은 데이터를 받을 때에
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
를 등록해서 데이터가 들어오면 함수가 호출되도록 되어 있습니다.

그리고 보낼 때에도 writeUTF어쩌구로 보냅니다.

근데 XMLSocket은 더 간단하게 주고 받을 수 있습니다.

XMLSocket은 저 아래에있는 이벤트를 등록합니다.
xmlsocket.addEventListener(DataEvent.DATA, socketDataHandler);

그리고, 저 함수에서 DataEvent에 있는 data값에 데이터가 들어있습니다.
그냥 출력해주면 돼요-_-;

보낼 때에는 XMLSocket에 있는 send메소드를 이용해서 그냥 보내면 돼요. 아주 간단해요!

클라이언트(FLEX)
[code]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
 creationComplete="initApp()">
 
 <mx:Script>
  <![CDATA[
   private var xmlsocket:XMLSocket;
   [Bindable]
   public var userId:String;
   
   private function initApp():void {
    currentState = "logon";
   }
   
   public function logon():void {
    userId = tUserId.text;
   
    xmlsocket = new XMLSocket();
    xmlsocket.addEventListener(DataEvent.DATA, socketDataHandler);
    xmlsocket.connect("localhost", 10001);
    xmlsocket.send(userId + "\n");
   
    currentState = "chat";
   }

   private function socketDataHandler(event:DataEvent) :void {
    log.text += event.data;
      }
        
   public function send():void {
                xmlsocket.send(msg.text + "\n");
                msg.text = "";
                
   }
  ]]>
 </mx:Script>
 
 <mx:Panel id="panel" width="100%" height="100%" verticalAlign="middle"
  horizontalAlign="center">
  <mx:ControlBar id="cb" height="44" />
 </mx:Panel>
 
 <mx:states>
 
  <mx:State name="logon">
   <mx:AddChild relativeTo="{panel}">
    <mx:HBox>
     <mx:Label text="User Id:" />
     <mx:TextInput id="tUserId" enter="logon()" />
     <mx:Button label="Logon" click="logon()" />
    </mx:HBox>
   </mx:AddChild>
  </mx:State>
 
  <mx:State name="chat">
   <mx:SetProperty target="{panel}" name="title"
    value="접속자 ID : [{userId}]" />
   <mx:AddChild relativeTo="{panel}">
    <mx:TextArea id="log" width="100%" height="100%" editable="false"
     updateComplete="log.verticalScrollPosition=log.maxVerticalScrollPosition;"/>
   </mx:AddChild>
   <mx:AddChild relativeTo="{cb}">
    <mx:HBox width="100%" paddingTop="0" paddingBottom="0">
     <mx:TextInput id="msg" enter="send()" width="100%" />
    </mx:HBox>
   </mx:AddChild>
  </mx:State>
 
 </mx:states>
 
</mx:Application>
[/code]

 
Posted by 머드초보
,
 

XMLSocket은 뭔가 이상하군요-_-;

그냥 Socket클래스는 그냥 쓰던 소켓같은데 XMLSocket은 삽질한 결과 이상하게 주고 받는 것 같아요.

우선 보낼 때 이상하게 나눠서 보내게 되더라구요.

그리고 \0을 끝으로 인식하는 듯합니다. 그래서 자바서버에서 보낼 때 pw.println("blur~blur~")이렇게 보낼 때에는 blur~blur~\r\n이 가게 되는데 저것이 끝이라고 인식을 못하더라구요.
그래서 보낼 때에는 pw.print("blur~blur~\n\0") 이라고 보내야해요.

그리고,
mudchobo : 안녕하세요\n\0 라고 보내면, 이상하게 나눠서 호출이 되더라구요-_-;
mudchobo : 데이터를 받고, 그다음에 안녕하세요\n\0을 받아요-_-;

왜그럴까요-_-; 어쨌든, 편법으로 만든 채팅프로그램입니다.

서버(JAVA)
ChatServer.java
[code]package com.mudchobo.chat;

import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

public class ChatServer {

 private ServerSocket server;
 
 void startServer() {
  try {
   server = new ServerSocket(10001);
   System.out.println("접속을 기다립니다.");
   HashMap<String, PrintWriter> hashMap =
    new HashMap<String, PrintWriter>();
   
   while (true) {
    Socket sock = server.accept();
    ChatThread chatThread =
     new ChatThread(sock, hashMap);
    chatThread.start();
   } // while
  } catch (Exception e) {
   System.out.println(e);
  }
 }
 public static void main(String[] args) {
  ChatServer chatServer = new ChatServer();
  chatServer.startServer();
 }
}
[/code]

ChatThread.java
[code]package com.mudchobo.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

class ChatThread extends Thread {
 private Socket sock;
 private String id;
 PrintWriter pw;
 private BufferedReader br;
 private HashMap<String, PrintWriter> hashMap;

 public ChatThread(Socket sock, HashMap<String, PrintWriter> hashMap)
  throws UnsupportedEncodingException, IOException {
  this.sock = sock;
  this.hashMap = hashMap;
 
  pw = new PrintWriter(
    new OutputStreamWriter(sock.getOutputStream(),"UTF-8"));
  br = new BufferedReader(
    new InputStreamReader(sock.getInputStream(), "UTF-8"));
  id = br.readLine();
  hashMap.put(id, pw);
  broadcast(id + "님이 접속하였습니다.");
  System.out.println("접속한 사용자의 아이디는 " + id + "입니다.");
 }

 public void run() {
  try {
   String line = null;
   while ((line = br.readLine()) != null) {
    if (line.equals("/q")) {
     break;
    } else {
     broadcast(id + " : " + line);
    }
   }
  } catch (Exception ex) {
   System.out.println(ex);
  } finally {
   hashMap.remove(id);
   broadcast(id + " 님이 접속 종료하였습니다.");
   System.out.println(id + " 님이 접속 종료하였습니다.");
   try { if (sock != null) sock.close(); } catch (Exception ex) {}
  }
 }

 public void broadcast(String msg) {
  Collection<PrintWriter> collection = hashMap.values();
  Iterator<PrintWriter> iter = collection.iterator();
  while (iter.hasNext()) {
   PrintWriter pw = (PrintWriter) iter.next();
   pw.print(msg + "\n\0");
   pw.flush();
  }
 }
}
[/code]
저 부분만 바뀌었어요 ^^

이제 클라이언트로-_-;

 
Posted by 머드초보
,