adobe Edge

2012. 6. 4. 16:53

어도비 사에서 html5 를 적극 지원하기 위해 Edge 라는 프로그램을 선보였다.

7월 31일 부터 preveiw 버전을 다운로드 할 수 있도록 하였다.

http://labs.adobe.com/technologies/edge/



 

Edge 는 좀더 쉽게 html5 와 css3 를 이용하여 애니메이션을 만들 수 있도록 하는 툴이다. 당연히 html5 를 지원하지 않는 인터넷 익스플로러 6,7,8 에서는 동작 하지 않는다. 하지만 이를 지원하는 브라우저에서는 잘 동작 된다. 물론 아이폰과 아이패드에서도 아주 잘 동작 될 것이다(테스트 해보지 않았음.).



 

그럼 지금부터 Edge 에 대해 조금 살펴 보기로 한다. 먼저 아래 링크로 가서 Edge 의 preview 버전을 다운로드 받은 후 설치 한다.

http://labs.adobe.com/technologies/edge/

adobe 계정이 필요 하며, windows 는 vista 이상 부터 설치가 가능하며, 맥은 Mac OS X v10.6 and v10.7 부터 설치가 가능하다.

설치가 끝나면 아래와 같은 화면을 볼 수 있다.

adobe Edge Preveiw 버전의 실행화면

엣지 프로그램 튜토리얼 과 샘플 파일도 다운로드 받을 수 있다.



 

나 는 엣지 프로그램의 테스트를 위해 Create New 를 클릭 하였다. 그러면 아래와 같이 Untitled-1.html 파일이 만들어 지며 flash 나 afterEffects 를 다루어 본 사람이라면 조금 익숙한 work space를 볼 수 있다.

Create New 를 누르면 Untitled.html 문서가 만들어 진다.

일 단 상단에 선택, 도형, 택스트 입력 툴이 보인다. 좌측에는 속성 창(Properties) 창이 보이며, 여기서 Stage 의 색상 과 width, height 값을 설정 할 수 있다. 또한 Stage 를 넘어설 경우에 해당되는 css 속성자인 overflow 를 선택 할 수도 있다.

overflow 속성 선택

직사각형툴(Rectangle Tool) 을 이용해 사각형을 그려 보겠다.

직사각형 툴(Rectangle Tool)

사각형을 그린뒤 해당 사각형(Elements)를 선택하면 좌측 속성창에 해당 엘리먼트의 조정가능한 속성값들이 나온다. 해당 속성값은 아래와 같다.

  1. Element 의 ID 값을 지정한다. (<div id="Rectangle1"></div> 라고 생각하면 된다. 실제로 이렇게 된다.)
  2. Element 의 좌표값과 사이즈, 투명도를 지정할 수 있다.
    • 중 요한것은 이것은 애니메이션을 만들기 위한 툴이기 때문에 좌표값의 개념을 다르게 생각해야 한다. 최초 사각형 모양의 엘리먼트를 그린 그 위치를 x,y 각각 0으로 인식하면 된다. 그리고 그려진 위치를 기준으로 +,- 하여 애니메이션이 생성된다.
  3. Element의 background 와 border 를 지정한다.
  4. Element의 회전, 회전시 기준점, 뒤틀림, 비율 등을 지정할 수 있다.
  5. border-radius 속성을 지정할 수 있다.

* 위의 속성값들을 변화 시키면 하단 타임 라인에 해당 속성값들이 추가된다. 이 개념은 에프터 이펙트와 비슷한데 아래에서 추가로 설명 하도록 하겠다.

여기에 택스트를 하나 더 추가해 보도록 하겠다. 텍스트는 내가 자주가는 네이버카페인 '하드코딩하는 사람들' 이라고 쓰도록 하겠다.


텍스트를 적으면 해당 텍스트 에 대한 속성값들이 properties 창에 보여진다.


 

  1. Element 의 id 값이다.
  2. Element 의 좌표값과 사이즈, 투명도를 지정할 수 있다.
  3. font-family 와 size , color , text-align 및 decoration 속성들을 변경할 수 있다.
  4. Element 의 회전축, 회전각도, 뒤틀림, 비율 등을 변경 할 수 있다.

여기까지 하게되면 마크업 구조는 다음과 같아진다.

1
2
3
4
5
6
<div id="stage">
<div id="Rectangle">
</div>
<div id="Text2">
하드코딩하는 사람들</div>
</div>

물론 위의 코드는 Edge 가 자바스크립트 화 하여 문서가 로드될때 상위 Element에 write 해준다. 크롬 개발자 도구로 확인 할 수 있다. 이제 만들어진 엘리먼트들에게 생명을 불어 넣어 보겠다. 그전에 알아두어야 할것 몇가지..

위의 속성값들 이름 앞에 보면 ◇ 모양을 볼수 있다. 이것은 하단 Timeline 창의 Element 에 해당 속성에 대한 키프레임을 추가하는 버튼이다. 클릭하거나 해당 속성을 변경하게 되면 하단 타임라인의 엘리먼트에 속성값이 추가되는 것을 알 수 있다.

이것이 add Keyframe 버튼

키프레임추가 버튼을 누르거나 속성값을 변경하면 타임라인에 키프레임이 생성된다.(Auto-Keyframe Properties 가 체크된 상태일 경우 -> 붉은색 시계모양)


 

이것이 Auto-Keyframe Properties 로 체크되 있으면 Element 의 속성값이 변화할때 자동으로 키프레임이 추가된다.



급하게 애니메이션을 만들어 보겠다.

순서는 지금 까지 만은 앨리먼트에 속성값을 각각 타임라인의 시간에 따라 다르게 주기만 하면 된다.

예로 0:00 에서 엘리먼트의 x 축을 10 으로 주면 0:02 에서 x 축의 값을 30으로 변경하면 좌에서 우로 움직이는 애니메이션이 된다.


일단 지금 만들어 놓은 것이 최종적인 모습이므로 키프레임에서 현재 만들어 놓은 속성들을 0:02 로 끌어서 이동시켰다.


 


그런다음 타임라인의 현재 프레임을 0:00 으로 이동시켜서 시작시의 모습으로 속성을 변경 시켜본다. 위에서 회색박스가 떨어지는 효과를 주기 위해 Rectangle4 의 tY 값을 -276까지 변경해서 stage 의 위쪽으로 안보일때까지 올려 버렸다. 그러면 타임라인에 아래와 같이 모션이 적용된걸 확인 할 수 있다. 재생 버튼을 눌러 보면 위에서 아래로 떨어지는 회색 상자 모션을 볼 수 있다.


 


위의 녹색부분을 클릭하면 좌측에 속성을 변화 시킬 수 있다. 모션이 되는 부분의 아이디, 시간, 시작되고 끝나는 시간을 조절할 수 있으며 Easing(부드럽게 시작되고 끝나는 등의 효과) 를 줄 수 있다. 이부분은 직접 해보는 편이 빠를듯.


이와 같이 해서 텍스트에도 같은 효과를 주었다.


 

모션이 완료되고 저장하면, edge 파일과 함께 html, css, js 파일과 edge_includes 폴더 가 생성된다. 이것들이 모두 올라가야 하며, html 파일을 열어보면 (웹퍼블리셔, 혹은 개발자라면) 아..이렇게 되는 구나 라고 알수 있을듯...



 

위에 작업한거 샘플파일임.


시작할때는 꼼꼼하게 분석해서 포스팅 해야지..했는데.. 회사일도 바쁘고 하다보니 결국 날림이 됐다.

지금은 베타 버전이라 기능이 거의 없지만 실제 상용화 버전은 아마 이벤트를 걸고, 만들고 하는 기능 부터 해서 많은 부분이 추가될 거라 기대한다.

 

http://eyekorea.tistory.com/18 에서 가져왔습니다.


Posted by 사라링

        <div id="container">
            <canvas title="그려주세요." id="drawCanvas" width="1200" height="250" s
                style="position: relative; border: 1px solid #000;"></canvas>
        </div>


<script type="text/javascript">

    if (window.addEventListener) {
        window.addEventListener('load', InitEvent, false);
    }
    var canvas, context, tool;

    function setTextCanvas() {

    }

    function InitEvent() {
        canvas = document.getElementById('drawCanvas');
        //       resetCanvas();
        if (!canvas) {
            alert("캔버스 객체를 찾을 수 없음");
            return;
        }
        if (!canvas.getContext) {
            alert("Drawing Contextf를 찾을 수 없음");
            return;
        }
        context = canvas.getContext('2d');
        if (!context) {
            alert("getContext() 함수를 호출 할 수 없음");
            return;
        }
        // Pencil tool 객체를 생성 한다.
        tool = new tool_pencil();
        canvas.addEventListener('mousedown', ev_canvas, false);
        canvas.addEventListener('mousemove', ev_canvas, false);
        canvas.addEventListener('mouseup', ev_canvas, false);
    }

    function tool_pencil() {
        var tool = this;
        this.started = false;
        // 마우스를 누르는 순간 그리기 작업을 시작 한다.
        this.mousedown = function(ev) {
            context.beginPath();
            context.moveTo(ev._x, ev._y);
            tool.started = true;
        };
        // 마우스가 이동하는 동안 계속 호출하여 Canvas에 Line을 그려 나간다
        this.mousemove = function(ev) {
            if (tool.started) {
                context.lineTo(ev._x, ev._y);
                context.stroke();
            }
        };
        // 마우스 떼면 그리기 작업을 중단한다
        this.mouseup = function(ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
            }
        };
    }

    // Canvas요소 내의 좌표를 결정 한다.
    function ev_canvas(ev) {
        if (ev.layerX || ev.layerX == 0) {// Firefox 브라우저
            ev._x = ev.layerX;
            ev._y = ev.layerY;
        } else if (ev.offsetX || ev.offsetX == 0) {// Opera 브라우저
            ev._x = ev.offsetX;
            ev._y = ev.offsetY;
        }
        // tool의 이벤트 핸들러를 호출한다.
        var func = tool[ev.type];
        if (func) {
            func(ev);
        }
    }




</script>


'HTML5.0' 카테고리의 다른 글

HTML 5 설명 글 중 (일본어를 구글로 강제 번역함 ㅠㅠ )  (0) 2012.06.04
adobe Edge  (0) 2012.06.04
캔버스 이미지 뛰우기 .  (0) 2012.06.04
canvas 사이트 모음 .  (0) 2012.05.24
Canvas  (0) 2012.05.22
Posted by 사라링

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
};
img.src="img_flwr.png";
</script>
</body>
</html>

<!DOCTYPE html>
<html>
<body>

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>


<script type="text/javascript">

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var grd=ctx.createLinearGradient(0,0,175,50);
grd.addColorStop(0,"#FF0000");
grd.addColorStop(1,"#00FF00");
ctx.fillStyle=grd;
ctx.fillRect(0,0,175,50);

</script>

</body>
</html>


'HTML5.0' 카테고리의 다른 글

adobe Edge  (0) 2012.06.04
캔버스 간단한 마우스 그리기  (0) 2012.06.04
canvas 사이트 모음 .  (0) 2012.05.24
Canvas  (0) 2012.05.22
html4.0 을 html 5.0 으로 변환  (0) 2012.05.14
Posted by 사라링

Ajax 란

 | AJAX
2012. 5. 24. 20:42

5년 전, XML에 대해 무지했다면 아무도 얘기할 상대가 없는 미운 오리 새끼 신세가 되었을지도 모르겠다. Ruby 프로그램이 주목을 받았던 8개월 전, Ruby 프로그램 언어 기능에 대해 알지 못했던 프로그래머들은 냉수기 관련 산업세계에서 환영 받지 못했다. 그런 것처럼, 최신 기술단계로 입문하고자 한다면 Ajax에 대해 알아야 한다.

하지만 Ajax는 일시적으로 유행하는 툴이 아니다. 웹 사이트를 구축하는 강력한 방식이며 완전히 새로운 언어를 배우는 것보다는 그다지 어렵지 않다.

Ajax에 관해 자세히 들어가기 전에 잠시 Ajax의 기능에 대해 알아보자. 오늘날 애플리케이션을 작성할 시 두 가지 애플리케이션이 있다.

  • 데스크톱 애플리케이션
  • 웹 애플리케이션

두 애플리케이션은 다 친숙한 것들이다. 일반적으로 데스크톱 애플리케이션은 CD상에 배치된 다음 (또는 웹 사이트에서 다운로드) 컴퓨터에 완전 설치된다. 이 애플리케이션은 인터넷을 이용해 업데이트를 다운로드하기도 하지만 애플리케이션 실행 코드는 데스크톱 상에 상주해 있다. 전혀 새로운 것이 아닌 웹 애플리케이션은 웹 서버 상에서 실행되며 웹 브라우저 상에서 접속된다.

하지만 두 애플리케이션에 대한 코드 실행 위치보다 애플리케이션 작동방식 및 애플리케이션과 사용자와의 상호작용방식이 중요하다. 일반적으로 데스크톱 애플리케이션은 상당히 빠르고 (컴퓨터 상에서 실행되고 인터넷 상에서 대기 중인 상태가 안 나온다.), 대형 사용자 인터페이스(일반적으로 운영체제와 상호작용)를 갖추며 상당히 동적이다. 거의 대기시간 없이 메뉴 및 하위 메뉴를 클릭, 지시, 입력하고 풀업한다.

반면 웹 애플리케이션은 가장 최신 것이며 데스크톱에서는 전혀 얻을 수 없는 서비스를 제공한다.(Amazon.com 및 eBay를 생각해 볼 것.) 하지만 웹 애플리케이션 기능으로 인해 서버 응답 대기, 스크린 재생 대기, Request 컴백 및 새 페이지 생성에 관한 대기 기능 등이 부수된다.

분명 지나친 단순화 과정임에는 틀림없지만 기본 개념은 얻게 된다. 이미 눈치를 챘겠지만 Ajax는 데스크톱 애플리케이션 및 항상 업데이트 되는 웹 애플리케이션의 기능 및 상호작용 간의 차이를 줄여주는 역할을 한다. 여러분은 마치 데스크톱 애플리케이션에서 찾은 것처럼 동적 사용자 인터페이스 및 가상 제어기능을 사용한다. 하지만 웹 애플리케이션 상에서 데스크톱 애플리케이션을 이용할 수 있다. 그러면 대기 중인 것이 무엇인가? Ajax 및 볼품없는 웹 인터페이스가 응답 Ajax 애플리케이션으로 변환되는 과정에 대해 살펴보기로 하자.

그러면 대기 중인 것이 무엇인가? Ajax 및 볼품없는 웹 인터페이스가 응답 Ajax 애플리케이션으로 변환되는 과정에 대해 살펴보기로 하자.

오래된 기술, 새로운 기법

Ajax에 관해 살펴보면 Ajax는 실지로 많은 기술들이 응집되어 있다. Ajax의 기본을 마치고 넘어가려면 몇 가지 다른 기술들(필자는 첫 번째 이 시리즈에서 각각의 기술에 관해 설명할 것이다.)을 면밀히 살펴보아야 한다. 하지만 이들 기술 가운데 어느 정도 알고 있는 것이 많은 건 다행이다. 더군다나 각각의 기술 대부분은 Java/Ruby같은 프로그래밍 언어만큼 어려운 게 아니라서 배우기 쉽다.

Ajax 정의

Ajax는 비동기 JavaScript 및 XML의 약어이다.(DHTML도 마찬가지다.) Adaptive Path사의 Jesse James Garrett이 이 약어를 만들어냈으며(참고자료), Jesse에 따르면 이 약어는 두문자어는 아니라고 한다.

Ajax 애플리케이션에 포함된 기본기술은 다음과 같다.

  • 웹 양식을 구축하고 애플리케이션 완료 때까지 사용되는 필드를 식별하는 데 HTML을 사용한다.
  • 자바 스크립트 코드는 Ajax 애플리케이션을 실행하는 중심 코드며 서버 애플리케이션과의 커뮤니케이션을 용이하게 한다.
  • DHTML(동적 HTML)은 웹 양식을 동적으로 업데이트 한다. div, span및 기타 동적 HTML 요소를 사용해 HTML을 마크업 한다.
  • 서버에서 복귀된 HTML 및 (때로) XML 구조를 다루는 데 있어 DOM, 즉 문서 객체 모델(Document Object Model)을 사용한다.

이 기술들에 대해 간략히 요약하고 각 기술의 기능에 대해 좀 더 알아보기로 하는데 각 기술에 관한 자세한 사항은 차후 글에서 다룰 것이다. 우선은 Ajax의 구성요소 및 기술에 대해 친숙해 지는 데 초점을 맞추기로 한다. 자바 스크립트에 익숙할수록 Ajax에 담긴 기술에 관한 일반적인 지식 단계에서 각 기술에 관한 자세한 지식으로 넘어가는 게 더 쉬워진다.(또한 이로 인해 웹 애플리케이션 개발에 관한 문이 열리게 된다.)

XMLHttpRequest 객체

알고자 하는 객체 중 첫 번째는 아마도 가장 생소한 것이 아닌가 싶다. 그 객체는 일명 XMLHttpRequest인데 자바 스크립트 객체의 일종이며 Listing 1에 나와 있는 것처럼 단순하게 생성된다.


Listing 1. 새로운 XMLHttpRequest 객체 생성
                
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>

필자는 다음 글에서 이 객체에 대해 더 논의할 것이다. 하지만 지금 상태에서는 모든 서버 커뮤니케이션을 다루는 객체라는 사실만 알아둔다. 다음 사항으로 가기 전에 잠깐 생각해 보면 자바 스크립트 객체는 XMLHttpRequest를 통해 서버에 전달하는 자바 스크립트 기술의 일종이다. 이 객체는 애플리케이션 흐름이 정상적이지 않으며 Ajax 기술의 많은 부분을 차지하고 있다.

정상적인 웹 애플리케이션에서 사용자는 양식 필드를 기입하며 제출 버튼을 클릭한다. 그러면 전 양식을 서버에 보내며 서버는 처리과정을 통해 양식을 스크립트(일반적으로 PHP, 자바 또는 CGI 과정/이와 유사한 과정)에 전송한다. 스크립트를 실행할 때 스트립트를 통해 완전히 새로운 페이지가 전송된다. 그 페이지는 데이터가 작성된 새로운 양식의 HTML/확인 페이지 또는 원 양식에 기입된 데이터에 근거해 선택된 옵션이 포함된 페이지일 수 있다. 물론, 서버 상의 스크립트/프로그램이 처리되면서 새로운 양식을 다시 보내는 동안 사용자는 대기해야 한다. 서버로부터 데이터를 다시 받을 때까지는 스크린 상에 아무 것도 없게 되며 결국 대화성은 낮게 된다. 사용자는 즉각적으로 응답을 받지 못하며 데스크톱 애플리케이션 상에서 작업하는 기분이 들지 않게 된다.

Ajax는 근본적으로 자바 스크립트 기술 및 웹 양식 및 서버 간의 XMLHttpRequest 객체를 결합한다. 사용자가 웹 양식을 기입할 때 데이터는 직접 서버 스크립트에 전송되지 않고 자바 스크립트 코드에 전달된다. 대신 자바 스크립트 코드는 양식 데이터를 포착해 Request를 서버에 전송한다. 이 과정이 일어나는 동안, 사용자 스크린 상의 양식은 순식간에 나타나거나 깜빡이거나 사라지거나 정지하지 않는다. 즉 자바 스크립트 코드는 몰래 Request를 전송하며 사용자는 Request가 만들어졌는지도 알지 못한다. 게다가 Request를 비동기적으로 전송하기 때문에 더 좋은 상황이 된다. 이는 자바 스크립트에서 서버 응답을 그냥 대기하지 않는다는 것을 의미한다. 따라서, 사용자는 데이터를 계속 기입하고 화면이동하고 애플리케이션을 사용한다.

그런 다음 서버는 자바 스크립트 코드(웹 양식에 대해 아직도 대기 중임)에 데이터를 다시 전송한다. 자바 스크립트 코드에서는 데이터와의 상호기능을 결정하며 연속적으로 양식 필드를 업데이트 하면서 애플리케이션에 즉각적인 응답을 준다. 결국 사용자는 양식을 제출/재생하는 작업 없이 새로운 데이터를 얻게 된다. 자바 스크립트 코드는 데이터를 얻고 계산도 수행하며 또 다른 Request를 전송하며 이런 모든 과정은 사용자 개입 없이도 된다! 이것이 바로 XMLHttpRequest 객체의 장점이다. XMLHttpRequest 객체는 서버와 같이 커뮤니케이션을 주고받고 사용자는 그 과정에서 벌어지는 과정을 알지 못한다. 이로 인해 데스크톱 애플리케이션과 마찬가지로 동적, 상호 반응적인 고도의 양방향 경험을 얻게 되지만 그 속에 인터넷의 모든 장점이 담겨 있다.

자바 스크립트에 대한 부가사항

일단 XMLHttpRequest에 대해 다루게 되면 나머지 자바 스크립트 코드는 상당히 평범한 것들이다. 사실 다음과 같은 기본적인 작업에 자바 스크립트 코드를 이용한다.

  • 양식 데이터 얻기: 자바 스크립트 코드로 HTML 양식에서 데이터를 꺼내 이를 서버에 전송하는 작업이 간단해진다.
  • 양식 상의 값 변환: 필드 값 설정에서 연속적인 이미지 교체작업에 이르는 양식 업데이트 작업 또한 간단하다.
  • HTML 및 XML 구문분석: 자바 스크립트 코드를 이용해 DOM(다음 섹션 참조)을 처리하고 서버에서 다시 전송하는 HTML 양식 및 임의의 XML 데이터에 관한 구조를 다루게 된다.

첫 번째 두 항목에 대해서 여러분은 Listing 2에 나온 대로 getElementById()에 익숙해지려 할 것이다.


Listing 2. 자바 스크립트 코드에서의 필드 값 포착 및 설정
                
// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;

// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];

Ajax 애플리케이션에서 특별히 획기적인 사항은 없고 상기 사항 정도면 충분하다. 이에 대해 상당히 복잡한 건 없다는 사실을 깨달아야 한다. 일단 XMLHttpRequest만 정복하면 Ajax 애플리케이션에서 나머지는 대부분 Listing 2에 나온 바와 같이 상당히 독창적인 HTML과 결합된 단순 자바 스크립트 코드다. 그런 다음 가끔 약간의 DOM 작업이 발생하게 된다. 이에 관해 살펴 보자.

DOM으로 종료하기

DOM, 즉 문서 객체 모델이라는 것이 있는데 이는 아주 중요하다. DOM에 대해 듣는 것은 그다지 어렵지 않다고 하는 사람들이 있다. HTML 디자이너에 의해서는 종종 사용되지 않으며 하이-엔드 프로그래밍 작업으로 들어가지 않는 한은 JavaScript 코더에서 흔치 않은 것이 바로 DOM이다. 종종 과중-업무 Java 및 C/C++ 프로그램 상에서 DOM을 종종 많이 활용하게 된다. 사실은 DOM이 배우기 어려운 특성 때문에 명성이 자자해 그 프로그램 상에서 종종 사용하는 것이 아닌가 싶다.

다행히도 JavaScript 기술에 있어 DOM을 활용하는 일은 쉽고 대부분 직관적이다. 이 시점에서 필자는 DOM 사용법에 관해 보여 주고 적어도 이에 대한 몇 가지 코드 예를 제시하려 하지만 이 글의 의도와는 벗어나는 것 같다. DOM에 관해 대략적으로 다루는 것 없이도 Ajax에 대해 깊이 다룰 수 있다. 필자는 차후의 글에서 다시 DOM에 관해 다루려 한다. 하지만 지금 상황에서는 언급하지 않으려 한다. JavaScript 코드와 서버 사이에 XML을 이리저리 전송하고 HTML 양식을 변화시킬 때 DOM에 대해 자세히 다루게 될 것이다. 지금은 DOM없이 효과적인 Ajax 애플리케이션을 작동하는 게 쉬우므로DOM은 논외로 한다.

Request 객체 얻기

Ajax 애플리케이션에 관한 기본적 개념에 대해 배웠으면 몇 가지 특수사항에 대해 살펴 보자. XMLHttpRequest 객체는 Ajax 애플리케이션에서 중요하므로, 아마도 많은 이들에게는 생소한 것일 수도 있다. 거기서 필자는 논의를 시작한다. Listing 1에서 보다시피, XMLHttpRequest 객체를 생성, 사용하는 것은 상당히 쉬워야 한다. 잠깐만 기다려 보시라.

수년 동안 브라우저에 관한 논란은 끊이지 않았고 동일한 브라우저로는 아무 것도 얻을 수 없다는 사실을 기억하는가? 믿건 말건, 소규모 브라우저에서도 이와 같은 논쟁은 끊이지 않고 있다. 더군다나 놀라운 사실은 XMLHttpRequest가 이 논란의 희생양 중 하나라는 것이다. 따라서 XMLHttpRequest 객체를 작동시키기 위해선 몇 가지 다른 작업을 해야 한다. 단계별로 설명하겠다.

Microsoft 브라우저 다루기

Microsoft 브라우저, Internet Explorer는 XML을 다룰 시 MSXML 구문분석계를 사용한다.(참고자료) Internet Explorer 상에서 다뤄야 할 Ajax 애플리케이션을 작성할 시 독특한 방식으로 XMLHttpRequest 객체를 작성해야 한다.

하지만 그렇게 간단한 작업은 아니다. Internet Explorer에 설치된 JavaScript 기술 버전에 따라 MSXML 버전도 변하게 되며 실지로 2개의 버전이 있다. 따라서 두 경우를 다루는 코드를 작성해야 한다. Microsoft 브라우저 상에서 XMLHttpRequest 객체를 생성하는 데 필요한 코드에 관해선 Listing 3을 보라.


Listing 3. Microsoft 브라우저 상에서 XMLHttpRequest 객체 생성
                
var xmlHttp = false;
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}

모든 작업이 정확히 맞아떨어지는 것은 아니다. 하지만 그래도 상관없다. 이 시리즈가 끝나기 전에 JavaScript 프로그래밍, 에러 취급 및 조건부 번역 및 기타 사항에 관해 자세히 다루게 될 것이다. 지금 현 상태에서는 두 가지 중심 라인만 다루고자 한다.

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

and

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.

간단히 말해서, 이 코드로 MSXML의 한 버전을 이용해 XMLHttpRequest 객체 생성을 기한다. 하지만 객체가 생성되지 않는 경우 다른 버전을 사용해 XMLHttpRequest 객체를 생성한다. 두 코드 다 작동되지 않는 경우 xmlHttp 변수는 거짓으로 설정되고 작동되지 않는 것이 있다는 것을 코드에 알려 준다. 그럴 경우, 비-Microsoft 브라우저가 있을 가능성이 있다. 따라서 객체 생성을 위해선 다른 코드를 사용해야 한다.

Mozilla 및 Microsoft 브라우저 다루기

인터넷 브라우저를 선택하지 않거나 비-Microsoft 브라우저를 작성할 경우 다른 코드가 필요하다. 사실, 이 라인은 Listing 1에서 봤던 단순 코드라인이다.

var xmlHttp = new XMLHttpRequest object;.

이 단순한 라인으로 Mozilla, Firefox, Safari, Opera 및 임의의 양식/형태에서 Ajax애플리케이션을 지원하는 기타 비-Microsoft 브라우저에서 XMLHttpRequest 객체를 생성한다.

지원기능 통합

여기서 모든 브라우저를 지원하는 것이 중요하다. Internet Explorer/비-Microsoft 브라우저에서만 작동되는 애플리케이션을 작성하는 사람이 어디 있겠는가? 또한 더 심한 경우, 애플리케이션을 두 번 작성하고자 하는가? 물론 아니라고 믿는다. 따라서 코드에선 Internet Explorer 및 비-Microsoft 브라우저를 지원하는 기능이 포함되어야 한다. Listing 4에서는 다중-브라우저 방식으로 작동하는 코드에 대해 나와 있다.


Listing 4. 다중 브라우저 방식으로 XMLHttpRequest 객체 생성하기
                
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
  xmlHttp = new XMLHttpRequest();
}

지금 현재로선, 주석 및 @cc_on와 같은 어려운 태그를 무시한다. 이들은 다음 글에서 깊이 다룰 JavaScript 컴파일러 명령으로 오로지 XMLHttpRequest 객체 상에만 초점이 맞추어져 있다. 이 코드에 관한 핵심은 세 가지 과정으로 요약된다.

  1. 변수 xmlHttp를 생성해 앞으로 생성할 XMLHttpRequest 객체를 참조한다.
  2. Microsoft 브라우저에서의 객체를 시도, 생성한다.
    • Msxml2.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
    • 과정이 실패할 경우, Microsoft.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
  3. xmlHttp가 아직도 설정되지 않은 경우 비-Microsoft 방식으로 XMLHttpRequest 객체를 생성한다.

위 과정 끝 단계 시 사용자가 실행하는 브라우저 종류에 관계없이 xmlHttp의 경우 유효한 XMLHttpRequest 객체를 인용한다.

보안

보안이란 무엇인가? 오늘날 브라우저는 사용자들에게 보안 레벨을 올리고 JavaScript 기술을 생성하며 브라우저 옵션을 해제하는 기능을 제공한다. 이 경우 코드가 작동되지 않는 경우도 있을 수 있다. 그 때 발생하는 문제를 적절하게 다뤄야 한다. 이에 관한 내용은 적어도 기사 한 분량을 차지할 정도라 나중에 다루기로 하겠다.(긴 시리즈가 될 것 같다, 그렇지 않은가? 하지만 걱정 마시라. 과정을 다 배우고 나면 이와 관련된 모든 사항을 숙달할 테니까.) 현재로선 강력하지만 완전하지 않은 코드를 작성하는 중이다. 이 코드는 Ajax 애플리케이션을 관리하는 데 좋다.

Ajax 세계에서의 Request/Response

인제 Ajax 애플리케이션에 대해 이해하고 XMLHttpRequest 객체 및 객체 생성에 관한 기본적인 개념을 얻는다. 자세히 읽다 보면 Ajax 애플리케이션은 웹 애플리케이션에 제출되는 HTML 양식보단 서버 상의 임의의 웹 애플리케이션에 대화하는 JavaScript 기술이라는 사실을 알게 된다.

그러면 빠진 부분은 어떤 것인가? 실질적인 XMLHttpRequest 객체 사용법이다. 이 객체는 작성하는 각각의 Ajax 애플리케이션에서 일정 형태로 사용하는 중요 코드라 Ajax 애플리케이션이 포함된 기본 Request/응답 모델 모양을 통해 객체 사용법을 빨리 익힌다.

Request 만들기

새로운 XMLHttpRequest 객체가 있는 경우 이를 시험해 보자. 먼저 웹 페이지에서 호출하는 JavaScript 방법이 필요하다.(사용자가 텍스트에서 입력하거나 메뉴에서 옵션을 선택할 시와 같음.) 그 다음, 거의 모든 Ajax 애플리케이션에서의 동일한 기본 아웃라인을 따른다.

  1. 웹 양식으로부터 필요한 모든 데이터 얻기
  2. 연결할 URL 구축
  3. 서버 연결
  4. 서버 실행 종료 시 서버 실행 기능 설정
  5. Request 전송

Listing 5는 위의 순서대로 5단계를 진행하는 Ajax 방법의 예에 관해 나와 있다.


Listing 5. Ajax가 포함된 Request 만들기
                
function callServer() {
  // Get the city and state from the web form
  var city = document.getElementById("city").value;
  var state = document.getElementById("state").value;
  // Only go on if there are values for both fields
  if ((city == null) || (city == "")) return;
  if ((state == null) || (state == "")) return;

  // Build the URL to connect to
  var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);

  // Open a connection to the server
  xmlHttp.open("GET", url, true);

  // Setup a function for the server to run when it's done
  xmlHttp.onreadystatechange = updatePage;

  // Send the request
  xmlHttp.send(null);
}

Ajax 코드에 관한 많은 것이 명백하다. Ajax 코드의 첫번째 비트는 몇 가지 양식 필드 값을 포착하는 기본 JavaScript 코드를 사용한다. 그런 다음 이 코드에서는 연결 최종 목적지로 PHP 스크립트를 설정한다.

PHP 스크립트의 URL을 지정한 다음(양식에서 나온) 단순한 GET 매개변수를 이용해 이 URL에 도시 및 국가를 추가한다. 그 다음 연결하면 먼저 XMLHttpRequest 객체가 작동되는 것을 보게 된다. 연결방법은 연결 URL 뿐만 아니라, GET 매개변수에도 나와 있다. 최종 매개변수를 true로 설정한 경우, 이 매개변수에선 비동기식 연결(Ajax를 만든다.)을 요구한다. false로 설정한 경우엔 Request를 만들 시 서버 상에서 Ajax에서의 JavaScript 코드가 대기하고 응답을 받을 때 코드가 지속된다. 사용자는 최종 매개변수를 true로 설정하면서 서버에서 배경에 있는 Request를 처리하는 동안 사용자는 웹 양식(심지어는 기타 JavaScript 방식)을 여전히 사용한다.

한편 xmlHttp(이것은 XMLHttpRequest 객체의 인스턴스라는 사실을 기억하라.)의 onreadystatechange 속성으로 서버 실행이 종료될 시(5분/5시간 내에 종료될 수 있음) 서버 기능을 명령한다. 이 코드는 서버 상에서 대기하지 않기 때문에 서버가 기능을 인식해 서버에 응답할 수 있도록 하는 게 필요하다. 이 경우 서버에서 Request를 처리하면서 종료 시 이른바 updatePage()라 불리는 특수 방법을 트리거한다.

최종적으로 send() 코드를 0(null) 값으로 호출한다. 데이터를 추가해 이를 서버에 전송하므로 Request에는 추가해서 보낼 게 없다. 이렇게 되면 Request를 발송하고 서버는 서버에 요구된 기능을 실행한다.

이 코드에서 나오는 것이 없는 경우, 코드가 상당히 간단하다는 것을 명심하라. 이 코드는 Ajax 애플리케이션의 비동기적 특성을 제외하고는 상당히 단순하다. 이 코드를 통해 복잡한 HTTP Request/응답 코드보다는 근사한 애플리케이션 및 인터페이스에 완전 초점을 맞추도록 한다는 사실을 여러분은 높게 평가할 것이다.

Listing 5의 코드는 코드를 얻는 방법만큼이나 쉽다. 데이터는 단순 텍스트이고 Request URL의 일부로 포함된다. GET 매개변수는 더 복잡한 POST대신 Request를 전송한다. 여기에 덧붙일 XML/컨텐츠 헤더가 없고 Request 본체에 전송할 데이터도 없다. 이게 바로 Ajax 유토피아다.

그렇다고 미리 겁먹지 마라. 시리즈가 계속될수록 문제는 더 복잡해진다. 그 때는 POST Request를 전송하는 방법, Request 헤더 및 컨텐츠 형식을 설정하는 방법, 메시지에 XML을 설정하는 방법 및 Request에 보안기능을 추가하는 방법을 배우게 되는데 배우는 목록만 해도 상당히 길다! 지금은 이런 어려운 주제에 대해 신경 쓰지 말자! 그냥 기본만 충실하게 익히면 Ajax 전체 툴을 구축하게 된다.

응답 취급과정

이제 서버 응답을 실지로 취급해야 한다. 이 시점에서는 정말로 두 가지 사항만 알면 된다.

  • xmlHttp.readyState 속성이 4와 같을 때까지는 어떤 작업도 해선 안 된다.
  • 서버는 xmlHttp.responseText 속성에 응답한다.

2가지 항목 중 첫번째 항목인 준비 상태에 관해선 다음 글에서 대부분 다룰 것이다. 그 때는 HTTP Request 단계에 대해 알고 싶은 것 이상으로 배우게 된다. 지금 현재로선, xmlHttp.responseText 속성 값 4를 단순 점검하는 경우, 작업이 계속 진행된다.(다음 글에서 기대할 만한 사항이 나오게 된다.) 서버 응답을 얻기 위해 xmlHttp.readyState 속성을 사용하는 과정인 두 번째 항목은 쉽다. Listing 6Listing 5에서 전송된 값에 근거해 서버에서 호출하는 방법에 관한 예를 보여준다.


Listing 6. 서버 응답 취급하기
                
function updatePage() {
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    document.getElementById("zipCode").value = response;
  }
}

다시 보면, xmlHttp.readyState 코드는 그리 어렵거나 복잡하지 않다. 이 코드는 서버에서 해당 준비 상태로의 호출을 대기하고 서버에서 다시 복귀되는 값(이 경우, 사용자 기입 도시 및 국가에 대한 ZIP 코드)을 사용해 또 다른 형태의 양식 필드를 설정한다. 그 결과, zipCode 필드는 ZIP 코드와 함께 갑자기 나타난다. 하지만 사용자는 버튼을 클릭해서는 안 된다! 그게 바로 이전에 말했던 데스크톱 애플리케이션이다. Ajax 코드에는 응답성, 동적 상태 외의 더 많은 것이 있다. 독자들은 zipCode가 정상 텍스트 필드라는 것을 눈치챘을지도 모른다.

일단 서버에서 zipCode를 복귀시키고 updatePage() 방식으로 도시/국가 ZIP 코드와 함께 zipCode 필드 값을 설정하는 경우 사용자는 값을 무효로 한다. 값을 무효로 하는 데는 두 가지 이유가 있다. 예에서 나오는 상황을 단순화시키고, 때로는 사용자가 서버에서 명령하는 것을 무효로 하기 위해서다. 이 두 가지를 명심하라. 좋은 사용자-인터페이스 설계를 위해 중요하다.

웹 양식 다루기

그러면 이 글에서 다룰 게 남아 있는가? 그다지 많지 않다. 양식에 기입할 정보를 포착해 이를 서버에 전송하고 응답에 관해 취급할 또 다른 JavaScript 방법을 제공하면서 심지어는 다시 응답될 때 필드 값을 설정하기까지 하는 JavaScript 방법을 다룬다. 여기서는 첫번째 JavaScript 방법을 호출해 전 과정을 시작하기만 하면 된다. 분명 HTTL 양식에 버튼을 추가하지만 2001년 버전과 거의 동일하다고 생각되지 않는가? Listing 7과 같이 JavaScript 기술을 활용한다.


Listing 7. Ajax 프로세스 시작
                
<form>
 <p>City: <input type="text" name="city" id="city" size="25" 
       onChange="callServer();" /></p>
 <p>State: <input type="text" name="state" id="state" size="25" 
       onChange="callServer();" /></p>
 <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p>
</form>

이런 단면이 루틴 코드의 한 단면 이상을 보여준다고 생각된다면 맞는 말이다. – 그렇다! 사용자가 도시/국가 필드에 관한 새로운 값을 입력할 경우 callServer() 방식을 전송한 다음 Ajax 애플리케이션이 시작된다. 이제 여러 상황을 다룰 만하다고 느껴지기 시작하는가? 좋다! 바로 그거다!

맺음말

이 시점에서 적어도 리소스 란에서 Ajax 애플리케이션에 관해 깊숙이 알려고 하는 경우, 첫번째 Ajax 애플리케이션을 작성할 준비가 되어 있지 않을 게다. 하지만 이런 애플리케이션이 작동하는 기본 개념 및 XMLHttpRequest 객체의 기본 개념을 이해하기 시작한 경우 이 객체, JavaScript-서버 간 대화 취급방식, HTML 양식 취급 및 심지어 DOM 관리 방식까지 모든 것을 배워야 한다.

지금 현재로선, Ajax 애플리케이션이 얼마나 강력한 툴인지 생각하는 데 시간을 보낸다. 버튼만 클릭할 뿐만 아니라 필드에 입력하고 콤보 상자에서 옵션을 선택하고 심지어는 마우스를 스크린 주위에 끄는 경우 응답하는 웹 형식을 상상해 본다. 비동기식의 정확한 의미 및 Request 상에서 응답하기 위해 서버 상에서 실행하지만 대기하지 않는 JavaScript 코드에 관해 생각해 본다. 여러분이 부딪치는 문제의 종류는 어떤 것인가? 어떤 영역의 문제에 주의를 기울일 것인가? 프로그래밍에 이 새로운 접근방식을 설명하기 위해 양식 설계를 변환하는 방법은 어떤 것인가?

이런 문제에 관해 실지로 생각할 시간을 보낸다면 잘라 붙이는 코드를 가지고 이를 잘 이해하지 못하는 애플리케이션에 포함시키는 것보다는 훨씬 더 낫다. 다음 글에서는 이와 같은 개념을 실제 작업에 응용해 본 작업에서처럼 애플리케이션을 만들어야 하는 코드에 관한 자세한 정보를 제공하기로 한다. 그 때까지 Ajax 애플리케이션의 가능성을 마음껏 즐겨라.

'AJAX' 카테고리의 다른 글

PJax ?  (0) 2012.08.24
Dialog  (0) 2012.06.19
AJax JSON 데이터 가져오기의 형식 .  (0) 2012.05.24
Posted by 사라링
 

1.

    $.ajax({
            "url" : "tableData.jsp",
            "type" : "get",
            "dataType": "json",
            "data" : {"dataType":"init"},
            "success" : function(data){
                alert("가져온 데이터 입니다 . "+data);
                var str = "<select id='mainTableList'>";
                str +="<tr >";
                $.each(data,function(i,v){
                    //데이터 인풋

                  str +="<td>"+ v.mem_id+"</td>; 

});
                str +="</tr>";
                $("#tableList").html(str);
               
            },
            "error" : function(info, xhr){
                if(info.readyState == '4'){
                 alert('문제가 발생했습니다.\n상태코드 : ' + info.status+ '\n\n' + info.responseText);
                }
                else{
                 alert('문제가 발생했습니다.\n잠시후 다시 시도해 주세요.\n 상태코드 : ' +info.status);
                }
               }
        });

tableData.jsp 에서 JSON 타입으로 데이터를 가져 오며. 그것에 대하여 성공(success),또는 실패로 구분할수 있다.

가져온 데이터에 대하여  i 는 index v 는 i번째 (Ajax 는 1부터 시작)의 value 를 뜻한다. 데이터 에 대해서는 밑에서 말하겠다.



2.

                $.getJSON("memberData.jsp",
                     function(data){
                  //  alert(data);
                    var str = "<table id='mem_list' align='center'border='1' bordercolor='yellow' >";
                    str += "<tr bgcolor='silver'><th>회원ID</th><th>회원성명</th><th>주민번호</th><th>우편번호</th>";
                    str +="<th>주 소</th><th>회사전화</th><th>핸드폰</th><th>이메일</th></tr>";
                    $.each(data, function(i, v){
                        str += "<tr id='mem_select'>";
                        str += "<td class='mem_id'>" + v.mem_id + "</td>";
                        str += "<td>" + v.mem_name + "</td>";
                        str += "<td>" + v.mem_regno + "</td>";
                        str += "<td>" + v.mem_zip + "</td>";
                        str += "<td>" + v.mem_add + "</td>";
                        str += "<td>" + v.mem_comtel + "</td>";
                        str += "<td>" + v.mem_hp + "</td>";
                        str += "<td>" + v.mem_mail + "</td></tr>";
                    });
                    str += "</table>";
                    $("#memList").html(str);
                });


JSON 데이터 가져 오기의 두번째 형태 이다.

여기서는 memberData.jsp 로 바로 데이터를 보내서 가져오는 형태 이다. 간단 하지만 에러가 나도 어디서 문제 인지 알수 없는 문제가 있다. 하지만

코딩이 간단 하기때문에 구현을 쉽게 할수 있다.

"mem_id="+mem_id , 를 추가 하여 파라미터 값으로 보내 줄수 도 있다.



$("#mem_select").live("click", function(){
                    var mem_id = $(this).children(".mem_id").text().trim();
                    $.getJSON("memberData.jsp",
                     "mem_id="+mem_id,
                      function(data){
                          $.each(data,function(i,v){
                        $("#mem_id").val(v.mem_id);
                        $("#mem_pass").val(v.mem_pass);
                        $("#mem_name").val(v.mem_name);
                        $("#mem_regno").val(v.mem_regno);
                        $("#mem_bir").val(v.mem_bir);
                        $("#mem_zip").val(v.mem_zip);
                        $("#mem_add").val(v.mem_add);
                        $("#mem_hometel").val(v.mem_hometel);
                        $("#mem_comtel").val(v.mem_comtel);
                        $("#mem_hp").val(v.mem_hp);
                        $("#mem_mail").val(v.mem_mail);
                        $("#mem_job").val(v.mem_job);
                        $("#mem_like").val(v.mem_like);
                        $("#mem_memorial").val(v.mem_memorial);
                        $("#mem_memorialday").val(v.mem_memorialday);
                        $("#mem_mileage").val(v.mem_mileage);
                        if (v.mem_delete != "y") {
                            $("#mem_delete").attr("checked", true);
                        }
                        });
                    });
                   
                });

 

위 예제는 1번2 번에서 가져온 데이터에 대하여 div 의 id 값에 html 형식으로 넣어서 구현 되어진 것에 대하여

live 형식으로 클릭 되었을때 이벤트가 실행 되도록 하는 메서드 이다. 반드시 live 형식으로 구현 해야 하는데 그 이유는 맨처음 시작시에 JSON 데이터 메서드가 시작전에

는 만들어지지 않은  객체 이기 때문에 일반 형식으로 구현시에 없는!!! 객체를 구현 하라고 명령 하는 것임으로 실행이 안된다.



대상이 되어 지는 DATA .jsp의 형식은 대략 이러 함.

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="java.sql.*"%>
<%@page import="kr.or.ddit.db.ConnectionProvider"%>
<%@page import="java.sql.Connection"%>
<%@ page import = "kr.or.ddit.db.*" %>
<% request.setCharacterEncoding("UTF-8");
    String mem_id=request.getParameter("mem_id");
    System.out.print(mem_id);
%>   
[

<%
    Connection conn = null;
    PreparedStatement psmt = null;;
    ResultSet rs = null;
   
    try{
    conn =ConnectionProvider.getConnection();
   
    if(mem_id==null){
    psmt = conn.prepareStatement("select * from member");
    }else {
    psmt = conn.prepareStatement("select * from member where mem_id=?");
        psmt.setString(1, mem_id);
    }
    rs=psmt.executeQuery();
   
    %>
   
   
    <%
    while(rs.next()){
       
        if(rs.getRow()>1){
            out.print(",");
        }
    %>
    {
    "mem_id"  : "<%=Util.toJS(rs.getString("mem_id"))%>",
    "mem_pass"  : "<%=Util.toJS(rs.getString("mem_pass"))%>",
    "mem_name"  : "<%=Util.toJS(rs.getString("mem_name"))%>",
    "mem_regno"  : "<%=Util.toJS(rs.getString("mem_regno1"))%> - <%=Util.toJS(rs.getString("mem_regno2"))%>",
    "mem_bir"  : "<%=Util.toJS(rs.getString("mem_bir")).subSequence(0, 10)%>",
    "mem_zip"  : "<%=Util.toJS( rs.getString("mem_zip"))%>",
    "mem_add"  : "<%=Util.toJS(rs.getString("mem_add1"))%> <%=Util.toJS(rs.getString("mem_add2"))%>",
    "mem_hometel"  : "<%=Util.toJS(rs.getString("mem_hometel"))%>",
    "mem_comtel"  : "<%=Util.toJS(rs.getString("mem_comtel"))%>",
    "mem_hp"  : "<%=Util.toJS(rs.getString("mem_hp"))%>",
    "mem_mail"  : "<%=Util.toJS(rs.getString("mem_mail"))%>",
    "mem_job"  : "<%=Util.toJS(rs.getString("mem_job"))%>",
    "mem_like"  : "<%=Util.toJS(rs.getString("mem_like"))%>",
    "mem_memorial"  : "<%=Util.toJS(rs.getString("mem_memorial"))%>",
    "mem_memorialday"  : "<%=Util.toJS(rs.getString("mem_memorialday")).subSequence(0, 10)%>",
    "mem_mileage"  : "<%=Util.toJS(rs.getString("mem_mileage"))%>",
    "mem_delete"  : "<%=Util.toJS(rs.getString("mem_delete"))%>"
    }
    <%
    }
    }catch(SQLException e){
        e.printStackTrace();
    }finally{
        if(rs!=null) try{rs.close();}catch(Exception e){}
        if(psmt!=null) try{psmt.close();}catch(Exception e){}
        if(conn!=null) try{conn.close();}catch(Exception e){}
   
    }

%>
]



'AJAX' 카테고리의 다른 글

PJax ?  (0) 2012.08.24
Dialog  (0) 2012.06.19
Ajax 란  (0) 2012.05.24
Posted by 사라링

SQL>SELECT TABLE_NAME
        FROM USER_TABLES
        WHERE TABLE_NAME = ’찾을 테이블 이름’
        -->찾을 테이블 이름은 대문자여야 됩니다.

Posted by 사라링

canvas 사이트 모음 .

2012. 5. 24. 10:21
하나는 http://mrdoob.com/ 이고

하나는 http://www.nihilogic.dk/labs/ 입니다.



'HTML5.0' 카테고리의 다른 글

캔버스 간단한 마우스 그리기  (0) 2012.06.04
캔버스 이미지 뛰우기 .  (0) 2012.06.04
Canvas  (0) 2012.05.22
html4.0 을 html 5.0 으로 변환  (0) 2012.05.14
Aptana 설치  (0) 2012.05.14
Posted by 사라링

Canvas

2012. 5. 22. 20:21

브라우저 위의 그림판
HTML5 의 많은 새로운 기능 중 가장 자주 언급되어 왔던 것이 아마 Canvas(캔버스) 일 것이다
Canvas 는 Web Workers 나 Web Storage와 같은 다른 HTML5 스펙보다 덜 기술적이며 보다 직관적이다.
개발자 뿐만 아니라 비개발자들 역시 Canvas의 개념을 쉽게 이해할 수 있고 흥미를 보여왔기 때문에 가장 먼저 그리고 가장 흔하게 소개된 HTML5 기술인 것이다

Canvas 는 말 그대로 그림을 그릴 수 있는 화폭, 즉 그림판과 같다
그것도 다른 곳에 아닌 브라우저 위에서 동작하는 그림판인 것이다

Canvas 위에 선, 도형, 텍스트, 이미지와 같은 그래픽을 표현할 수 있고 색깔, 그림자, 패턴과 같은 여러 효과를 적용할 수 있다. 그리고 기본적으로 Canvas 는 2차원 그래픽 표현을 위한 스펙이지만 추가로
WebGL를 기반으로 하는 3D 그래픽용 Canvas 의 스펙 개발이 진행중이다

참고: WebGL은 오픈 그래픽 라이브러리인 OpenGL(OpenGL ES 2.0)에 기반한 웹 표준 그래픽 라이브러리이다. WebGL을 이용하면 브라우저에 별도의 플러그 인 없이 완벽하게 하드웨어 가속되는 3D그래픽을 표현할 수 있게 된다. 주요 브라우저 벤더사인 애플, 구글, 모질라 및 오페라와 하드웨어 업체인 AMD 및 엔비디아 등이 WebGL Working Group 멤버로 활동하고 있다. 그리고 구글의 웹 용 3D API O3D 플러그 인 기술을 포기하고 WebGL 을 선택했다 


브라우저 지원 현황
브라우저 지원 현황 역시 다른 HTML5 기술보다 더 일반적이다
다시 말해 대부분의 브라우저에서 Canvas를 지원한다는 의미이다


그림1. 브라우저별 2D Canvas 지원 현황 (출처: http://caniuse.com/)

IE9 이전 버전에서 Canvas 지원하기
현재까지 출시된 IE8 까지는 HTML5 지원이 거의 되지 않는다
Canvas 역시 IE9 이전 버전에서는 동작하지 않는다
다만 구글에서 제공하는 크롬프레임을 설치하면 IE9 이전버전에서도 HTML5 를 동작시킬 수 있다

그러나 Canvas의 경우 더 쉽게 IE에 적용할 방법이 있다.
ExplorerCanvas 라이브러리를 이용하면 이전버전의 IE에서도 Canvas를 동작시킬 수 있게 된다
(ExplorerCanvas는 이전 버전의 IE에서 Canvas API가 동작할 수 있도록 해 주는 오픈소스 자바스크립트 라이브러리이다)
ExplorerCanvas 다운로드: http://code.google.com/p/explorercanvas/

다운받은 excanvas.js 스크립트 파일을 Canvas가 구현된 HTML 파일의 헤더 영역에 다음과 같이
정의하여 IE일 경우 이 스크립트가 적용되도록 처리하면 된다
<html>
<head>
 <!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
  ...



Canvas 학습 지원 사이트
Canvas로 구현할 수 있는 것은 아주 많다
개념적으로 보편적인 기술인 만큼 그 응용 개발 역시 매우 다양하게 펼칠 수 있다
그러나 응용도 기본이 갖춰져야 제대로 되는 만큼 기본사용법의 정확한 숙지가 필요하다

이 글에서도 기본적인 사용법과 간단한 데모를 작성해 보겠지만,
그전에 Canvas 학습을 도와주는 훌륭한 사이트가 있어 소개한다

이 두 사이트에서 제공하는 Canvas 튜토리얼은 정확한 기본기를 갖추고 응용력을 기르는데 충분한 도움을 줄 것이다. Canvas를 적용할 서비스는 굉장히 많으며 특히 게임과 같은 동적이고 화려한 그래픽이 필요한 서비스에는 활용도가 무궁무진할 것이다. 잘 정리된 기본 학습 도구를 활용하는 것이 매우 중요하므로 위 사이트들을 꼭 참고하기 바란다


Canvas 다루기
지금부터 Canvas를 다루는 기본적인 방법에 대해 알아 보도록 하자

<canvas> 태그와 그리기 컨텍스트
그림을 그리기 위해서는 제일 먼저 브라우저에 화폭이 준비되어 있어야 한다
<canvas>라는 마크업 태그를 이용하여 브라우저에 캔버스 영역을 지정할 수 있다
<canvas id="cv" width="400" height="300"></canvas>

HTML 문서에 <canvas> 태그를 삽입하는 것 만으로 브라우저에 그림판이 준비된다
다만 캔버스는 기본적으로 테투리가 없기 때문에 위 코드만으로는 브라우저에서 캔버스를 눈으로 확인하기는 힘들다. 따라서 스타일을 적용해 캔버스의 테두리를 보이게 하는 것이 좋을 수 있다
<canvas id="cv" width="400" height="300"
    style="position: relative; border: 1px solid #000;"></canvas>

그리고 이 캔버스를 이용해 그리기를 수행하려면 '그리기 컨텍스트'를 얻어야 한다
그리기 컨텍스트는 앞서 정의한 <canvas> DOM 객체의 getContext 메서드로 얻을 수 있다
var canvas = document.getElementById("cv"); //canvas의 DOM 객체를 얻는다
var context = canvas.getContext("2d");         //DOM 객체로부터 2D 컨텍스트를 얻는다

이후 그리기 작업은 '그리기 컨텍스트'를 통해 이루어진다

캔버스의 좌표
캔버스에 각종 도형 및 선과 같은 2차원 그래픽 작업을 할 때 각 점의 위치를 지정해야 하는데
이는 캔버스의 2차원 좌표가 기준이 된다
사각형 모양을 하고 있는 캔버스는 제일 왼쪽 상단 꼭지점이 (0,0) 시작점이 된다
(0,0) 시작점을 기준으로 그리고자 하는 도형의 가로 위치 x 와 세로위치 y 좌표를 지정하면 된다

그림2. Canvas의 좌표 (출처: http://diveintohtml5.org/canvas.html)


그리기 작업

1) 사각형 그리기
그리기의 가장 기본이 되는 도형이다. Canvas API 에서 사각형을 위한 함수를 따로 제공하고 있다
아래와 같은 사각형 함수인데, 모두 같은 매개변수를 취하고 있다
x,y : 사각형의 시작점 좌표(왼쪽 위 모서리 지점), width,height: 사각형의 너비,높이

fillRect(x, y, width, height)       : 색으로 채운 사각형을 그린다
strokeRect(x, y, width, height) : 선만 있는 사각형을 그린다
clearRect(x, y, width, height)   : 사각형 영역을 지운다

아래 그림은 간단한 사각형 그리기 샘플이다
차례로 속이 찬 사각형과, 윤곽만 있는 사각형, 그리고 절반이 지워진 사각형이다
아래 결과 화면과 코드를 참고하기 바란다



<!DOCTYPE html>
<html>
<head></head>
<body>
  <canvas id="cv" width="400" height="300" style="position: relative; border: 1px solid #000;"></canvas
</body>
</html>
<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");          
 
  context.fillRect(10,10,100,100);    //색으로채운 사각형
  context.strokeRect(120,10,100,100); //윤곽만 있는 사각형
 
  context.fillRect(230,10,100,100);   //색으로 채운 사각형
  context.clearRect(230,10,50,50);    //앞 사각형의 절반을 지움
</script> 


2) 각종 도형 및 선 그리기
사각형과는 달리, 삼각형, 오각형, 육각형 및 원과 같은 도형은 선들을 연결하여 직접 그려줘야 한다
완성된 도형은 선들의 집합체이며 각각의 선들을 패스(Path) 라 한다
(엄밀히 말하자면 각 선은 서브패스이며 서브패스 전체를 가리켜 패스라 한다)

결국 도형을 그린다는 것은 각 선을 연결한다는 의미이며 이는 패스(Path)를 그리는 과정인 것이다

패스(Path)그리기 순서
첫째, 패스 그리기를 시작을 알린다
: beginPath() 함수로 canvas에 패스그리기를 알린다. 이전의 패스는 모두 초기화된다

둘째, 패스 경로 즉 시작점과 종료점을 지정한다
: moveTo(x,y) 함수로 패스의 시작점을 지정하고 lineTo(x,y) 함수로 패스가 이어질 점을 지정한다
 
셋째, 패스 경로를 따라 실제로 그린다
: 이전 과정까지는 패스 즉 경로에 대한 정보를 셋팅하는 것이다
  실제 지정된 패스를 따라 선을 그려야 하는데, 이는 stroke(), fill()과 같은 잉크(ink)함수가 이용된다

삼각형 그리기
간단한 삼각형 그리기 샘플을 보자.
아래와 같은 삼각형을 그리기 위해 패스그리기를 수행한 예이다


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");          
 
  context.beginPath(); //패스 그리기 시작  
  context.moveTo(50,10); //패스 시작점 지정  
  context.lineTo(20 ,100); //패스 이동점 지정
  context.lineTo(80 ,100); 
  context.lineTo(50 ,10);  
  context.stroke();    //윤관선 그리기
  //context.fill();   //색 채우기
</script>

beginPath() 로 패스그리기의 시작을 알리고 moveTo()로 패스 시작점을 설정한다
그리고 lineTo() 를 이용하여 패스의 경로를, 그리는 방향 대로 이동한다
마지막으로 stroke()로 패스의 윤곽선을 그린다
주석처리된 fill() 함수로 패스를 그릴 경우 패스 속이 색(기존 검정색)으로 채워지게 된다 

이런식으로 삼각형은 물론, 사각형, 오각형,.. N각형의 도형을 맘껏 그릴 수 있다

원 그리기
앞서 살펴본 삼각형 그리기는 직선을 연결한 도형일 경우에는 적합하지만 곡선이나 원을
그릴 수는 없다. 즉 lineTo() 함수는 직선을 그리는 함수이다

원이나 곡선 역시 패스 그리기의 일종으로 앞서 살펴본 과정을 그대로 따른다
다만 직선을 그리는 함수인 lineTo() 대신 원을 그리는 함수인 arc() 나 배지곡선을 그리는 함수인 quadraticCurveTo() 함수를 이용하면 된다

간단한 원그리기 샘플을 살펴 보자


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");          
 
  context.beginPath(); //패스 그리기 시작   
  context.arc(70,70,50,0, 2*Math.PI, true); //원그리기 
  context.stroke();    //윤관선 그리기
</script>


패스 닫기
패스를 이용해 도형을 마음껏 그릴 수 있으려면 관련 학습을 조금 더 해야 한다
패스와 관련된 추가 학습은 다른 사이트를 참고하도록 하며 이 글에서는 명시적으로 패스를 닫는 closePath() 함수에 대해 알아보면서 패스 정리를 마치고자 한다

closePath()는 패스를 명시적으로 닫는 역할을 한다
반드시 사용해야 하는 것은 아니지만 명시적으로 closePath()를 호출해 주면
마지막 패스의 좌표와 시작좌표를 자동으로 연결해 주기 때문에 편리하다

다음은 앞서 살펴본 삼각형 그리기 예에서 마지막 패스를 생략하고 closePath()를 대신 사용하였다
즉 마지막 lineTo() 함수가 없어도 자동으로 시작점과 연결해 주기 때문에 결과는 동일하다
<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");          
 
  context.beginPath(); //패스 그리기 시작 
  context.moveTo(50,10); //패스 시작점 지정 
  context.lineTo(20 ,100); //패스 이동점 지정
  context.lineTo(80 ,100); 
  context.closePath();     //마지막 패스 이동점 대신 패스를 명시적으로 닫는다
  context.stroke();    //윤관선 그리기
</script>


스타일 및 효과
캔버스에 그리기 작업을 할 경우 별다른 스타일을 지정하지 않으면 기본 스타일이 적용된다
앞서 살펴본 샘플에서 도형의 안,팎의 색이 검정색이었던 것은 기본값이기 때문이다
스타일을 적용하면 도형의 색 지정 뿐만 아니라 그라데이션 효과, 그림자 효과등을 줄 수 있다

색 지정
우선 간단히 색을 지정하는 예를 보자. 앞서 살펴본 사각형 그리기 예에서 색을 지정한다
채우기 스타일은 fillStyle 로 윤곽선 스타일은 strokeStyle 로 색을 지정하면 된다
색을 지정할 때 blue, red 와 같은 문자는 물론 #ffffff 혹은 rgb(255,0,0) 등 모든 CSS 컬러를 사용할 수 있다. 색을 지정하지 않았을 땐 기본값으로 #000000(검정색) 이 된다


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");                 
 
  context.fillStyle = "blue";
  context.fillRect(10,10,100,100);    //파란색으로 채운 사각형
 
  context.strokeStyle = "red";
  context.strokeRect(120,10,100,100); //빨가색 윤곽선 사각형
</script>


그라데이션 효과
fillStyle 이나 strokeStyle를 통해 색깔 지정 뿐만 아니라 그라데이션 효과도 줄 수 있다
그라데이션은 선형그라데이션과 원형그라데이션 두 가지 종류가 있다

선형 그라데이션
: (x,y) 지점에서 (x1,y1) 까지 직선으로 색조가 변화한다
  createLinearGradient(x,y,x1,y1) 함수 이용

원형 그리데이션
: 중심이 (x,y), 반지름 r인 원에서 중심이 (x1,y1), 반지름이 r1 인 원 사이의 색조가 변화한다
  createRadialGradient(x,y,r,x1,y1,r1) 함수 이용

createXXXGradient 함수로 그라데이션의 형태를 지정한 후,
addColorStop(offset, color) 함수를 이용하여 각 지점에 이용될 색을 지정한다
offset는 0.0(시작점) 에서 1.0 (끝점) 사이의 위치 값을 나타내며 해당 위치의 색을 지정한다

사각형에 선형 그라데이션 효과를 준 예를 살펴 보자
두 사각형 모두 선형 그라데이션 효과를 준 것이며 직선 방향을 조정하여 가로,세로 효과를 줬다

(화살표는 색조 변화 방향을 나타냄)

<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");                 
 
  var gradient = context.createLinearGradient(0,0,100,0);
  gradient.addColorStop(0,"white");
  gradient.addColorStop(1,"blue"); 
  context.fillStyle = gradient;   
  context.fillRect(10,10,100,100); 
 
  gradient = context.createLinearGradient(0,0,0,100);
  gradient.addColorStop(0,"white");
  gradient.addColorStop(1,"red"); 
  context.strokeStyle = gradient;
  context.strokeRect(120,10,100,100);      
</script>


그림자 효과
선이나 도형에 그림자 효과를 줄 수 있다.
shadowOffsetX, shadowOffsetY 함수를 이용하여 원본 도형의 위치를 기준으로 그림자의 위치를 지정할 수 있으며 shadowColor 로 그림자 색상 shadowBlur로 그림자의 흐리기를 조정할 수 있다


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");                 
    
  context.shadowColor = "green";
  context.shadowOffsetX = 5;
  context.shadowOffsetY = 5;
  context.shadowBlur = 2; 
 
  context.fillStyle = "blue";
  context.fillRect(10,10,100,100);  
</script>



이미지 및 텍스트 그리기
캔버스에는 선이나 각종 도형 이외에도 이미지 파일을 삽입하거나 텍스트를 직접 그릴 수도 있다
캔버스에 텍스트 그리기를 이용하면 글자에 각종 효과를 줄 수 있는 장점이 있다
그리고 이미지 역시 각종 이미지 처리를 할 수 있다는 장점이 있겠다

텍스트 그리기
우선 캔버스에 텍스트를 그리는 예를 살펴 보자
다른 도형 그리기와 마찬가지로 채워진 텍스트 혹은 윤곽선만 있는 텍스트를 그릴 수 있다


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");                 
    
  var msg = "Hello, Canvas!"
 
  context.font = "20px '맑은 고딕'";
  context.fillText(msg, 10  ,50);
 
  context.font = "40px 'Tahoma'";
  context.strokeText(msg, 10  ,100);
</script>


이미지 그리기
drawImage 함수를 이용하여 캔버스에 이미지 파일을 삽입할 수 있다
주의할 점은 drawImage의 호출 시점이다. 이미지가 모두 로딩된 이후에 이 함수를 호출해야 한다
따라서 이미지 로딩이 완료될 때 발생하는 onload 이벤트에서 이 함수를 사용하는 것이 일반적이다

눈의 즐거움을 위해 손담비 사진을 이용해 샘플을 만들어 보자 ^.^
Image 객체의 onload 이벤트에서 drawImage 함수가 호출되는 것을 눈여겨 보기 바라며
이미지를 이용하여 사각형을 그릴 때 채우기 패턴으로 사용할 수도 있다
예에서는 손담비 이미지를 기반으로 패턴을 생성하여 사각형의 채우기 스타일로 사용하고 있다
그리고 회전효과도 가미했다(이미지 그리기와는 무관하지만...)


<script type="text/javascript">
  var canvas = document.getElementById("cv");
  var context = canvas.getContext("2d");                 
    
  var image = new Image();
 
  image.onload = function(){
    context.rotate(20*Math.PI/180);       //회전효과
   
    context.drawImage(image,30,10);   //이미지 그리기
   
    var pattern = context.createPattern(image,"repeat"); //반복패턴정의
    context.fillStyle = pattern;                                       //fill 패턴 지정
    context.fillRect(200,10,200,250);                                   //이미지로 사각형을 채운다     
  }
 
  image.src = "sondambi.bmp";
</script>


Canvas 초기화
그림을 그리다 모두 지우고 싶을 때가 있다
캔버스에 각종 그래픽 작업을 하다가 모든 것을 지우고 다시 시작하고 싶은,
일명 리셋(reset)을 하고 싶다면 매우 단순하게 초기화를 할 수 있다

캔버스의 너비나 높이 속성을 다시 설정하는 것만으로 캔버스는 완전 초기화 된다
캔버스에 그려진 내용 뿐만 아니라 그리기컨텍스트의 각종 속성도 기본값으로 돌아 온다

function resetCanvas(){
    canvas.width = canvas.width;       
  }


마무리 데모
이제 이 글을 마치기 전에 마무리 데모를 살펴 보자
사실 이 글에서 소개된 캔버스 다루기 내용은 극히 일부에 지나지 않는다.
2D 그래픽 처리와 관련한 다양한 기법과 API들이 존재한다.

반드시 관련 자료를 참고하여 추가 학습을 하길 권하며 3D 캔버스인 WebGL도 필요하다면 관련 자료를
찾아 보기 바란다

마지막 데모는 마우스로 그림을 그릴 수 있는 그림판이다
캔버스에 마우스를 데고 자유자재로 움직이면, 선이 마우스를 따라 그려지는 샘플이다

아래 데모 실행화면을 보자. 필자가 캔버스에 대고 그린 그림이다 -.-;


전체 소스
<!DOCTYPE html>
<html>
  <head>
    <title>Canvas Paint Example</title>      
    <!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->   
  </head>
  <body>
   <div id="container">
     <canvas id="drawCanvas" width="400" height="300"
            style=" position: relative; border: 1px solid #000;"></canvas>
</div>
</body>
</html>
<script type="text/javascript">   
if(window.addEventListener){
    window.addEventListener('load', InitEvent, false);
}
var canvas, context, tool;       
function InitEvent () {                                      
    canvas = document.getElementById('drawCanvas');
    if (!canvas) {
      alert("캔버스 객체를 찾을 수 없음");
      return;
    }
    if (!canvas.getContext) {
      alert("Drawing Contextf를 찾을 수 없음");
      return;
    }       
    context = canvas.getContext('2d');
    if (!context) {
      alert("getContext() 함수를 호출 할 수 없음");
      return;
    }
    // Pencil tool 객체를 생성 한다.
    tool = new tool_pencil();
    canvas.addEventListener('mousedown', ev_canvas, false);
    canvas.addEventListener('mousemove', ev_canvas, false);
    canvas.addEventListener('mouseup',   ev_canvas, false);
}
function tool_pencil ()                                  
{
    var tool = this;
    this.started = false;
    // 마우스를 누르는 순간 그리기 작업을 시작 한다.
    this.mousedown = function (ev)
    {
        context.beginPath();
        context.moveTo(ev._x, ev._y);
        tool.started = true;
    };
   // 마우스가 이동하는 동안 계속 호출하여 Canvas에 Line을 그려 나간다
    this.mousemove = function (ev)
    {
        if (tool.started)
        {
            context.lineTo(ev._x, ev._y);
            context.stroke();
        }
    };
   // 마우스 떼면 그리기 작업을 중단한다
    this.mouseup = function (ev)
    {
      if (tool.started){
            tool.mousemove(ev);
            tool.started = false;
      }
    };
}       
// Canvas요소 내의 좌표를 결정 한다.
function ev_canvas (ev)
{
    if (ev.layerX || ev.layerX == 0)
    { // Firefox 브라우저
      ev._x = ev.layerX;
      ev._y = ev.layerY;
    }
    else if (ev.offsetX || ev.offsetX == 0)
    { // Opera 브라우저
      ev._x = ev.offsetX;
      ev._y = ev.offsetY;
    }
    // tool의 이벤트 핸들러를 호출한다.
    var func = tool[ev.type];       
    if (func) {
        func(ev);
    }
}
</script>


'HTML5.0' 카테고리의 다른 글

캔버스 이미지 뛰우기 .  (0) 2012.06.04
canvas 사이트 모음 .  (0) 2012.05.24
html4.0 을 html 5.0 으로 변환  (0) 2012.05.14
Aptana 설치  (0) 2012.05.14
HTML 이란.  (0) 2012.05.14
Posted by 사라링

프로그래밍 문제 접근법


인터뷰에서 가장 주된 부분을 차지하는 것은 기술면접, 코딩 => 어려운 문제 => 능력을 보여줄 수 있는 기회
답이 보이지 않는 상황에서 문제를 어떤 식으로 해결하는지를  살펴보기 위한 문제들도 있으니 긴장은 하지말자!


1. 절차

1.1 시나리오
코딩문제는 인터뷰어와 일대일로 진행하는 것이 일반적.  
종이와 펜을 코드를 작성하라고 한다거나, 전에 문제를 설명해보라고 할 수 있다.


1.2 문제
짧은 시간안에 설명까지 할수 있어야 하기 때문에, 변별력 있는 적당히 어려운 문제가 출제된다.
(실전에 직접 적용할 수 있는 코드를 만드는 문제가 나올 가능성은 희박함)
문제의 난이도는 대체로 점점 어려워지는 순서로 배치된다 


1.3 어떤 언어를 선택할 것인가?
일반 프로그래밍 또는 개발업무를 지원했다면  C#, Java, C++,  C 같은 주류 언어를 제대로 쓸수있는 정도면 됨
인터뷰를 하러 가기 전에 자신이 사용할 모든 언어의 사용법 및 문법을 제대로 숙지해야함
(C++ 프로그래밍을 마지막으로 건드려본지 몇년 지났다면 적당한  C++ 레퍼런스 가이드를 펼쳐 중요한 내용 체크!)


1.4 의사소통의 중요성 
자신이 사용할 언어를 가다듬고 가능하면 가장 좋은 코드를 만들자.
인터뷰어가 정말로 원하는 것은 지원자가 문제를 푸는 각 단계들을 어떻게 진행하는지 보는 것임
지속적으로 무슨일을 하고 있는지 설명하도록 하자



2. 문제해결
인터뷰 문제를 해결하는 조직적인 방법을 알아보면,
1) 문제를 확실히 이해한다
   - 문제를 이해하지 못했을 경우 주저하지 말고 인터뷰어에게 문제에 대한 질문을 해야함 
2) 일단 문제를 이해하고 나면 몇 가지 예를 들어본다 
  - 예를 시도하다보면 문제를 어떻게 풀어야 할지 감을 잘을 수도 있다.
3) 문제 풀이에 사용할 알고리즘에 초점을 맞춘다 
  - 보통 이 과정은 시간이 오래 걸리는 단계임. 부담을 가지지 말고, 인터뷰어와 대화를 통해 무엇을 하고 있는지를 보여줘야함 
4) 알고리즘과 구현 방법을 알아내고 나면 인터뷰어에게 풀이를 설명한다.
5) 코딩을 할 때도 뭘 하고 있는지 설명한다. 
   - 조용히 코드만 적는 방법은 그리 좋지 않다. 
6) 필요하다면 질문을 한다
7) 코드를 완성하고 나면 바로 몇 가지 예를 시도해 보고 맞는지 확인한다 
8) 모든 오류 및 특별 케이스, 특히 경계 조건을 확인한다 

=> 코드가 제대로 만들어졌다는 판단이 들면 인터뷰어가 코드에 대한 질문을 몇 가지 던질 것이다.
보통 이런 추가 질문에는 실행시간이나 또 다른 구현 방법, 복잡도 등에 초점을 맞춘다 


2.1 문제를 풀다가 막히는 경우
인터뷰어는 문제에 대한 답을 바로 알아낼 수 없는 경우에 지원자가 어떤 식으로 반응하는지를 살펴보고 싶어하기 마련.
문제를 풀다가 갑자기 막히게 됐을 때 포기하거나 좌절하는 것은 최악의 대응책이다. 
계속해서 흥미를 보이고 풀려고 시도하는 모습을 보이자

* 예를 다시 따져본다
 - 특정 예에서 일반적인 경우로 확장을 해보고 그로부터 풀이를 도출해보자.
* 다른 자료 구조를 사용해 시도해 본다.
* 언어에서 그리 많이 쓰이지 않는 기능 또는 고급 기능을 고려해 보자. 
 - 다른 자료구조, 언어ㄱ의 고급 기능이 문제 풀이의 핵심이 되는 경우도 있다. 


3. 풀이 분석

3.1 빅 오 분석법(big-O analysis) 
입력 값의 개수에 따라 알고리즘이 수행되는데 걸리는 시간을 바탕으로 알고리즘의 효율성을 평가하는 실행 시간 분석법
(입력의 개수 n이 매우 큰 경우의 실행시간인 점근적인 실행시간을 따지기 때문에 상수항은 무시함                                                    
(n이 매우 커질 때 가장 큰 항만 남기고 다른 항은 무시함)


3.2 빅 오 분석법을 적용하는 방법
1) 입력 값이 무엇인지 확인하고 어떤 것을  n으로 놓아야 할지 결정한다.
2) 알고리즘에서 수행해야 할 연산 횟수를 n의 식으로 표현한다 
3) 차수가 제일 높은 항만 남긴다
4) 모든 상수 인수를 없앤다 


때론 최선 케이스,  평균 케이스, 최악 케이스의 실행 시간을 따져봐야 하는 문제도 생김. 



Posted by 사라링

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


applicationcontext.xml


applicationDataSource.xml


db.properties


web-servlet.xml

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




먼저  web.xml 에 context-param 울 추가 하자.

여기서  classpath 의 값이 application*.xml 인 이유는

추후 DB 연결인 datasource 구현및 AOP 구현을 위해 만드는 것이다.

applicationAOP.xml 이면 AOP 구현 

applicationcontext.xml   context 구현

applicationDataSource.xml 이면 DS 구현   이다.


본래 마이바 티스 에서는

MyBatiseFacotry.java


config.xml

을 이런식으로 구현 하게 된다.

dipather의 즉 조립기에서는 연결된 sqlSessionFactoryBean을 만들기 위해서 application 구현부에 등록을 먼저 해야 한다.


applicationDataSource.xml 를 경로에 맞기 생성하자. Datasource 에서는 크게 3개의 컨테이너(bean) 울 구현 해야 한다.

먼저 datasource 를 보자 .


여기서 defaultAutoComiit의 경우 기본 값을  true 이나. comiit(커멧이 무엇인지는 알거라 믿음)이 여기서 ture 인경우 성능에 문제가 발생 된다고 한다.

아마도 select 문 의 경우 commit 필요 업는데도 불필요 하게 실행 되는등등의 문제가 있는듯 하다. 


라고 만들면 된다 .

p:configLocation 의 경우 


이렇게 구현되어 진다. 기존의 config.xml 이 데이터 베이스에 대한 것에 대하여 다 입력 되어 있었던것을 기억해 두자. 

이후에 같은 경로에 applicationcontext.xml 을 만들어 보자. 먼저 할것은


을 추가 하자 db 연결에 대한 설정 파일을  properties 에서 설정 함을 알수 있다.

이렇게 설정만들어 보자. !!


   MyBatis 에서 제공하는 MapperFacetoryBean 을 이용하여  프락시(대행)객체를 생성하여 호출
   단, 기존 dao의 로직이 있는 경우는 안됨,  해당 로직은 다른곳(서비스)에서 처리 한마디로 마이바티스 를 안만들고 자체적으로 처리됨.


mybatis-spring-1.1.1.jar

을 추가하자. 

그 후에 bean 컨테이너를 짜야 한다.


이런식으로!!!

추가:

p:sqlSessionFactory-ref="sqlSessionFactoryBean" 의 경우 반드시 service 구현부 에서 set 로 구현 되어야 한다.

ex)


이렇게 구현 하자 .

그리고

이것도 까먹지 말자. 생성 할때 추가 하던가 하는게 좋다.






'스프링3.0' 카테고리의 다른 글

MyBatis  (0) 2012.07.03
스프링 3.0 + ibatise  (0) 2012.07.03
web.xml 구현부 encoder  (0) 2012.05.19
Spring 개발 환경 .  (0) 2012.05.19
dispathcer 구현부 web-servlet.xml  (0) 2012.05.19
Posted by 사라링

web.xml 구현부 encoder

2012. 5. 19. 15:55

spring 구현시에 반드시 추가 해야만 한다. 안그러면 한글이 깨진다.


web,xml 구현


    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>



을 추가 하자.

Posted by 사라링

Spring 개발 환경 .

2012. 5. 19. 15:06

이클립스에서 스프링을 구현해 보자.


http://www.springsource.org/spring-community-download


접속 하자.


아래와 같이 가입 하라고 나오나. 밑에 단에


(I'd rather not fill in the form. Just take me to the download page)  라고 써있다. 난 그런거 필요 없으니 다운로드

페이지를 보여줘..  라고 한다 클릭해 주자


라고 나온다 여기서 spring-framework-3.1.1.RELEASE-with-docs.zip 또는 아래 것을 다운 받으면 된다. 되도록이면  doc 가 포함 된 것을 받자.


압축을 푼후에 src 폴더의 내용을  builderpacher 또는 lib 폴더에 추가 시킨다.

대략적으로 사용 하는 것만 따로 추출 해보자면


org.springframework.aop-3.1.1.RELEASE.jar


org.springframework.asm-3.1.1.RELEASE.jar


org.springframework.beans-3.1.1.RELEASE.jar


org.springframework.context-3.1.1.RELEASE.jar


org.springframework.context.support-3.1.1.RELEASE.jar


org.springframework.core-3.1.1.RELEASE.jar


org.springframework.expression-3.1.1.RELEASE.jar


org.springframework.jdbc-3.1.1.RELEASE.jar


org.springframework.orm-3.1.1.RELEASE.jar


org.springframework.transaction-3.1.1.RELEASE.jar


org.springframework.web-3.1.1.RELEASE.jar


org.springframework.web.servlet-3.1.1.RELEASE.jar


이다. 각자 다운 받아도 되나 통합 사이트 에서 되도록 받자... ; 용량 문제로 한꺼번에 못올린다.







Posted by 사라링

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

web-servlet.xml

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



만약 스프링 폴더가 없다면 any-frame 에서 스프링 프레임웍을 이클립스에 넣어야 한다. 이클립스 종료후 이클립스 폴더에

설치 ::http://sararing.tistory.com/entry/Spring-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD

core 한글 (애니프레임) 가이드 PDF:http://dev.anyframejava.org/docs/anyframe/plugin/essential/core/1.0.3/reference/pdf/core-1.0.3.pdf


Spring Bean Configuration File 입력후 경로및 파일이름(web-servlet.xml) 을 넣은 next를 하면



이렇게 나온다 여기서 XSD를 추가 해야만 한다. 지속 적으로 사용 하는 경우에 내용을 복사 해서 사용 해도 된다.

AOP 입력 맨 밑에 3.0.XSD 최신판을 추가 체크 하도록 하자.


추가 할것은

이렇게 된다. 만들어 보자.


만들어진 xml파일의 기본 내용은


이렇게 될것이다. 

기본적으로  Spring 에서 MVC 패턴을 구현 하다고 했을때 dipathcer 를 말하는 것은 방금 만든 web-xml 을 말하는 것이다.


dipathcer 구현은 MVC 패턴에서 가장 중심이 되는 것으로 신경써서 구현 해야 한다.  현재 Spring으로 구현 부는 member 와 board 가 있으며 pds 라는 다운로드 까지 포함 되어 있다.

controller 는 anotation을 통해 매핑 되어 있다.

controller 구현 bean을 보자.

위의 내용에 추가 된것을 하나씩 보자. 


내용을 보자면 "kr.or.ddit.web.controller" 경로 의 java 파일을 기본 위치로 설정 되어 컨트롤러를 확인 할수 있도록 되어 있다. 기본적으로 jsp 에서 요청시에 맨처음에 dispahcer 에서 실행 하는 것은 매칭된 controller를 찾는 것이다. 이 경로를 찾기 위에서는 HandlerMapping 이 작동 되는데 여기서는 ID="dahmhandlerMapping"

이라는 이름으로 구현 되어 있다. 참고로 fullpath를 이용 하려면 핸드러 매핑,핸드러 어뎁터 두 곳 모두  p:alwaysUseFullPath="true" 를 줘야 한다.



컨트롤러 매핑의 경우 직접적으로 줄수도 있는데


이렇게 하면 된다.


매핑되어 찾아진 controller 에서는 그 결과 값으로 Model 또는 view 값으로 결과 값을 리턴 하며 반환 값으로 String (controller 구현부에서 확인 가능) 으로 보여줄 view를 검색 하게 되는데 그렇게 보여 지는것을 viewResolver 라고 한다.


여기서 확인 해야 할것은. controller 에서 주는 값을 확인 해야 하는데 그 값에 prefix 는 앞에 suffix 는 뒤에 추가 하는 것을 위미 한다. order의 경우 우선순위를 말한다. 

dispatcher 에서 업로드 를 구현 할수 있는데 이경우 반드시 아이디 값을 = "multipartResolver" 로 줘야 한다.


insert 문이나 edit 문의 경우 결과 값 == 성공 또는 실패 에 대하여 view 단을 따로 구현 하는것은 매우 비효율 적이라고 할수 있다. 따라서 결과 값에 대하여 하나의 message 형태 도는 클래스 형태로 구분 되어 지는데 message 형태로 출력  dispather 또한 가능 하다.



이렇게 하여


실제 경로의 팔일은

이런식으로 구현하면 된다.   message 는 대충 보자.











'스프링3.0' 카테고리의 다른 글

web.xml 구현부 encoder  (0) 2012.05.19
Spring 개발 환경 .  (0) 2012.05.19
DispatcherServlet web.xml 구현부  (0) 2012.05.19
Encoding Filter (web.xml 구현 )  (0) 2012.05.19
Missing artifact ojdbc:ojdbc:jar:14:compile  (0) 2012.05.18
Posted by 사라링

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--//WEB-INF/web-wervlet.xml을 기본설정 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:kr/or/ddit/config/web-servlet.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

'스프링3.0' 카테고리의 다른 글

Spring 개발 환경 .  (0) 2012.05.19
dispathcer 구현부 web-servlet.xml  (0) 2012.05.19
Encoding Filter (web.xml 구현 )  (0) 2012.05.19
Missing artifact ojdbc:ojdbc:jar:14:compile  (0) 2012.05.18
스프링 3.0 AOP 에러. 문제 해결  (1) 2012.05.15
Posted by 사라링

web.xml 구현   


<filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

'스프링3.0' 카테고리의 다른 글

dispathcer 구현부 web-servlet.xml  (0) 2012.05.19
DispatcherServlet web.xml 구현부  (0) 2012.05.19
Missing artifact ojdbc:ojdbc:jar:14:compile  (0) 2012.05.18
스프링 3.0 AOP 에러. 문제 해결  (1) 2012.05.15
Spring3.0 Tiles  (1) 2012.05.14
Posted by 사라링

전자 정부 프레임웍 .. 프로젝트 만들자 마자 에러 생김..


pom.xml 을 열어 <repository>  <dependency> 추가. 저작권 때문이 라고함. 아놔.



<repository>
    <id>mesir-repo</id>
    <url>http://mesir.googlecode.com/svn/trunk/mavenrepo</url>
</repository>

And you can get the ojdbc14 jar w/this dep. def.

<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc14</artifactId>
  <version>10.2.0.4.0</version>
</dependency>    




http://www.jroller.com/mert/entry/oracle_s_ojdbc14_jar_mesir 출처


'스프링3.0' 카테고리의 다른 글

DispatcherServlet web.xml 구현부  (0) 2012.05.19
Encoding Filter (web.xml 구현 )  (0) 2012.05.19
스프링 3.0 AOP 에러. 문제 해결  (1) 2012.05.15
Spring3.0 Tiles  (1) 2012.05.14
Spring3.0 DB  (0) 2012.05.14
Posted by 사라링

외장 하드 같은 경우 간혹 배드섹터로 인해 인식이 안되는 경우가 발생 할수 있다. 이는..

usb 를 통해 전원공급과 하드섹터 읽음이 같이 연결 되어 지는데 정상적이라면 읽음이 종료 된후에 전원공급이 종료 되어야 하나.

읽는 도중에 강제로 선을 뽑는 경우 전원이 먼저 끊어지기 때문에 문제 되어지는것 같다 이런 경우

윈도우키 + R 을 눌러 실행창을 누루고 CMD 를 누룬다. 보통 도스실행창 이라고 한다.


실행 창이 켜진 상태에서 

chkdsk h:/f/r <--- 명령어를 입력 한다.

참고로 여기서 h 는 드라이버의 이름이다 만약 연결 했을때 외장하드 드라이버 연결조차 안된다면 chkdsk 조차 안된다는것이다.

참고로 chkdsk 는 하드웨어 섹터 점검 명령 이다.




참고로 엄청 오래 걸린다;;;

Posted by 사라링

소켓 통신 구현

2012. 5. 15. 20:50

[안드로이드] 서버/클라이언트 소켓(Socket) 통신하기

 

 추가: 설명은 퍼왔으나 소스 부분은 자체적으로 수정 했습니다.

 

<목표> [안드로이드] 서버/클라이언트 소켓(Socket) 통신하기

     

   

   오늘은  서 버, 클라이언트의 소켓(Soket) 통신에 대해서 알아보겠습니다. 기존의 많은 안드로이드 어플리케이션이 각각의 서버를 이용하여 정보를 주고 받습니다. 아무래도 기기 내에서 만으로 서비스하기에는 한계가 있기 때문이죠. 정보를 저장하고, 서버에서 처리하여 결과를 주고, 클라이언트는 그 결과를 받아서 어플리케이션에 알맞은 동작을 취하도록 합니다. 트위터 서비스나 스마트폰을 이용해서 공짜 문자(통신료 제외)를 주고 받을 수 있는 것도 서비스를 제공하는 곳에서 서버를 두기 때문입니다. 그 덕분에 핸드폰을 벗어나 더 많은 정보를 처리할 수 있도록 할 수 있습니다.

 

   서 버/클라이언트 소켓 통신은 기존의 자바를 이용해서 소켓 통신을 해보신 분들이라면 어렵지 않게 사용하실 수 있습니다. 서버의 소스 자체는 완전히 자바 소스로 이루어지기 때문이지요. 실제로 서버는 안드로이드를 통해서 돌리는 것이 아니라, 기존의 자바 프로그래밍을 이용하여 수행합니다. 클라이언트는 당연히 안드로이드로 개발을 해야겠지요. 오늘 보여드릴 예제 소스는 인터넷에 돌아다니는 간단한 서버 – 클라이언트 소켓 통신을 가지고 와서 나름대로 수정을 해본 것입니다. 기존의 샘플 코드가 하나의 메시지를 서버로 보내고 난 뒤에, 바로 클라이언트에서 기다리면서 데이터가 오기를 기다리는 형태로 제공되었습니다. 그렇기 때문에 클라이언트가 계속 데이터를 기다리면서 블록킹 되어 있는 상태에서만 프로그래밍이 돌아갔습니다. 이러한 부분을 수정하여 쓰레드를 이용하여 백그라운드에서 돌아가게 하여, 기존의 클라이언트에서는 원래의 프로그램이 수행되고, 서버에서 오는 정보를 받는 부분은 쓰레드를 통해 해결했습니다.

 

    먼저 서버를 만들 자바 코드를 알아보고, 뒤에는 안드로이드에서 소켓 통신을 위한 설정과정을 간단한 예제를 통해서 알아보겠습니다.

     

     

     

STEP 1  Java Source Code

     

   자바 코드는 두 가지를 다루게 됩니다. 처음은 서버를 돌리는 데 필요한 자버 코드를 알아보고, 두 번째는 안드로이드 클라이언트 코드를 알아보겠습니다.

 

 

  [[ 서버 ]]   TCP Server Java Code

 

package kr.or.ddit;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

public class JavaServer {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            System.out.println("Starting Java Socket Server ......");
            ServerSocket serverSocket = new ServerSocket(5001);
            System.out.println("Listening at port : 5001");

            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println(getTime() + " host : "
                        + socket.getInetAddress() + ", port : "
                        + socket.getPort());

                ObjectInputStream inputStream = new ObjectInputStream(
                        socket.getInputStream());
                String inputString = inputStream.readUTF();
                System.out.println("ID : " + inputString);

                ObjectOutputStream outputStream = new ObjectOutputStream(
                        socket.getOutputStream());
                outputStream.writeUTF(inputString);
                outputStream.flush();
                socket.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    static String getTime() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd [hh:mm:ss]");
        return format.format(new Date());
    }

}

 

    서버의 기능은 클라이언트에서 오는 데이터를 받아들이는 게 핵심입니다. 자신의 포트를 세팅하여 소켓을 여는 것부터 시작하여, 클라이언트에서 오는 정보를 받기 위해서 accept() 를 통해서 기다립니다. 그리고 데이터가 왔다는 신호가 오면 리더를 통해서 스트림을 읽어냅니다. 그리고 자신이 받은 스트림 정보를 다시 돌려보내는 역할을 합니다. 현재는 하나의 클라이언트와 컨넥트를 통해 데이터를 주고 받는 형식입니다. 많은 클라이언트와 통신하고 싶으면 클라이언트에 대한 정보를 저장하고, 여러 클라이언트에게 적절하게 보내는 기능을 추가하시면 되겠습니다.

 

 

   [[ 클라이언트 ]]   TCP Client Java Code

 

 


======================================================================================================
AndroidSocketClientActivity.java
======================================================================================================
package kr.or.ddit;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class AndroidSocketClientActivity extends Activity {
    TextView textView;
    EditText editText;
    String myName = "";
    String serverIp = "xxx.xxx.xx.xx"; //서버의 아이피를 적어야 함.
    int portNum = 50001;

    Handler handler = new Handler();

    ClientThread thread;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        textView = (TextView) findViewById(R.id.textView);
        editText = (EditText) findViewById(R.id.editText);
        Button requestBtn = (Button) findViewById(R.id.requst);

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                textView.append(msg.getData().getString("msg") + "\r\n");
            }
        };

        thread = new ClientThread(handler, serverIp, portNum, myName);
        thread.start();

        requestBtn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                thread.writeMessage(editText.getText().toString());
                editText.setText("");
            }
        });
    }

}



====================================================================================================
ClientThread.java
====================================================================================================
package kr.or.ddit;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class ClientThread extends Thread {
    static DataOutputStream outputStream;
    static Socket socket;
    private SendService sendService;
    private ReceiverService receiverService;
    private String name;
   
    public ClientThread(Handler handler, String ip, int port, String name) {
        sendService = new SendService();
        sendService.start();
        receiverService = new ReceiverService(handler, ip, port);
        receiverService.start();
        this.name = name;
        try {
            outputStream.writeUTF(name);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   
    public void writeMessage(String msg) {
        sendService.writeMessage(msg);
    }
   
    class SendService extends Thread {
        public void writeMessage(String msg) {
            try {
                if (ClientThread.socket != null && ClientThread.socket.isConnected()) {

                    outputStream.writeUTF("[" + name + "]" + msg);
                    outputStream.flush();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
   
    class ReceiverService extends Thread {
        private DataInputStream inputStream;
        private Handler handler;
       
        public ReceiverService(Handler handler, String ip, int port) {
            this.handler = handler;
            try {
                socket = new Socket(ip, port);
                inputStream = new DataInputStream(socket.getInputStream());
                outputStream = new DataOutputStream(socket.getOutputStream());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       
        @Override
        public void run() {
            try {
//                while (socket != null && socket.isConnected()) {
                while (inputStream != null) {
                    String receiveMessage = inputStream.readUTF().toString();
                    Message message = handler.obtainMessage();
                    Bundle bundle = new Bundle();
                    bundle.putString("msg", receiveMessage);
                    message.setData(bundle);
                    handler.sendMessage(message);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
       
        public void cancel() {
            try {
                socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

 

   이 번에 살펴볼 코드는 안드로이드 클라이언트 프로그램입니다. 안드로이드 클라이언트 코드에서는 서버에 소켓을 연결하고 받은 정보를 이용하여 프로그램을 수행시키는 것을 다룹니다. 먼저 onCreate()가 되면 서버에 연결하도록 설계되어 있습니다. IP 주소와 포트 번호를 알맞게 설정해주시고, 소켓을 연결합니다. 그리고 데이터를 주고 받기 위해서 리드, 라이터를 설정하여 둡니다. 예제에서는 간단히 텍스트 박스에 문자를 적고 버튼을 누르면, 서버로 데이터를 보냅니다. 그리고 서버에서 오는 데이터를 계속 받기 위해서 while을 쓰레드를 통해서 실행합니다. 여기서 받은 데이터 정보를 토스트 기능을 통해 출력합니다. 여기서 UI에 대한 접근을 핸들러를 통해서 하고 있는 것을 확인할 수 있습니다. 이렇게 하는 이유는 다른 포스트에 올리겠습니다. 일단 UI에 대한 접근은 핸들러를 통해서 수행한다고 생각하시고 프로그램을 수행해야한다는 것만 기억하시고 계시면 될 것 같습니다.

       

 

STEP 2  Xml Code

       

    Xml 코드에는 간단히 EditText에서 넣은 문자열을 버튼을 통해 서버로 데이터를 보내는 기본적인 기능만 추가하시면 됩니다.

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffffff" >

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <TextView
            android:id="@+id/textView"
            android:layout_width="fill_parent"
            android:layout_height="88dp"
            android:background="#ffffaadd"
            android:textColor="#ff000000" />
    </ScrollView>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <EditText
            android:id="@+id/editText"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:hint="@string/editText" />

        <Button
            android:id="@+id/requst"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/request" />
    </LinearLayout>

</RelativeLayout>

 

        

     

STEP 3  AndroidManifest.xml Code

     

    메니페스트에는 소켓을 이용하기위해 인터넷을 사용해야 하므로, 인터넷을 사용하겠다는 퍼미션만 추가해주시면 됩니다.

       

AndroidManifest.xml 에 추가해야할 인터넷 사용 허가권

<uses-permission android:name="android.permission.INTERNET" />

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="kr.or.ddit"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".AndroidSocketClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

     

     

     

 < 마무리 >   서버/클라이언트 소켓(Socket) 통신하기

     

 

   서버와 클라이언트의 소켓 통신에 대해서 알아보았습니다. 핸드폰 내에서의 기능과 정보만으로는 어플리케이션이 한정적일 수 밖에 없습니다. 그렇기 때문에 통신을 통해서 좀 더 폭넓은 서비스를 제공하기 위해서 서버와 클라이언트가 서로 통신할 수 있도록 소켓에 대해서 알아볼 필요가 있었습니다. 하나의 서버가 여러 곳의 클라이언트들에 대해서 서비스를 해줘야 할 때는 클라이언트에 대한 정보를 가지고 있으면서 소켓을 각각 연결시켜주어야 합니다. 안드로이드 클라이언트 부분에서도 현재 수행되고 있는 동작에 영향을 받지 않으면서 백그라운드에서 쓰레드가 돌면서 서버에서 오는 정보를 수시로 받을 수 있도록 해야합니다. 소켓 통신에 대한 기존 개념을 알고 계신 분들이라면 크게 어렵지 않게 이해하실 수 있으셨으리라 봅니다. 처음 접하시는 분들은 데이터를 주고 받는 부분에서 자신이 수행하고 싶은 기능만 추가해주시면 간단히 소켓 통신을 하실 수 있으리라 생각합니다.

   

   

   

[참고자료]  


'안드로이드' 카테고리의 다른 글

You must supply a layout_width attribute  (0) 2012.05.15
Progressbar  (0) 2012.05.15
안드로이드 색상표  (0) 2012.05.11
안드로이드 강좌 모음 pdf&동영상 강좌.  (0) 2012.05.11
화면회전  (0) 2012.05.08
Posted by 사라링

발생 : 인텐트로 .ItemEdit 액티비티를 호출 할 때 발생 

10-20 09:00:59.928: DEBUG/dalvikvm(207): GC freed 43 objects / 2096 bytes in 235ms
10-20 09:01:05.298: DEBUG/dalvikvm(107): GC freed 2132 objects / 124248 bytes in 232ms
10-20 09:01:32.229: WARN/KeyCharacterMap(321): No keyboard for id 0
10-20 09:01:32.238: WARN/KeyCharacterMap(321): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
10-20 09:01:33.140: INFO/ActivityManager(52): Starting activity: Intent { cmp=com.misun.smileproj.timemetrix/.ItemEdit }
10-20 09:01:33.269: DEBUG/AndroidRuntime(321): Shutting down VM
10-20 09:01:33.269: WARN/dalvikvm(321): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
10-20 09:01:33.278: ERROR/AndroidRuntime(321): Uncaught handler: thread main exiting due to uncaught exception
10-20 09:01:33.310: ERROR/AndroidRuntime(321): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.misun.smileproj.timemetrix/com.misun.smileproj.timemetrix.ItemEdit}: java.lang.RuntimeException: Binary XML file line #3: You must supply a layout_width attribute.
...

원인 : 레이아웃 설정파일에서 위젯의 layout_height 과 layout_width를 제대로 명시하지 않았다. 
해결 : 필수 속성값 명시하기


'안드로이드' 카테고리의 다른 글

소켓 통신 구현  (0) 2012.05.15
Progressbar  (0) 2012.05.15
안드로이드 색상표  (0) 2012.05.11
안드로이드 강좌 모음 pdf&동영상 강좌.  (0) 2012.05.11
화면회전  (0) 2012.05.08
Posted by 사라링


에러 메세지 :

심각: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 17 in XML document from file [D:\workJSP\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\dditSpring\WEB-INF\classes\kr\or\ddit\config\applicationAOP.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:advice'.
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396)



cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:advice'.


 BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext


등의 에러 메세지가 나왔다. 대충 요약 하면 txManager  인 트렌젝션 매니저를 찾지 못한다는 것이다. 코드를 아무리 분석 해도 문제가 해결 안되었으나 문제는 bean 에 있는 것이 아니라. xsi:schemaLocation 에 있었다.


이 스키마 로케이션에 

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"


으로 추가및 수정 하여 문제 해결!!


but no declaration can be found for element

'스프링3.0' 카테고리의 다른 글

Encoding Filter (web.xml 구현 )  (0) 2012.05.19
Missing artifact ojdbc:ojdbc:jar:14:compile  (0) 2012.05.18
Spring3.0 Tiles  (1) 2012.05.14
Spring3.0 DB  (0) 2012.05.14
Spring3.0 View error filedown  (0) 2012.05.14
Posted by 사라링

BLOG main image
.. by 사라링

카테고리

사라링님의 노트 (301)
JSP (31)
J-Query (41)
JAVA (24)
디자인패턴 (1)
스트러츠 (3)
안드로이드 (11)
오라클 (45)
우분투-오라클 (1)
이클립스메뉴얼 (6)
스프링3.0 (23)
자바스크립트 (10)
HTML5.0 (17)
정보처리기사 (1)
기타(컴퓨터 관련) (1)
문제점 해결 (3)
프로젝트 (2)
AJAX (4)
하이버네이트 (3)
트러스트폼 (11)
Jeus (2)
재무관리(회계) (5)
정규식 (5)
아이바티스 (8)
취미 (2)
소프트웨어 보안 관련모음 (0)
정보보안기사 (6)
C언어 베이직 및 프로그램 (3)
보안 관련 용어 정리 (2)
넥사크로 (6)
웹스퀘어_ (0)
Total :
Today : Yesterday :