이 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속성에 접근할 수 있어요^^
'플렉스'에 해당되는 글 86건
- 2007.12.01 [FLEX] HTTPService가 출력한 XML을 ArrayCollection에 넣기! null에러해결법! 12
- 2007.12.01 [FLEX] XML을 HTTPService로 불러올 때 xml데이터에 특수문자가 들어있는경우!
- 2007.11.18 [FLEX] Struts + iBATIS + FLEX 초간단게시판-_-; 20
- 2007.11.15 [FLEX] 서버(JAVA)-클라이언트(FLEX) 모델의 채팅프로그램2(XMLSocket이용)
- 2007.11.15 [FLEX] 서버(JAVA)-클라이언트(FLEX) 모델의 채팅프로그램1(XMLSocket이용) 5
물론 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파서가 파싱하지 않습니다.
아...계속 게시판만 만드네요-_-; 그래도 데이터연동의 가장 기본이 되는것을 해야하니깐-_-;
테스트환경은 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로 삽질하시는 분들께 도움이 되고자-_-;
Struts + iBATIS를 이용한 xml을 리턴하는 게시판입니다.
그런식으로 나타낸 xml코드를 flex에서 가져다가 DataGrid에 넣도록 되어있습니다.
Flex Project Archive로 export한 프로젝트입니다.
즉, 그냥 서버단에서 리턴하는 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 ;
입니다-_-;
설명은 나중에-_-; 아.....졸려-_-;
클라이언트입니다.
그냥 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]
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]
저 부분만 바뀌었어요 ^^
이제 클라이언트로-_-;