'분류 전체보기'에 해당되는 글 2491건

  1. 2008.11.19 StarBox 0.3 별점 라이브러리!
  2. 2008.11.19 PBwiki JavaScript Testing
  3. 2008.11.19 jQuery의 무서운 돌진…
  4. 2008.11.19 slickspeed - speed/validity selectors test for frameworks
  5. 2008.11.19 Good bye alert(); - JavaScript Library
  6. 2008.11.19 ExtJS의 기본 이해하기 ( Component Class의 inheritance 구현 및 계층 구조의 이해 )
  7. 2008.11.19 간단한 jQuery 소개
  8. 2008.11.19 FusionCharts.js 자바스크립 파일과 그래프용 swf파일
  9. 2008.11.19 jQuery summary
  10. 2008.11.19 jQuery를 이용한 FancyBox
  11. 2008.11.19 jQuery 개발자를 위한 메모 - 레퍼런스
  12. 2008.11.19 Open-Source 기반의 Javascript Library중 하나인 jQuery
  13. 2008.11.19 Downloading jQuery
  14. 2008.11.19 [본문스크랩] Java 보안과 암호화
  15. 2008.11.19 java.lang.OutOfMemoryError
  16. 2008.11.19 JSP에서 원하는 Appender 선택하여 쓰기 (처음시작하기...필독)
  17. 2008.11.19 Log4j Summary
  18. 2008.11.19 iBATIS
  19. 2008.11.19 PDF 파일 만들기 - fop 0.93
  20. 2008.11.19 [펌] JExcelApi & POI
  21. 2008.11.19 엑셀을 자바로 읽을(쓰는것 포함) jxl 방법
  22. 2008.11.19 Orinoco - A Java API to generate PDF documents
  23. 2008.11.19 Java Excel API - A Java API to read, write and modify Excel spreadsheets
  24. 2008.11.19 Excel File(엑셀파일) 다운로드 받기 1
  25. 2008.11.19 jsp에 엑셀 자료 넣기 jexcel or poi
  26. 2008.11.19 java(자바)로 excel(엑셀) 파일 활용 (jxl api) 정리
  27. 2008.11.19 자바 JXL API 를 이용한 Excel 파일 만들기
  28. 2008.11.19 java의 excel 컨트롤 - jxl, poi
  29. 2008.11.19 Apache Download Mirrors
  30. 2008.11.17 Vmware를 이용한 Ubuntu 설치 방법
반응형
사용자 삽입 이미지

별점 라이브러리입니다.
Script.aculo.us 와 Prototype 1.6.0을 이용한 라이브러리 입니다.

유사하게 만들어 놓은 것이 있기는 한데 이게 훨씬 더 깔끔하네요...
투명 이미지를 통한 백그라운드 색상을 변화시켜서 처리를 했습니다.

상당히 효율적인 생각으로 접근했네요.  대부분의 국내 사이트의 롤오버 효과를 보면 이미지를 새로 로딩하는
경우가 많은데요.

이는 효율적인 웹 사이트 개발에 아주 저해되는 요소입니다.
개발자가 알아야할 부분이기도 하지만 디자이너도 알아야 할 부분입니다.

롤오버 자체는 더이상 이미지를 두개로 만들어 _on.gif  와 _off.gif 방식으로 롤오버는 더 이상
만들지 마시길 바랍니다.

이 라이브러리도 한가지 단점이라면 투명이미지를 활용해서 백그라운드 색상에 다른 경우에는
이미지를 새롭게 만들어 주어야 한다는 것이죠!

별의 색깔은 자유자재로 변곃라 수 있지만 백그라운드의 색상에 맞게 변경할 수는 없답니다.
그것까지 가능하려면 플래시를 조금 이용하거나 base64 이미지를 이용해서 동적인 이미지를 그리면 되겠죠.
하지만 그렇게 처리한다는 것 자체는 너무 무거워지는 라이브러리가 된다는 것!!

사용법
  1. <script type='text/javascript' src='js/prototype.js'></script>  
  2. <script type='text/javascript' src='js/scriptaculous.js?load=effects'></script>  
간단하게 위와 같이 파일을 import 합니다.
Css 파일도 import하구요.
  1. <link rel="stylesheet" type="text/css" href="css/starbox.css" />  
이렇게 사용하면 됩니다.
  1. new Starbox(element, average, { stars: 10, buttons: 20, max: 10 });  
  2. new Starbox(element, average, { overlay: 'big.png', ghosting: true });  
  3. new Starbox(element, average, { onRate: yourAjaxSaveFunction, rerate: true });  
  4. <script type='text/javascript' src='js/starbox.js'></script>  
다양한 옵션들은 이 처럼 설정하시면 됩니다.
  1. new Starbox(  
  2.   element,                  // the id of your element  
  3.   average,                  // average rating to start with  
  4.   {  
  5.     buttons: 5,             // the number of buttons (choices)  
  6.     className : 'default',  // or your own classname  
  7.     color: false,           // color of the colorbar  
  8.     duration: 0.6,          // duration of the effect across the bar, if used  
  9.     effect: { mouseover: false, mouseout: true } // or your own  
  10.     hoverClass: 'hover',    // or your own classname  
  11.     hoverColor: false,      // color of the colorbar when hovered  
  12.     ghostColor: false,      // color of the ghostbar  
  13.     ghosting: false,        // shows a ghost bar with the average when true  
  14.     identity: false,        // can be used with onRate  
  15.     indicator: false,       // or a string to add an indicator div after the starbox  
  16.                             // #{average}, #{max} and #{total} can be used  
  17.                             // example: '#{average}/#{max} out of #{total} votes'  
  18.     inverse: false,         // true, false  
  19.     locked: false,          // or true to load an disabled starbox  
  20.     max: 5,                 // maximum rating, that of the last star  
  21.     onRate: false,          // or function(element, info){}  
  22.                             // info = { identity: identity,  
  23.                             //          rated: rated,  
  24.                             //          average: average,  
  25.                             //          max: max,  
  26.                             //          total: total  
  27.                             //        }  
  28.     overlay: 'default.png', // or other png in same folder as starbox.css  
  29.     rated: false,           // or the previous rating cast by this user,  
  30.                             // this is used by rerate to see if the starbox  
  31.                             // needs to be locked  
  32.     ratedClass: 'rated',    // or your own  
  33.     rerate: false,          // or true to allows adjusting of previous rating  
  34.     stars: 5,               // the amount of stars  
  35.     total : 0               // the amount of votes cast  
  36.   }  
  37. );  
사용자 css 도 가능하겠죠.. ^^
  1. .starbox .stars { background: #cccccc; }  
  2. .starbox .rated .stars { background: #dcdcdc; }  
  3. .starbox .rated .hover .stars { background: #cccccc; }  
  4. .starbox .colorbar { background: #1e90ff; }  
  5. .starbox .hover .colorbar { background: #ffcc1c; }  
  6. .starbox .rated .colorbar { background: #64b2ff; }  
  7. .starbox .rated .hover .colorbar { background: #1e90ff; }  
  8. .starbox .ghost { background: #a1a1a1; }  
  9. .starbox .indicator { clear: both; } 
Posted by 1010
반응형
PBwiki 팀의 Brian Klug 씨는 자바스크립트(javascript) 라이브러리 제공에 대해 좀더 자세히 배우기 위해서

자바스크립트(javascript) 라이브러리 테스트를 Dojo, jQuery, Prototype, YUI, Prototculous 를 로딩해서 만들었네요. 

azki 님이 이런쪽에 관심이 많을것 같은데요?? 그런가요?? ^-^

이 테스트는 압축(packed)과 최소화(minified), gzip 과 gzip 하지 않았을때, 캐시 기타 등등 테스트에

속해있습니다.   흥미로운 결과중에 하나가.. 압축(packed)를 사용하지 말라는 것입니다.. ^^;;

테스트 써머리 페이지 http://jst.pbwiki.com/summary.php

사용자 삽입 이미지

Result Calculus (cached, gzipped, minified)
사용자 삽입 이미지
Posted by 1010
반응형
jQuery의 무서운 돌진…

jQuery의 MS와 Nokia이 adopting 소식과 존 레식 블로그의 컨퍼런스에 대한 소개 자료를 살펴보다.  약간의 번역과 요약정리 해봅니다.

jQuery 창시자이자 리더 개발자인 존 레식은 보스턴에서 열린 Ajax Experience에서 3일간의 행사 기간중 2개의 패널에서 아홉 가지의 이야기를 했습니다.  조만간 컨퍼런스의 발표 내용에 대한 것들은 비디오 자료와 함께 곧 포스팅 할 예정이라는데 언제 올라 올른지…

State of jQuery `08
급속한 성장을 보여준 jQuery에 대한 변화에 대한 프리젠테이션.  간략하게 요약하자면 jQuery 사이트의 UV와 PV의 향상, Google Trend에서도 확인할 수 있지만 2008년도의 jQuery의 변화를 보여주는 자료입니다.

아래 구글 트랜드의 그래프 자료를 보더라도 2분기에 오면서 꾸준한 유저층을 유지해오던 Prototype과 2007년 후반기부터 갑작스레 높아졌다 2008년 1분기에 급속한 하락한 Dojo에 반해 jQuery는 꾸준히 상승하고 있습니다.

비교그래프

Google Trend 자료



2008년 3월에 이미 Prototype과 비슷한 사용자층을 유지하고 있습니다.  Script.aculo.us가 있기는 하지만 ^^ 4월에서 6월의 기간 동안에는 Designer와 Ruby Dev 그룹에서는 이미 jQuery가 앞서가는 모습을 보입니다.

2008년에 다양한 기능 업그레이드와 퍼포먼스 향상의 대표적인 부분들에 대해서 알려주고 있었고 이에 대한 기술적인 다양한 방법으로 공개하였고 이로 jQuery의 트래픽이 꾸준히 상승한 것이 아닌가 추측해봅니다.

그리고 2009년에도 jQuery의 노력은 헛되지 않으리라 봐지는 다른 부분은 MS와 Nokia의 jQuery 탑재에 대한 소식도 빼놓을 수 없을 것 같습니다.  (Microsoft and Nokia are both adopting jQuery)

Nokia의 Phone 에 들어가는 웹 런터임(Webkit)에 사용될 포팅 어플리케이션의 작동을 위해 jQuery를 사용하고 새로운 Phone 에도 적용될 예정이라고 합니다.

Microsoft의 경우 그들의 개발 플렛폼 일부분에 jQuery를 만들었고 Visual Studio .NET에 탑재되었습니다. 그리고 jQuery를 이용한 다양한 컴포넌트를 제작하였습니다.

참조 : http://www.slideshare.net/jeresig/state-of-jquery-08-presentation/


jQuery Internals + Cool Stuff
이 프리젠테이션 자료에는 jQuery의 내부 기술과 쿨한 재료들에 대한 소개입니다.  Wrapping과 다른 사용자와 프레임웍들 간의 코드 충돌이 일어 나지 않도록 처리한 기술, Element에 Data 바인딩 및 캐시 활용 기술 등에 대한 소개,  jQuery의 Selector는 타 프레임웍과는 달리 비 종속적 동작으로 다른 프레임웍(Prototype이나 Mochikit)하고 함께 사용 가능하다는 것과 동작 원리에 대한 소개,  Event System 에 대한 소개, 브라우저 Sniffing 에 대한 기술.  마지막으로 TDD(Testing Driven Development) 를 위한 Suite 와 Profiling에 대한 소개가 있었습니다.

참조 : http://www.slideshare.net/jeresig/jquery-internals-cool-stuff-presentation/


JavaScript Library Overview
  90분 동안 발표한 자료로 다양한 라이브러리의 Overview는 각 라이브러리들 간의 비교를 쉽게 파악할 수 있도록 꾀 많은 자료 매우 다양한 방면에서 비교, 분석해 놓았네요. 

참조 : http://www.slideshare.net/jeresig/javascript-library-overview-presentation/
Ajaxian : http://ajaxian.com/archives/thinking-about-the-difference-between-frameworks


존 레식의 활동과 jQuery의 개발팀의 열정만큼이나 2008년도에 JavaScript 프레임워크는 MS와 Nokia의 adopting으로 2009년에는 더 많은 유저층과 트래픽을 유지하지 않을까 짐작해봅니다.    

또한 다양한 RIA 개발을 위한 다양한 플랫폼들과 대등한 관계에서 경쟁구도를 형성하리라 본다.  Silverlight의 최대 라이벌은 Adobe Systems 의 Flash가 아닌 JavaScript(http://live-kj2164.tistory.com/?page=2)라는 전문가들의 말처럼 jQuery 뿐만 아니라 모든 JavaScript 프레임웍들이 2009년도에는 좀더 다양한 기술로 발전할 수 있었으면 하는 바램입니다.


자료 출처 : http://ejohn.org/blog/jqueryembraceextend/
Posted by 1010
반응형
사용자 삽입 이미지





  다양한 프레임웍(DOMAssistant 2.6, jQuery 1.2.3, Prototype 1.6.0.2, Mootools 1.2b2, ExtJS Core 2.0.1, YUI 2.4.1)들에 대한 셀렉터(Selector) 속도 및 유효성 테스트입니다.

  정확한 테스트와 상호 테스트간의 충돌을 방지하기 위해서 각각의 프레임웍 테스트를 각각의 아이프레임내에서 수행되도록 처리했네요. 최대한 정확한 테스트가 되기위해서 여러모로 신경을 썼다는 군요.

사용자 삽입 이미지

제 PC 에서 수행한 결과입니다.
DOMAssistant 2.6         1087ms
jQuery 1.2.3                  1454ms
Prototype 1.6.0.2      2324ms
Mootools 1.2b2             1578ms
ExtJS Core 2.0.1      617ms
YUI 2.4.1                      1789ms

테스트 결과가 생각과 많이 다르네요..
Prototype.js가 속도면이나 유효성면에서 제일 떨어지네요.  실망스럽네요. 하지만 다른 부분은 탄탄하게 구성되어있으니 element 찾을때 Selector를 이용해 접근하는 $$ 함수의 사용을 자재해야겠군요.

  반면 ExtJS는 그리드 기반의 Framework인데 Selector 부분을 신경을 많이 썼나보군요.
하기야 대부분 css 컨트롤을 통해서 그리드 구성을 할터이니 이부분도 상당히 신경을 썼겠죠..
내부 로직은 잘 모르겠지만 ExtJS가 Selector에서는 다른 Framewokr에 비해서 탁월한 성능을 보이는게 사실이네요.

테스트 사이트 : http://www.domassistant.com/slickspeed/
Posted by 1010
반응형
심플한 라이브러리를 소개할까 합니다.  최근에 라이브러리 소개를 하지 않았는데 오랜만에 ^^..
소개하는데도 당연히 이유가 있겠죠.



Blackbird 라는 라이브러리 입니다.

일단 사이트에 접속을 하면 큰 글자로 이렇게 적혀있습니다.


Blackbird 에게는 "만나서 반가워" 이라고 말하고 alert() 에게는 "이만 안녕" 이라 말하라고 합니다. 
그래서 무엇인고 봤더니 log와 profiler로 활용하기 좋은 rich application을 JavaScript로 구현을 해 놓았군요.
이런 라이브러리야 이미 YUI에도 유사한 모양으로 있고 firebug에서도 강력하게 지원을 해주고 있는데...

깜직한 아이콘은 둘째 치고 개발자 편의를 위해 단축키까지 처리해 놓은 것을 보면 참. 많은 것을 느낍니다.

이미 나온 Blackbird 라이브러리는 누구나가 만들 수 있지만... 처음 나온 Blackbird 라이브러리는 처음 만든 개발자의 스킬과 마인드에서 밖에 나올 수 없는게 아닐까 생각해봅니다.

alert() 에게 "이만 안녕" 이라 말 할만 한가요?

Library : http://www.gscottolson.com/blackbirdjs/
Google : http://blackbirdjs.googlecode.com/
Posted by 1010
반응형
ExtJS의 기본 이해하기 ( Component Class의 inheritance 구현 및 계층 구조의 이해 )

  1. Ext.data.Connection = function(config){  
  2.     Ext.apply(this, config);  
  3.     this.addEvents(  
  4.         "beforerequest",  
  5.         "requestcomplete",  
  6.         "requestexception" 
  7.     );  
  8.     Ext.data.Connection.superclass.constructor.call(this);  
  9. };  


Ext.data.Connection 는 ExtJS의 Rmote server에 XHR Request를 위한 class이자 namespace 입니다.
사용자 삽입 이미지
ExtJS의 모든 Class는 Ext의 하위 패키지 그 안의 서브 클래스들로 구성되어 집니다.  이때 위 처럼 클래스들이 생성되어서 동작하기 위해서 기본적으로 하는 처리가 있습니다.


위의 소스를 간단하게 보겠습니다.
Ext.data.Connection 는 function 을 갖습니다. 첫번째 인자료 config 라는 Hash 형태의 오브젝트를 갖습니다.

Hash 형태의 오브젝트란? 
{ key : value }의 형태를 말하고 이해를 돕기 위해 Hash형 오브젝트라 칭합니다.
Hash형 오브젝트 타입은 value에는 다양한 type의 값이 올 수 있습니다.

이는 사용 시 new 연산자를 이용하여 인스턴스화 되게 됩니다.
즉 Ext.data.Connection은 function으로의 기능이 아닌 instance 화 되어 사용되게 됩니다.

그러면 인스턴스가 생성될 때 수행되는 컨텍스트를 봅니다.

Ext.apply(this, config); 는 아래의 Ext의 맴버로서 수행되어집니다.

  1. /**  
  2.  * Copies all the properties of config to obj.  
  3.  * @param {Object} obj The receiver of the properties  
  4.  * @param {Object} config The source of the properties  
  5.  * @param {Object} defaults A different object that will also be applied for default values  
  6.  * @return {Object} returns obj  
  7.  * @member Ext apply  
  8.  */ 
  9. Ext.apply = function(o, c, defaults){  
  10.     if(defaults){  
  11.         // no "this" reference for friendly out of scope calls  
  12.         Ext.apply(o, defaults);  
  13.     }  
  14.     if(o && c && typeof c == 'object'){  
  15.         for(var p in c){  
  16.             o[p] = c[p];  
  17.         }  
  18.     }  
  19.     return o;  
  20. };  


위의 apply에 의해서 this config로 넘겨준 값이 모두 overwrite 되게 됩니다. this가 가지고 있던 속성 및 메서드까지 모두 config가 가지고 있던 값으로 치환되어집니다.

이때 apply 에 첫번째 인자로 주는 config ExtJS에서는 해당 클래스가 갖는 속성의 의미와도 같습니다.

좀더 쉽게 풀이해서 쓴다면 ExtJS의 하나의 클래스가 인스턴스화 되어질 때 기본적으로 갖게 되는 속성 그리고 상속구조가 형성되면서 override 되는 속성과 메서드들의 기본 설정을 합니다.

좀더 쉬운 예를 들어보면 하나의 widget이 생성되어 브라우저에 띄울 때 그 widget의 기본 사이즈, 드래그 앤 드랍 등을 할 수 있는 설정을 이 config Hash 오브젝트로 넘겨주는 초기 설정값과도 같습니다.


  1. this.addEvents(  
  2.         "beforerequest",  
  3.         "requestcomplete",  
  4.         "requestexception" 
  5.     );  


이 코드는 이벤트 리스너를 설정하게 됩니다.  최근에 릴리즈한 자바스크립트 프레임웍에는 Custom Event가 모두 지원하고 있습니다. 

ExtJS에서도 이를 지원하는데요. 이는 Observable class에 있습니다. 
위의 코드는 이 Ext.data.Connection 이 인스턴스화 될 때 사용하게 될 기본적인 이벤트 리스너에 해당하는 것들입니다.

위에 잠깐 예시를 들었던 widget 에서는 기본적으로 widget을 움직일 수 있고 최소화 시킬 수 있는 기능을 기본적으로 갖게 됩니다.  경우에 따라서는 숨길 수 있는 기능이나 최대화 기능도 부여할 수 있습니다.  이처럼 this.addEvent를 통해서 Ext.data.Connection 이 갖는 기본적인 이벤트 리스너를 등록하게 됩니다.

XMLHttpRequest 를 통해서 서버측 데이터를 받아올 때 혹은 받을때 받고나서 등등 다양한 상황에 맞는 이벤트 리스너를 사용하기에 앞서 Connection 클래스가 기본적으로 갖게되는 이벤트 리스너를 설정해 주게 됩니다.  위의 경우 ‘beforerequest’, ‘requestcomplete’, ‘requestexception’ 3가지의 리스너를 설정하게 됩니다.

이렇게 설정된 리스너는 fireEvent 메서드 즉 핸들러를 수행하게 됩니다.

마지막 구문

Ext.data.Connection.superclass.constructor.call(this);

상당히 길게 나열된 구조입니다. ExtJS의 가장 중요한 부분이라고 해도 과언이 아닙니다. 어떻게 해서 저렇게 긴 메서드가 생성되었을까요 간단하게 풀이해서 보도록 합니다.
Ext.data.Connection 이것은 굳이 Ext.data.Connection 이라고 하지 않고 this라고 해도 무방했을텐데 왜 그랬는지 살짝 궁금해집니다.

this를 쓰지 않았던(?) 못했던(?) 이유... 2008.05.18 추가

more..



그 다음에 오는 superclass 는 단연 계층 구조에 있어서 최상위 클래스, 부모 클래스를 나타낼 텐데요.  superclass.constructor 입니다.  즉 superclass 가 아닌 superclass의 constructor를 나타냅니다.  이는 인스턴스화 되지 않는 부모 클래스의 생성자를 참조하고 있습니다.

그런데 과연 superclass 라는 것은 원래 있는 것인지? 아니면 ExtJS에서 기본적으로 제공하는 것인지 의문이 듭니다. 이는 Ext.extend 맴버에 의해서 Ext.data.Connection 에 부여됩니다.

Ext.extend(Ext.data.Connection, Ext.util.Observable, { … });

잠시 extend 메서드에 대한 설명을 간단하게 하고 넘어갑니다.
extend 메서드는 YUI의 구조와 동일합니다. 첫번째 인자로 넘어간 오브젝트에 superclass 속성을 부여하여 두번째 인자의 prototype을 superclass 가 레퍼런스하도록 합니다.

즉 Ext.data.Connection.superclass는 Ext.util.Observable.prototype을 레퍼런스하게 됩니다. 곧 Ext.util.Observable 의 constructor를 call 메서드를 통하여 호출하게 됩니다. 메서드를 Ext.data.Connection Scope에서 수행하게 됩니다.

이는 생성되면서 addEvent 를 통해서 생성된 이벤트 리스너의 동작을 켭니다. 이 말은 addEvent를 통해서 추가된 리스너들은 단지 ExtJS의 이벤트 class에 이벤트 이름만 등록하고 실제로 Ext.data.Connection 이 인스턴스화 될 때 비로소 리스너가 작동이 가능하게 됩니다.

언제나 그렇듯 말로만 보면 쉽게 이런 구조가 이해되지 않아서 간략하게 나마 그림으로 표현해 봅니다.

사용자 삽입 이미지


어차피 그림 조차도 설명이네요. ^^;

Posted by 1010
반응형
네이버 extjs 카페에 오늘 가입을 했는데 단(zican)님의 jQury 철학소개라는 글이 있어서 소개를 합니다. jQuery라고하면 unobtrusive javascript(겸손한 자바스크립트)가 가장 중요한 단어가 아닌가 합니다. CSS가 다루는 걸 Style이라고 하면 Javascript가 다루는걸 behavior라고 하고, CSS를 document에서 분리해냈듯이 javascript도 분리하자는 주의입니다.

예를들면,

<html>
<head>
<script type="text/javascript">
function view(){
...
}

</script>
</head>
<body>
<img id="photo" src="###" onclick='view()'>
</body>
</html>



<html>
<head>
<script type="text/javascript">
window.onload=function(){
    document.getElementById('photo').onclick=view;
}
</script>
</head>
<body>
<img id='photo' src="###">
</body>
</html>

body 내부에는 자바스크립트를 쓰고있지 않습니다. 이런식으로 분리해내는게 unobtrusive javascript 입니다. 그런데 id지정하고 getElementById 쓰는것도 귀찮고 손이 많이 가는 작업이니 jQuery가 알려주는 손쉬운 방법을 보죠.

<html>
<head>
<script type="text/javascript" src="jquery-1.2.6.min.js"></script>
<script type="text/javascript">
$(
    $('#photo').click(
        function(event){
            ...
        }
    )
);
</script>
</head>
<body>
<img id="photo" src="###">
</body>
</html>

초간단 예를들면 이게 뭐가 쉬워졌나 싶으실 겁니다. 어째건 첫번째로 지켜야 할 원칙 javascript는 분리해 놓은 상태입니다.

$('#photo')를 하면 document.getElementById('photo')와 동일한 역할을 합니다. 즉 $('id')하면 해당 아이디를 갖는 element를 리턴합니다. 정확히는 해당아이디를 갖는 element 배열을 리턴합니다. 작동하는 방식은 위쪽 예제와 동일합니다.

jQuery가 기본 자바스크립트보다 unobtrusive javascript를 쓰기에 적합한 장점으로는 document 내의 어떤요소를 찾을때 굉장히 편하게 찾을수 있는 방법을 제공한다는 점입니다.

id를 지정해서 찾을수 있고, 클래스가 지정된 요소를 찾을수도 있고, css selector 처럼 복잡한 요소를 찾을수도 있습니다. $("ul li dd") 이건 ul 밑에 li 밑에 dd인 element를 리턴합니다. 기존 css selector 에서 쓰는것 말고 jQuery에서 제공하는 여러필터가 있습니다. 이걸쓰면 테이블에서 홀수행 혹은 짝수행만 뽑아 올수도있고, td 중에 데이터에 year라는 문자가 있는 것만 뽑아올수도 있고, 지금 클릭한 element 바로 밑에 것 또는 바로 위에는 것 또는 부모인 것을 골라낼수도 있습니다.

즉, id같은 걸 쓰지 않고도 document DOM의 구조를 이용해서 필요한 요소를 추려 낼수 있다는게 굉장한 장점입니다. 더불어 hidden 상태인 것만 골라낼 수도 있습니다.

단님이 소개한 예제 링크를 아래에 소개해 드리겠습니다.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>$.browser Example</title>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js"></script>

<script type="text/javascript">
$(function(){
    $('.itemImg').click( function(event) {
        if (this == event.target) {
            var next = $('~ img:first', this);
            if(!next[0]){
                next = $('img:first', $(this).parents('div:first'));
            }
            $(this).hide();
            next.css('opacity', '0.01').show().animate({opacity:1}, 'slow');
         }
         return false;
    }).css('cursor', 'pointer');
});
</script>
</head>
<body>

<div>

<img class="itemImg" src='http://wstatic.naver.com/t/2008/0610/20080610112255.jpg'/>
<img class="itemImg" style="display:none" src='http://imgnews.naver.com/image/w3/2008/06/11/1213144220.jpg'/>
<img class="itemImg" style="display:none" src='http://imgnews.naver.com/image/w3/2008/06/11/1213140508.jpg'/>
</div>

<div>
<img class="itemImg" src='http://imgnews.naver.com/image/w3/2008/06/11/1213144220.jpg'/>
<img class="itemImg" style="display:none" src='http://wstatic.naver.com/t/2008/0610/20080610112255.jpg'/>
</div>

</body>
</html>
Posted by 1010
반응형

참고 : http://www.fusioncharts.com/

웹으로 통계를 이쁘게 그래프로 보여주고 싶은분들께 추천합니다.
물론 유료이긴 합니다만, 일부 그래프들은 이용 가능합니다.

필요한것은..
FusionCharts.js 자바스크립 파일과 그래프용 swf파일입니다.
(위 FusionChart 사이트에서 다운로드 가능합니다.)

아래와 같이 간단히 자바스크립트 코딩을 하면 이쁜 그래프가 나옵니다. ;-)
즉, FusionChart swf 파일에 맞는 xml 문서만 인자로 넘겨주면 됩니다.

<div id="chart1div"></div>
<script language="JavaScript" src="FusionCharts.js"></script>
<script type="text/javascript">
<!--
    var chart1 = new FusionCharts("Area2D.swf", "sampleChart1", "700", "350", "0", "1");
    chart1.setDataURL(XML페이지 주소);   
    chart1.render("chart1div");
-->
</script>

사용자 삽입 이미지
Posted by 1010
반응형



Posted by 1010
반응형
처음 Ajax framework로 잡았던 것은  prototypejs 였는데
Effect를 만들기위해서 같이 사용되었는 scriptaculous와 결합하면 너무 무거운 느낌이 들었다.
그래서 jquery를 이용하여 사이트를 오픈해 보려는 시도를 하고 있다.  
jQuery는 Core 이상의 다양한 plugin이 존재하는데 마침 Ajax 기반의 레이어 생성 코드를 찾다가 발견했다.

사이트주소 : http://fancy.klade.lv


wk2UHGzAZ8LlxczS3u/hZ2EHl8UH5B9/1bU/hhTrMH4=
Posted by 1010
반응형

jQuery 개발자를 위한 메모 - 레퍼런스

레퍼런스

$()

jQuery 오브젝트를 만들어 내는 함수입니다.

$("CSS/Xpath 문자열")

CSS/XPATH 그리고 요소를 지정해, 매치한 요소를 가진다jQuery 오브젝트를 돌려줍니다. 자세한 지정 방법은 CSS / XPath (을)를 참조해 주세요.

var $toc_1 = $("#toc_1");
jquery_dump($toc_1);
var $h1 = $("h1");
jquery_dump($h1);
var $h1head = $("h1.head");
jquery_dump($h1head);
var $ahref = $("a[@href='http://jquery.com/']");
jquery_dump($ahref);
var $h1pa = $("//p/a");
jquery_dump($h1pa);

$(DOM 요소) / $([DOM 요소의] 배열)

지정했다DOM 요소를 가진다jQuery 오브젝트를 돌려줍니다.
each (이)나 콜백 함수로 this (을)를 나팔 하는 경우에 이용한다 사용법이 많다고 생각합니다.

$(function(){
//
초기화 코드
$("#link").click(function(){
alert( $(this).html() );
return false;
});
});

$(jQuery 오브젝트)

jQuery 오브젝트의 현재 상태와 같다DOM 요소 집합을 가졌다jQuery 오브젝트를 작성합니다.
jQuery 의 스택의 최신의DOM 요소 집합이 카피되어 스택의 모든 상태까지는 카피되지 않습니다. 또,DOM 요소 자체의 카피도 되지 않습니다.

$("CSS/Xpath 문자열", 문맥)

지정된 문맥 중(안)에서, 매치하는 요소를 가진다jQuery 오브젝트를 추출해, 돌려줍니다.
일부의 범위에 한해서 검색을 실시하고 싶은 경우에 이용할 수 있습니다.
이 단락에는 class="context_header" 하지만 지정되어 있습니다.

$("title",xml.reponseXML);
alert(  $("br", $(".context_header")).size()  );

jQuery 오브젝트 조작

jQuery 오브젝트는, 복수의DOM 요소를 가질 수 있습니다.0 개의 경우도 있습니다. 그러한DOM 요소에 관한 조작을 실시하는 메소드군입니다.

size() / length

DOM 요소의 수를 표시합니다.

단락

단락

단락

var $target = $("#target_jquery_size");
alert( $("p", $target).size() );
var $target = $("#target_jquery_size");
alert( $("p.header", $target).size() );
var $target = $("#target_jquery_size");
alert( $("p", $target).length );

get()

DOM 요소를 배열로 취득합니다.

단락

단락

var $target = $("#target_jquery_get");
alert( $("p", $target).get() );
alert( $("p", $target).get()[0] );

get(N)

N 번째의DOM 요소를 취득합니다.

단락

단락

var $target = $("#target_jquery_get_N");
alert( $("p", $target).get(0) );
alert( $("p", $target).get(1) );
alert( $("p", $target).get(2) ); //
존재하지 않는 경우는 undefined
하지만 돌아간다

[N]

N 번째의DOM 요소를 취득합니다. get(N) (와)과 같습니다.

단락

단락

var $target = $("#target_jquery_get_N2");
alert( $("p", $target)[0] );
alert( $("p", $target)[1] );
alert( $("p", $target)[2] ); //
존재하지 않는 경우는 undefined
하지만 돌아간다

each( 함수)

각각의DOM 요소에 대해서, 지정한 함수를 실행합니다.
DOM 요소가this (이)가 되어 함수가 실행됩니다. jQuery 오브젝트로서 취급하고 싶은 경우는,$(this) (와)과 나팔 할 필요가 있습니다.

단락1

단락2

var $target = $("#target_jquery_each");
$("p", $target).each(function(){
alert( this );
});
var $target = $("#target_jquery_each");
$("p", $target).each(function(){
alert( $(this).html() );
});

이벤트

이벤트의 설정을 실시합니다. HTML (으)로의 onclick / onfocus 등과 같은 일을,JavaScript 옆으로부터 설정할 수 있습니다.
여기에서는 코어의 이벤트 기능에 대해 설명합니다만, 확장 이벤트라는 것이 있어, 이벤트를 보다 간단하게 설정하거나 마우스 오버등의 지원 기능이 있습니다.
bind/unbind 대신에, 확장 이벤트를 사용하는 것을 추천합니다.

bind(" 이벤트명", 함수)

대상 오브젝트에 관해서, 지정한 이벤트가 발생했을 때에, 함수를 호출하도록(듯이) 설정합니다.

unbind(" 이벤트명", 함수) / unbind(" 이벤트명")

대상 오브젝트에 관해서, 이벤트와의 묶어를 해제합니다.
함수를 지정하지 않았던 경우는, 모든 함수와의 묶어가 해제됩니다.

trigger(" 이벤트명")

대상 오브젝트에, 지정한 이벤트를 발생시킵니다.

DOM( 기본)

attr( 키) / attr( 키, 치) / attr( 해시) / removeAttr( 키)

DOM 요소의 속성을 조작합니다.
키만을 지정했을 경우는 취득, 키, 값으로의 지정이나, 해시로 지정했을 경우는, 그러한 설정치로 덧쓰기합니다. removeAttr() 의 경우는, 지정한 속성을 삭제합니다.
취득의 경우는, 최초의DOM 요소가 대상이 됩니다. 값을 설정하는 경우는, 모든DOM 요소가 대상이 됩니다.

단락

단락

var $target = $("#target_dom_attr");
var $p = $("p", $target);
alert( $p.attr("class") ); //
최초의 요소가 대상
alert( $target.html() );
$p.attr("class", "danraku3"); //
모든 요소가 대상
alert( $target.html() );
$p.removeAttr("class");
alert( $target.html() );

addClass( 클래스명) / removeClass( 클래스명) / toggleClass( 클래스명)

대상의DOM 요소에, 지정한 클래스를 추가·삭제, 혹은 타글 합니다.

단락

단락

var $target = $("#target_dom_class");
var $p = $("p", $target);
$p.addClass("addclass");
alert( $target.html() );
$p.toggleClass("danraku1");
alert( $target.html() );

text()

모든DOM 요소의 텍스트 컨텐츠를 이어 맞춘 문자열을 돌려줍니다.

단락전 텍스트

단락내 텍스트

단락 후 텍스트
var $target = $("#target_dom_text");
alert( $target.text() );
alert( $target.html() );

DOM( 속성)

jQuery 오브젝트는 복수의DOM 요소를 가집니다만,DOM 조작을 실시하는 경우, 조작 대상이 경우에 따라서 다른 것에 주의해 주세요.
참조의 경우는 최초의DOM 요소, 설정·개서의 경우는 모든DOM 요소가 대상이 됩니다.

html() / html("HTML 문자열")

DOM 요소를HTML 그리고 취득, 혹은 지정했다HTML 에 갈아넣습니다.

이 단락은 <p id="target_ref_dom_html"> 입니다.

alert(  $("#target_ref_dom_html").html()  );
$("#target_ref_dom_html").html("
단락의 내용을 고쳐 씁니다.");

val() / val( 치)

DOM 요소의 value 속성의 내용을 취득·설정합니다.

href() / href( 치) / id() / id( 치) / name() / name( 치)
/ rel() / rel( 치) / src() / src( 치) / title() / title( 치)

각각, 메소드명과 동명의 속성의 취득·설정을 실시합니다.

DOM(DOM 조작)

remove()

대상의DOM 요소를 삭제합니다.

이 단락은,<p id="target_ref_dom_remove"> 입니다.

	$("#target_ref_dom_remove").remove();

empty()

대상의DOM 요소의 아이 요소를 모두 삭제합니다.
DOM 요소 자체는 남습니다.
html() 그리고 내용을 대입할 때 등에, 일단 클리어 하고 싶은 경우에 이용할 수 있습니다.

이 단락은,<p id="target_ref_dom_empty"> 입니다.

$("#target_ref_dom_empty").empty();

append("HTML 문자열") / append(DOM 요소) / append([DOM 요소의] 배열)

대상의DOM 요소의 아이 요소의 말미에, 지정된 것을 추가합니다.

이 단락은,<p id="target_ref_dom_append"> 입니다.

$("#target_ref_dom_append").append("[[append]]");

prepend("HTML 문자열") / prepend(DOM 요소) / prepend([DOM 요소의] 배열)

대상의DOM 요소의 아이 요소의 선두에, 지정된 것을 추가합니다.

이 단락은,<p id="target_ref_dom_prepend"> 입니다.

$("#target_ref_dom_prepend").prepend("[[prepend]]");

appendTo("CSS/Xpath 문자열")

대상의DOM 요소를,CSS/XPath 지정으로 지정된 요소의 아이 요소의 말미로 이동합니다.

이 단락은,<p id="target_ref_dom_appendto"> 입니다.

이 단락은,<p id="target_ref_dom_appendto2"> 입니다.

$("#target_ref_dom_appendto").appendTo("#target_ref_dom_appendto2");

clone() (을)를 이용하는 것으로 카피할 수도 있습니다.

이 단락은,<p id="target_ref_dom_appendto_copy"> 입니다.

이 단락은,<p id="target_ref_dom_appendto_copy2"> 입니다.

$("#target_ref_dom_appendto_copy").clone()
.appendTo("#target_ref_dom_appendto_copy2");

prependTo("CSS/Xpath 문자열")

대상의DOM 요소를,CSS/XPath 지정으로 지정된 요소의 아이 요소의 선두로 이동합니다.

이 단락은,<p id="target_ref_dom_prependto"> 입니다.

이 단락은,<p id="target_ref_dom_prependto2"> 입니다.

$("#target_ref_dom_prependto").prependTo("#target_ref_dom_prependto2");

clone() (을)를 이용하는 것으로 카피할 수도 있습니다.

이 단락은,<p id="target_ref_dom_prependto_copy"> 입니다.

이 단락은,<p id="target_ref_dom_prependto_copy2"> 입니다.

$("#target_ref_dom_prependto_copy").clone()
.prependTo("#target_ref_dom_prependto_copy2");

before("HTML 문자열") / before(DOM 요소) / before([DOM 요소의] 배열)

대상의DOM 요소의 앞에, 지정된 것을 추가합니다.

이 단락은,<p id="target_ref_dom_before"> 입니다.

$("#target_ref_dom_before").before("[[before]]");

after("HTML 문자열") / after(DOM 요소) / after([DOM 요소의] 배열)

대상의DOM 요소의 뒤에, 지정된 것을 추가합니다.

이 단락은,<p id="target_ref_dom_after"> 입니다.

$("#target_ref_dom_after").after("[[after]]");

insertBefore("CSS/Xpath 문자열")

대상의DOM 요소를,CSS/XPath 지정으로 지정된 요소의 앞으로 이동합니다.

이 단락은,<p id="target_ref_dom_insertBefore1"> 입니다.

이 단락은,<p id="target_ref_dom_insertBefore2"> 입니다.

$("#target_ref_dom_insertBefore2").insertBefore("#target_ref_dom_insertBefore1");

clone() (을)를 이용하는 것으로 카피할 수도 있습니다.

이 단락은,<p id="target_ref_dom_insertBefore_copy"> 입니다.

이 단락은,<p id="target_ref_dom_insertBefore_copy2"> 입니다.

$("#target_ref_dom_insertBefore_copy").clone()
.insertBefore("#target_ref_dom_insertBefore_copy2");

insertAfter("CSS/Xpath 문자열")

대상의DOM 요소를,CSS/XPath 지정으로 지정된 요소의 뒤로 이동합니다.

이 단락은,<p id="target_ref_dom_insertAfter"> 입니다.

이 단락은,<p id="target_ref_dom_insertAfter2"> 입니다.

$("#target_ref_dom_insertAfter").insertAfter("#target_ref_dom_insertAfter2");

clone() (을)를 이용하는 것으로 카피할 수도 있습니다.

이 단락은,<p id="target_ref_dom_insertAfter_copy"> 입니다.

이 단락은,<p id="target_ref_dom_insertAfter_copy2"> 입니다.

$("#target_ref_dom_insertAfter_copy").clone()
.insertAfter("#target_ref_dom_insertAfter_copy2");

clone()

대상의DOM 요소를 복제합니다.
appendTo/prependTo/insertBefore/insertAfter 등의 메소드와 조합해 사용합니다.
샘플은 각각의 메소드를 참조해 주세요.

wrap(HTML) / wrap(DOM 요소)

대상의DOM 요소의 외측에, 지정했다HTML ·DOM 요소를 삽입합니다.

이 단락은,<p id="target_ref_dom_wrap"> 입니다.

$("#target_ref_dom_wrap").wrap("<p class='dotted'></p>");

remove("CSS/XPath 문자열")

지정한 요소만을remove() 하는 것이라고 생각합니다만, 사용법을 잘 모릅니다. . .

DOM(jQuery 오브젝트 조작)

jQuery 오브젝트가 가진다DOM 요소를 조작하는 메소드군입니다.
jQuery 오브젝트는DOM 요소의 집합을 스택으로 가지고 있어 많은 메소드는 호출해 때 상태를 스택에 보존한 다음, 조작을 실시합니다.
스택을1 개전의 단계에 되돌리려면 ,end() 메소드를 이용합니다.

end()

최신의 스택 상태를 파기해,1 개전 상태에 되돌립니다.

단락1

단락2

단락3

var $target = $("#target_ref_jquery_end");
var $p = $("p", $target);
jquery_dump($p); //
모든 p
태그가 돌려주어집니다.
$p.filter(".header"); //
스택에 카피를 추가해,
// class="header"
이외의 오브젝트를 삭제합니다.
jquery_dump($p);
$p.end();
jquery_dump($p); //
최초 상태로 돌아오기 위해, 모든 p
태그가 돌려주어집니다.

filter("CSS/XPath 지정 문자열") / filter(["CSS/XPath 지정 문자열" 의] 배열)

DOM 요소의 집합을, 지정했다CSS/XPath 지정으로 더욱 좁힙니다.
문자열의 배열로 지정했을 경우, 어느 쪽인가에 매치하는 것에 좁힙니다.
호출시 상태는 스택에 보존됩니다.

단락1

단락2

단락3

var $target = $("#target_ref_jquery_filter");
var $p = $("p", $target);
jquery_dump($p); //
모든 p
태그가 돌려주어집니다.
$p.filter(".header"); //
스택에 카피를 추가해,
// class="header"
이외의 오브젝트를 삭제합니다.
jquery_dump($p);

not("CSS/XPath 지정 문자열") / not(DOM 요소)

filter() 의 부정판입니다.
CSS/XPath 지정으로 지정된 것, 혹은 지정되었다DOM 요소를 없앱니다.
호출시 상태는 스택에 보존됩니다.

단락

단락

단락

var $target = $("#target_ref_jquery_not");
var $p = $("p", $target);
jquery_dump($p); //
모든 p
태그가 돌려주어집니다.
$p.not(".header"); //
스택에 카피를 추가해,
// class="header"
(이)가 아닌 오브젝트를 삭제합니다.
jquery_dump($p);

find("CSS/XPath 지정 문자열")

DOM 요소의 집합에 포함되는 아이 요소로부터, 지정했다CSS/XPath 지정에 매치하는 것을 추출합니다.
호출시 상태는 스택에 보존됩니다.

  • 항목1
  • 항목2
  • 항목a
  • 항목b
var $target = $("#target_ref_jquery_find");
var $ul = $("ul", $target);
jquery_dump($ul);
jquery_dump($ul.find("li"));

next() / next("CSS/XPath 지정 문자열") / prev() / prev("CSS/XPath 지정 문자열")

next() (은)는,DOM 요소의 각각의 집합에 대해서, 그 요소의 다음에 있는 요소에 옮겨놓습니다. 다음의 요소가 없는 경우는, 그 요소는 삭제됩니다.
호출시 상태는 스택에 보존됩니다.
next("CSS/XPath 지정 문자열") 의 경우,next().filter("CSS/XPath 지정 문자열") (와)과 같은 동작이 됩니다. 다만, 스택은1 회 밖에 보존되지 않습니다.
prev() / prev("CSS/XPath 지정 문자열") 하 next() (와)과 달리, 그 요소의 전의 요소에 옮겨놓습니다.

  • 항목1
  • 항목2
  • 항목a
  • 항목b

단락1

단락2

var $target = $("#target_ref_jquery_next");
var $ulnext = $("ul", $target);
jquery_dump($ulnext);
$ulnext.next();
jquery_dump($ulnext);
$ulnext.end();
jquery_dump($ulnext);
var $target = $("#target_ref_jquery_next");
var $pnext = $("p", $target);
jquery_dump($pnext);
$pnext.next();
jquery_dump($pnext);
var $target = $("#target_ref_jquery_next");
var $ulnext = $("ul", $target);
jquery_dump($ulnext);
$ulnext.next(".nextfilter");
jquery_dump($ulnext);
$ulnext.end();
jquery_dump($ulnext); // 1
개전의 스택은,next(".nextfilter")
의 실행전의 내용입니다.
var $target = $("#target_ref_jquery_next");
var $pprev = $("p", $target);
jquery_dump($pprev);
$pprev.prev();
jquery_dump($pprev);

children() / children("CSS/XPath 지정 문자열")

DOM 요소의 각각 붙고, 아이 요소를 돌려줍니다.
호출시 상태는 스택에 보존됩니다.
children("CSS/XPath 지정 문자열") 의 경우,children().filter("CSS/XPath 지정 문자열") (와)과 같은 동작이 됩니다. 다만, 스택은1 회 밖에 보존되지 않습니다.

  • 항목1
  • 항목2
  • 항목a
var $target = $("#target_ref_jquery_children");
var $children = $("ul", $target);
jquery_dump($children);
$children.children();
jquery_dump($children);
$children.children();
jquery_dump($children);
var $target = $("#target_ref_jquery_children");
var $children = $("ul", $target);
jquery_dump($children);
$children.children(".top");
jquery_dump($children);

parent() / parent("CSS/XPath 지정 문자열")

각각DOM 요소의 친요소를 돌려줍니다. 다만, 공통의 부모를 가지는 요소가 다수 있었을 경우, 부모는 1개만 돌려주어집니다.
호출시 상태는 스택에 보존됩니다.
parent("CSS/XPath 지정 문자열") 의 경우,parent().filter("CSS/XPath 지정 문자열") (와)과 같은 동작이 됩니다. 다만, 스택은1 회 밖에 보존되지 않습니다.

  • 항목1
  • 항목2
  • 항목a
var $target = $("#target_ref_jquery_parent");
var $parent = $("#target_ref_jquery_parent_2", $target);
jquery_dump($parent);
$parent.parent();
jquery_dump($parent);
$parent.parent();
jquery_dump($parent);
var $target = $("#target_ref_jquery_parent");
var $parent = $("li", $target);
jquery_dump($parent);
$parent.parent();
jquery_dump($parent);
$parent.parent();
jquery_dump($parent);
var $target = $("#target_ref_jquery_parent");
var $parent = $("li", $target);
jquery_dump($parent);
$parent.parent(".top");
jquery_dump($parent);

parents() / parents("CSS/XPath 지정 문자열")

각각DOM 요소의 친요소, 그 친요소, 그 친요소···(와)과 순서에 돌려줍니다. 다만, 루트의 요소는 포함되지 않습니다.
호출시 상태는 스택에 보존됩니다.
parents("CSS/XPath 지정 문자열") 의 경우,parents().filter("CSS/XPath 지정 문자열") (와)과 같은 동작이 됩니다. 다만, 스택은1 회 밖에 보존되지 않습니다.

  • 항목1
  • 항목2
  • 항목a
// 
이 샘플은 처리가 무겁습니다.
//
다이얼로그가 화면을 초과했을 경우,Enter
키로 닫아 주세요.
var $target = $("#target_ref_jquery_parents");
var $parents = $("#target_ref_jquery_parents_2", $target);
jquery_dump($parents);
$parents.parents();
jquery_dump($parents);
var $target = $("#target_ref_jquery_parents");
var $parents = $("li", $target);
jquery_dump($parents);
$parents.parents(".top");
jquery_dump($parents);

ancestors() / ancestors("CSS/XPath 지정 문자열")

parents() 메소드의 별명입니다. 자세한 것은 parents 메소드를 참조해 주세요.

siblings() / siblings("CSS/XPath 지정 문자열")

각각DOM 요소의 형제 요소를 돌려줍니다. 다만, 공통의 형제 요소가 다수 있었을 경우, 독특한 1개만이 돌려주어집니다.
호출시 상태는 스택에 보존됩니다.
siblings("CSS/XPath 지정 문자열") 의 경우,siblings().filter("CSS/XPath 지정 문자열") (와)과 같은 동작이 됩니다. 다만, 스택은1 회 밖에 보존되지 않습니다.

  • 항목1
  • 항목2
  • 항목a

단락

var $target = $("#target_ref_jquery_siblings");
var $siblings = $("li.top", $target);
jquery_dump($siblings);
$siblings.siblings();
jquery_dump($siblings);
var $target = $("#target_ref_jquery_siblings");
var $siblings = $("ul", $target);
jquery_dump($siblings);
$siblings.siblings();
jquery_dump($siblings);
var $target = $("#target_ref_jquery_siblings");
var $siblings = $("ul", $target);
jquery_dump($siblings);
$siblings.siblings(".top");
jquery_dump($siblings);

contains( 문자열)

DOM 요소의 집합을, 지정한 문자열을 텍스트로 가지는 요소에 좁힙니다.
호출시 상태는 스택에 보존됩니다.

  • 항목1-1
  • 항목1-2
  • 항목2-1
var $target = $("#target_ref_jquery_contains");
var $contains = $("li", $target);
jquery_dump($contains);
$contains.contains("1-");
jquery_dump($contains);

add("CSS/XPath 지정 문자열") / add(DOM 요소) / add([DOM 요소의] 배열)

DOM 요소의 집합에,CSS/XPath 지정 문자열로 매치한 요소, 혹은 지정했다DOM 요소를 더합니다.
CSS/XPath 지정 문자열을 지정하는 경우, 대상은 문서 전체가 되어,$("CSS/XPath 지정 문자열", context) 의 같은 형식에서 범위를 지정할 수 없습니다.
호출시 상태는 스택에 보존됩니다.

  • 항목1-1
  • 항목1-2

단락1

var $target = $("#target_ref_jquery_add");
var $add = $("ul", $target);
jquery_dump($add);
$add.add("#target_ref_jquery_add2");
jquery_dump($add);
var $target = $("#target_ref_jquery_add");
var $add = $("ul", $target);
jquery_dump($add);
$add.add($("p", $target)[0]); // DOM
요소를 추가합니다
jquery_dump($add);

CSS

css( 키) / css( 키, 치) / css( 해시)

CSS 의 속성을 조작합니다.
키만을 지정했을 경우는 취득, 키, 값으로의 지정이나, 해시로 지정했을 경우는, 그러한 설정치로 덧쓰기합니다.
취득의 경우는, 최초의DOM 요소가 대상이 됩니다. 값을 설정하는 경우는, 모든DOM 요소가 대상이 됩니다.

background() / background( 치) / color() / color( 치)
/ float() / float( 치) / overflow() / overflow( 치)
/ position() / position( 치)

각각, 메소드명과 동명의CSS 속성의 취득·설정을 실시합니다.

left() / left( 치) / top() / top( 치)

각각, 메소드명과 동명의CSS 속성의 취득·설정을 실시합니다.

height() / height( 치) / width() / width( 치)

각각, 메소드명과 동명의CSS 속성의 취득·설정을 실시합니다.

효과

hide() / show()

show() (은)는 지정된 요소를 비표시 상태로부터 표시 상태로 변경합니다. 벌써 표시 상태이면 아무것도 하지 않습니다.
hide() (은)는 지정된 요소를 표시 상태로부터 비표시 상태로 변경합니다. 벌써 비표시 상태이면 아무것도 하지 않습니다.

이 단락은<p id="target_ref_effect_show"> 입니다.

$("#target_ref_effect_show").show();
$("#target_ref_effect_show").hide();

toggle()

지정된 요소의 표시·비표시를 바꿉니다.

이 단락은<p id="target_ref_effect_toggle"> 입니다.

$("#target_ref_effect_toggle").toggle();

기본 효과 (Basic Animations)

[Configure Your Download] 했을 경우,[Basic Animations] (을)를 선택하고 있지 않으면 이하의 함수는 이용할 수 없습니다.

show( 속도) / show( 속도, 콜백 함수)
/ hide( 속도) / hide( 속도, 콜백 함수)

show() / hide() (은)는 요소의 사이즈를 변경하면서, 표시한다, 혹은 비표시로 합니다.
표시중의 요소에 show() (을)를 사용하거나 그 역을 실시하면, 불필요한 애니메이션이 실행되는 일이 있습니다. 이것을 막기 위해서는, 요소의 지정에 :hidden ,:visible (을)를 이용해 주세요.
속도는,"fast", "normal", "slow" 의 어느쪽이든을 지정하는지,ms(1/1000 초) 단위의 수치로 지정합니다.
제2 인수에 콜백 함수를 지정하면, 애니메이션이 완료했을 때에 콜백 함수가 불려 갑니다.

이 단락은<p id="target_ref_effect_show_speed"> 입니다.

$("#target_ref_effect_show_speed").show(2000);
$("#target_ref_effect_show_speed").hide("slow");
$("#target_ref_effect_show_speed:hidden").show("normal");
$("#target_ref_effect_show_speed:visible").hide("slow",
function(){
alert( "animation done." );
});

slideDown( 속도) / slideDown( 속도, 콜백 함수)
/ slideUp( 속도) / slideUp( 속도, 콜백 함수)
/ slideToggle( 속도) / slideToggle( 속도, 콜백 함수)

slideDown() / slideUp() (은)는 요소를 슬라이드시키면서, 표시한다, 혹은 비표시로 합니다.slideToggle() (은)는, 표시·비표시를 바꿉니다.
표시중의 요소에 slideDown() (을)를 사용하거나 그 역을 실시하면, 불필요한 애니메이션이 실행되는 일이 있습니다. 이것을 막기 위해서는, 요소의 지정에 :hidden ,:visible (을)를 이용해 주세요.
속도는,"fast", "normal", "slow" 의 어느쪽이든을 지정하는지,ms(1/1000 초) 단위의 수치로 지정합니다.
제2 인수에 콜백 함수를 지정하면, 애니메이션이 완료했을 때에 콜백 함수가 불려 갑니다.

이 단락은<p id="target_ref_effect_slide"> 입니다.

$("#target_ref_effect_slide").slideDown(2000);
$("#target_ref_effect_slide").slideUp("slow");
$("#target_ref_effect_slide:hidden").slideDown("normal");
$("#target_ref_effect_slide:visible").slideUp("slow",
function(){
alert( "animation done." );
});
$("#target_ref_effect_slide").slideToggle("normal");

fadeIn( 속도) / fadeIn( 속도, 콜백 함수)
/ fadeOut( 속도) / fadeOut( 속도, 콜백 함수)
/ fadeTo( 속도, 투명도) / fadeTo( 속도, 투명도, 콜백 함수)

fadeIn() / fadeOut() (은)는 요소를 페이드시켜, 표시한다, 혹은 비표시로 합니다. fadeTo() (은)는 지정된 투명도까지 애니메이션 시킵니다.
대상이 되는 오브젝트는, 폭·높이가 벌써 결정하지 않으면 안됩니다.
표시중의 요소에 fadeIn() (을)를 사용하거나 그 역을 실시하면, 불필요한 애니메이션이 실행되는 일이 있습니다. 이것을 막기 위해서는, 요소의 지정에 :hidden ,:visible (을)를 이용해 주세요.
속도는,"fast", "normal", "slow" 의 어느쪽이든을 지정하는지,ms(1/1000 초) 단위의 수치로 지정합니다.
제2 인수 또는 제3 인수에 콜백 함수를 지정하면, 애니메이션이 완료했을 때에 콜백 함수가 불려 갑니다.

이 단락은<p id="target_ref_effect_fade"> 입니다.

$("#target_ref_effect_fade").fadeIn(2000);
$("#target_ref_effect_fade").fadeOut("slow");
$("#target_ref_effect_fade:hidden").fadeIn("normal");
$("#target_ref_effect_fade:visible").fadeOut("slow",
function(){
alert( "animation done." );
});
$("#target_ref_effect_fade").fadeTo("slow", 0.5);
$("#target_ref_effect_fade").fadeTo("slow", 0.1);

animate( 파라미터, 속도, 콜백 함수)

높이, 투명도등의 파라미터를 지정하고, 애니메이션을 시키는 메소드입니다.
파라미터에는,"height", "top", "opacity" 등을, 어떻게 변화시킬까 "show", "hide", 수치로 지정합니다. 숫자의 지정은 left/top 등에 대해 잘 움직이지 않는 것이 있는 것 같습니다.
속도는,"fast", "normal", "slow" 의 어느쪽이든을 지정하는지,ms(1/1000 초) 단위의 수치로 지정합니다.
제3 인수에 콜백 함수를 지정하면, 애니메이션이 완료했을 때에 콜백 함수가 불려 갑니다.

이 단락은<p id="target_ref_effect_animate"> 입니다.

// 1
회라도show/hide
(을)를 실시하면,CSS
의 설정에 overflow: hidden
(이)가 더해져 동작이 변화합니다.
// overflow:hidden
하지만 없는 경우(최초 상태)에서는, 폭이 좁아지면 개행을 해 높이가 바뀝니다.
// overflow:hidden
하지만 있는 경우(show/hide
후 )에서는, 폭이 좁아지면, 표시할 수 없는 부분은 숨습니다.
// width
변경으로 높이를 바꾸고 싶지 않은 경우는,CSS
정의에 주의해 주세요.
$("#target_ref_effect_animate").animate({
width: 100
}, "slow");
$("#target_ref_effect_animate").animate({
width: 500
}, "slow");
$("#target_ref_effect_animate").animate({
opacity: 'show',
height: 'show'
}, "slow");
$("#target_ref_effect_animate").animate({
opacity: 'hide',
height: 'hide'
}, "slow");

확장 이벤트 (Advanced Events)

[Configure Your Download] 했을 경우,[Advanced Events] (을)를 선택하고 있지 않으면 이하의 함수는 이용할 수 없습니다.

event( 함수)
/ unevent( 함수) / unevent()
oneevent( 함수)

이벤트의 설정을 실시합니다. HTML (으)로의 onclick / onfocus 등과 같은 일을,JavaScript 옆으로부터 설정할 수 있습니다.
이탤릭의event 에, 설정하고 싶은 이벤트명을 기술합니다. 기술할 수 있는 이벤트는 이하와 같습니다.

blur,focus,load,resize,scroll,unload,click,dblclick, mousedown,mouseup,mousemove,mouseover,mouseout,change,reset,select, submit,keydown,keypress,keyup,error

event() 그리고 이벤트에 함수를 묶습니다.
unevent() 그리고, 이벤트가 묶어를 해제합니다.함수를 지정하지 않으면, 모든 묶어가 해제됩니다.
oneevent() (은)는, 이벤트에 함수를 묶습니다만, 한 번 이벤트가 발생하면 묶어가 해제됩니다.
여러 차례 묶으면, 그 회수만 함수가 실행되는 것에 주의해 주세요.

이 단락은<p id="target_ref_event"> 입니다.

$("#target_ref_event").click(function(){
alert( "clicked!" );
});
//
이 샘플을 실행 후, 위의 점선의 단락을 클릭해 보세요.
$("#target_ref_event").unclick();
$("#target_ref_event").oneclick(function(){
alert( "clicked!" );
});
//
이 샘플을 실행 후, 위의 점선의 단락을 클릭해 보세요.
//
최초의1
회만alert
하지만 팝업 합니다.

ready( 함수)

$(document).ready( 함수) 의 형태로 이용해, 문서가 로드 되었을 때에 초기화 처리를 실행합니다.
이 긴 문자열 대신에, 짧고 $( 함수) (이)라고 쓸 수 있기 때문에, 이쪽을 이용하는 것을 추천합니다.

$(function(){
// HTML
로드 후에 실행하고 싶은 초기화 코드
});
$(document).ready(function(){
// HTML
로드 후에 실행하고 싶은 초기화 코드
});

hover(over 함수,out 함수)

마우스 오버 처리를 행하기 위한 이벤트를 설정합니다.
마우스가 대상 오브젝트에 들어갔을 때에 over 함수 하지만 불려 가 나왔을 때에 out 함수 하지만 불려 갑니다.

이 단락은<p id="target_ref_event_hover"> 입니다.

$("#target_ref_event_hover").hover(function(){
//
대상 오브젝트에 들어갔다
$(this).addClass("background_red");
}, function(){
//
대상 오브젝트로부터 빠졌다
$(this).removeClass("background_red");
});
//
이 샘플을 실행 후, 위의 점선의 단락에 마우스 커서를 이동해 보세요.

toggle( 함수1, 함수2)

대상 오브젝트가 클릭될 때마다, 함수1 , 함수2 (을)를 교대로 호출합니다.

이 단락은<p id="target_ref_event_toggle"> 입니다.

$("#target_ref_event_toggle").toggle(function(){
// (0
(으)로부터 세어)
짝수 번째의 클릭
$(this).addClass("background_red");
}, function(){
//(0
(으)로부터 세어)
홀수 번째의 클릭
$(this).removeClass("background_red");
});
//
이 샘플을 실행 후, 위의 점선의 단락을 클릭해 보세요.

Ajax (Basic AJAX)

[Configure Your Download] 했을 경우,[Basic AJAX] (을)를 선택하고 있지 않으면 이하의 함수는 이용할 수 없습니다.
여러가지 메소드를 이용했다Ajax 메소드 테스트 페이지 도 참조해 주세요.

load(url,params,callback)

Ajax 그리고 리모트의 파일을 읽어들여, 옮겨놓습니다.
callback 함수를 지정했을 경우, 제1 인수에 리모트의 파일 내용, 제2 인수에 스테이터스가 돌아갑니다. 스테이터스는,"success" 인가 "error" 의 어느 쪽인지입니다.
params (을)를 지정했을 경우는POST 메소드, 지정하지 않는 경우는GET 메소드가 됩니다.

이 단락은,<p id="target_ref_ajax_load"> 입니다.

$("#target_ref_ajax_load").load("hello.html");
$("#target_ref_ajax_load").load("hello.html", function(html, status){
alert( "html: " + html + "nstatus: " + status );
});
$("#target_ref_ajax_load").load("notfound.html", function(html, status){
alert( "html: " + html + "nstatus: " + status );
});

Ajax 메소드 테스트 페이지 도 참조해 주세요.

loadIfModified(url,params,callback)

load (와)과 같은 동작을 합니다만, 같다URL 에 대해서 여러 차례 loadIfModified() 했을 경우에, 2 번째 이후에 If-Modified-Since 헤더 첨부로 리퀘스트를 실시합니다. 만약 리모트의 파일이 갱신되어 있지 않은 경우,DOM 요소의 치환 하행 깨지지 않습니다.
리모트의 파일의 갱신을 정기적으로 체크하는 경우에 이용할 수 있습니다.
callback 함수를 지정했을 경우, 제1 인수에 리모트의 파일 내용, 제2 인수에 스테이터스가 돌아갑니다. 스테이터스는,"success" 인가 "notmodified" 인가 "error" 의 머지않아인가입니다.
params (을)를 지정했을 경우는POST 메소드, 지정하지 않는 경우는GET 메소드가 됩니다.

Ajax 메소드 테스트 페이지 도 참조해 주세요.

$.get(url,params,callback)

Ajax 그리고 리모트의 파일을GET 메소드로 읽어들여, 파일 내용을 돌려줍니다.
인수의 지정 방법은 $.load() (와)과 같습니다.

Ajax 메소드 테스트 페이지 도 참조해 주세요.

$.getIfModified(url,params,callback)

Ajax 그리고 리모트의 파일을GET 메소드로 읽어들여, 파일 내용을 돌려줍니다.
인수의 지정 방법은 $.loadIfModified() (와)과 같습니다.

Ajax 메소드 테스트 페이지 도 참조해 주세요.

$.post(url,params,callback)

Ajax 그리고 리모트의 파일을POST 메소드로 읽어들여, 파일 내용을 돌려줍니다.
인수의 지정 방법은 $.load() (와)과 같습니다.

Ajax 메소드 테스트 페이지 도 참조해 주세요.

$.ajaxTimeout(Timeout)

Ajax 계의 함수·메소드의 타임 아웃을ms 단위(1/1000 초)로 지정합니다. 0 (을)를 지정했을 경우는, 타임 아웃 처리를 실시하지 않습니다. 디폴트에서는0 하지만 설정되어 있습니다.
타임 아웃 시간 기다려도 리퀘스트가 완료하지 않는 경우,error 취급이 됩니다.
hello_timeout.cgi 하5 초간 응답을 돌려주지 않는다CGI 입니다. 브라우저의 캐쉬를 막기 위해서, 파라미터를 추가하고 있습니다.

이 단락은 <p id="target_ref_ajax_load_timeout"> 입니다.

$.ajaxTimeout(2000); // 
단위는ms
$("#target_ref_ajax_load_timeout").load("hello_timeout.cgi", {
timekey: 1
}, function(text, status) {
alert( "text: " + text + "nstatus: " + status );
});
$.ajaxTimeout(0); // 0
지정으로 타임 아웃 없음이 됩니다
$("#target_ref_ajax_load_timeout").load("hello_timeout.cgi", {
timekey: 1
}, function(text, status) {
alert( "text: " + text + "nstatus: " + status );
});

Ajax 메소드 테스트 페이지 도 참조해 주세요.

ajaxStart( 콜백 함수) / ajaxStop( 콜백 함수)
/ ajaxComplete( 콜백 함수) / ajaxError( 콜백 함수) / ajaxSuccess( 콜백 함수)

Ajax 호출해에 관한 글로벌인 콜백 함수를 설정합니다.
읽기중에 애니메이션을 표시시키는, 등의 목적으로 이용할 수 있습니다.
Ajax 리퀘스트가 실행중이 되었을 때에 ajaxStart 의 콜백이 불려 가 모든 리퀘스트의 실행이 완료했을 때에 ajaxStop 의 콜백이 불려 갑니다.
동시에 복수의 리퀘스트가 실행되었을 경우,ajaxStart/ajaxStop (은)는 최초와 마지막에1 회씩 불려 갑니다.
ajaxComplete / ajaxError / ajaxSuccess (은)는,Ajax 리퀘스트가 완료·실패·성공했을 때에, 리퀘스트마다 불려 갑니다.
1 회의 리퀘스트로,ajaxComplete 하지만1 회와ajaxError/ajaxSuccess 의 어느 쪽인지가1 회 불려 갑니다.

$("#loading").ajaxStart(function(){
$(this).show();
});
$("#loading").ajaxStop(function(){
$(this).hide();
});

Ajax 메소드 테스트 페이지 도 참조해 주세요.
ajaxStart/ajaxStop 그리고 화면상부에 애니메이션을 표시하고 있습니다.

유틸리티 함수

유틸리티 함수군입니다.$.method 그렇다고 하는 형식에서 이용할 수 있게 되어 있습니다.

$.each( 오브젝트/ 배열, 함수)

오브젝트 또는 배열의 모든 요소에 대해서, 지정한 함수를 호출합니다.
배열에 대해서 실행했을 경우, 함수의 제1 인수에 배열의 첨자(0 시작)이,this 에 요소가 건네받습니다.
오브젝트에 대해서 실행했을 경우, 함수의 제1 인수에 키가,this 에 값이 건네받습니다.

// 
배열의 경우
$.each(["
있어","
","
하"], function(i){
alert( "
배열[" + i + "] = " + this );
});
// 
오브젝트의 경우
$.each({ key1: "value1", key2: "value2" }, function(i){
alert( "
인수: " + i + "n
치: " + this );
});

$.extend( 오브젝트1, 오브젝트2)

오브젝트1 에 오브젝트2 의 내용을 더합니다.
계승을 실시할 때에 이용할 수 있습니다.

var settings = { key1: 1, key2: 2 };
var add = { key2: "
아", key3 : "
있어" };
$.extend(settings, add);
$.each(settings, function(i) {
alert( "
인수: " + i + "n
치: " + this );
});

$.grep( 배열, 함수, 반전 플래그)

배열의 각 요소에 대해서 함수를 실행해, 그 결과에 의해서 배열로부터 요소를 꺼냅니다. 원래의 배열은 변경되지 않습니다.
반전 플래그가false 의 경우는, 함수의 실행 결과가 true 의 요소를 꺼냅니다. 반전 플래그가true 의 경우, 그 거꾸로 됩니다. 생략 했을 경우, 반전 플래그는 false (으)로서 다루어집니다.

var data = [1,2,3,4];
var data2 = $.grep(data, function(i){
return (i % 2 == 0);
});
$.each(data2, function(i){
alert( "
배열[" + i + "] = " + this );
});
var data = [1,2,3,4];
var data2 = $.grep(data, function(i){
return (i % 2 == 0);
}, true);
$.each(data2, function(i){
alert( "
배열[" + i + "] = " + this );
});

$.map( 배열, 함수)

배열의 각 요소에 대해서 함수를 실행해, 그 함수의 반환값의 배열을 돌려줍니다. 원래의 배열은 변경되지 않습니다.
함수가 값을 돌려주면 그 값이 그대로 반환값에 포함됩니다. 함수가undefined (을)를 돌려주었을 경우는 반환값에는 포함되지 않습니다. 함수가 배열을 돌려주었을 경우는, 배열 오브젝트가 아니고, 각각의 값이 반환값의 배열에 추가됩니다.

var data = [1,2,3];
var data2 = $.map(data, function(i){
return i * 10;
});
$.each(data2, function(i){
alert( "
배열[" + i + "] = " + this );
});
var data = [1,2,3];
var data2 = $.map(data, function(i){
if(i == 2) {
return undefined;
}
return i * 10;
});
$.each(data2, function(i){
alert( "
배열[" + i + "] = " + this );
});
var data = [1,2];
var data2 = $.map(data, function(i){
return [i*10, i*100];
});
$.each(data2, function(i){
alert( "
배열[" + i + "] = " + this );
});

$.merge( 배열1, 배열2)

지정되었다2 개의 배열을 머지 합니다만, 중복은 없앱니다. 원래의 배열은 양쪽 모두 변경되지 않습니다.
중복이 있는 경우, 우선 배열1 의 내용이 모두 돌려주어진 후, 배열2 중 배열1 (와)과 중복되지 않은 것이 돌려주어집니다. 배열1 중(안)에서 중복 하고 있는 요소나, 배열2 중(안)에서 중복 하고 있는 요소는, 존재하는 개수분 돌려주어집니다.

var data1 = [1,2];
var data2 = [3,4];
var mergedata = $.merge(data1, data2);
$.each(mergedata, function(i){
alert( "
배열[" + i + "] = " + this );
});
var data1 = [1,2,1];
var data2 = [4,2,3,1,3];
var mergedata = $.merge(data1, data2);
$.each(mergedata, function(i){
alert( "
배열[" + i + "] = " + this );
});

$.trim( 문자열)

문자열의 전후에 있는 공백을 없앤 문자열을 돌려줍니다.

var str = "  
안녕하세요 ";
alert( "[" + str + "]" );
str = $.trim(str);
alert( "[" + str + "]" );
// 
탭이나 개행도 공백으로 간주해집니다
var str = "t
안녕하세요n";
alert( "[" + str + "]" );
str = $.trim(str);
alert( "[" + str + "]" );
// 
전각 공백도 없앨 수 있습니다
var str = "
 안녕하세요 ";
alert( "[" + str + "]" );
str = $.trim(str);
alert( "[" + str + "]" );

크로스 브라우저 함수

크로스 브라우저를 위한 함수군입니다. 아마 가까운 시일내에 코어에 추가된다고 생각합니다만, 현단계에서는 사용할 수 없습니다.

height()

오브젝트의 높이를 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 CSS 의 높이를 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 높이(innerHeight ), $(window) 에 대해서 사용하면, 표시 영역의 높이를 돌려줍니다.

이 단락은 <p id="target_ref_cross_height"> 입니다.

alert(  $("#target_ref_cross_height").height()  );
alert(  $(document).height()  );
alert(  $(window).height()  );

width()

오브젝트의 폭을 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 CSS 의 폭을 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 폭(innerWidth ), $(window) 에 대해서 사용하면, 표시 영역의 폭을 돌려줍니다.

이 단락은 <p id="target_ref_cross_width"> 입니다.

alert(  $("#target_ref_cross_width").width()  );
alert(  $(document).width()  );
alert(  $(window).width()  );

innerHeight()

오브젝트의 높이를 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 보더를 포함하지 않는 높이를 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 높이(innerHeight ), $(window) 에 대해서 사용하면, 표시 영역의 높이를 돌려줍니다.

이 단락은 <p id="target_ref_cross_innerheight"> 입니다.

alert(  $("#target_ref_cross_innerheight").innerHeight()  );
alert(  $(document).innerHeight()  );
alert(  $(window).innerHeight()  );

innerWidth()

오브젝트의 높이를 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 보더를 포함하지 않는 폭을 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 폭(innerWidth ), $(window) 에 대해서 사용하면, 표시 영역의 폭을 돌려줍니다.

이 단락은 <p id="target_ref_cross_innerwidth"> 입니다.

alert(  $("#target_ref_cross_innerwidth").innerwidth()  );
alert(  $(document).innerwidth()  );
alert(  $(window).innerwidth()  );

outerHeight()

오브젝트의 높이를 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 보더를 포함한 높이를 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 높이(outerHeight ), $(window) 에 대해서 사용하면, 표시 영역의 높이를 돌려줍니다.

이 단락은 <p id="target_ref_cross_outerheight"> 입니다.

alert(  $("#target_ref_cross_outerheight").outerHeight()  );
alert(  $(document).outerHeight()  );
alert(  $(window).outerHeight()  );

outerWidth()

오브젝트의 높이를 취득합니다.
임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 보더를 포함한 폭을 돌려줍니다. $(document) 에 대해서 사용하면, 문서의 폭(outerWidth ), $(window) 에 대해서 사용하면, 표시 영역의 폭을 돌려줍니다.

이 단락은 <p id="target_ref_cross_outerwidth"> 입니다.

alert(  $("#target_ref_cross_outerwidth").outerwidth()  );
alert(  $(document).outerwidth()  );
alert(  $(window).outerwidth()  );

scrollLeft() / scrollTop()

오른쪽 또는 아래에 스크롤 된 양을 취득합니다.
overflow:auto 의 요소를 가지는 임의의jQuery 오브젝트,$(document) ,$(window) 에 대해서 이용할 수 있습니다. jQuery 오브젝트에 대해서 사용하면, 최초의 요소의 스크롤 위치를 돌려줍니다.다만, 요소는 overflow:auto 일 필요가 있습니다. $(document) 에 대해서 사용하면, 문서에 대한 스크롤 위치,$(window) 에 대해서 사용하면, 표시 영역에 대한 스크롤 위치를 돌려줍니다.

이 단락은 <p id="target_ref_cross_scroll"> 입니다.

alert(  $("#target_ref_cross_scroll").scrollLeft()  );
alert( $("#target_ref_cross_scroll").scrollTop() );
alert(  $(document).scrollLeft()  );
alert( $(document).scrollTop() );
alert(  $(window).scrollLeft()  );
alert( $(window).scrollTop() );
Posted by 1010
반응형


Open-Source 기반의 Javascript Library중 하나인 jQuery를 Microsoft에서 적용하기로 했습니다.(많이 늦은 내용.. 찾아보니 처음 기사를 본게.. 9월30일입니다.) 자세한 내용은 본사의 부사장으로 계신 우리의 Scott님의 블로그를 http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx 를 참고 하시길 바랍니다.


Prototype과 비슷한 모습을 하고 있지만 Query라는 단어에서 느껴지듯이 상당한 유연성을 제공합니다.


가볍고 크로스브라우져에 강하다는 문구가 많은 설득력을 가지고 있어 보입니다.

이전 프로젝트까지는 모두 Prototype을 했었지만 앞으로는 jQuery를 이용해볼 생각입니다.
Prototype만큼이나 관련 페이지에 API와 DOC가 예제와 함께 깔끔하게 정리 되어 있어서, 약간의 수고만 한다면 도서를 구입하지 않고도 기능을 충분히 활용할 수 있을것으로 보입니다.

Protorype과 script.aculo.us에서 구현하는 효과와 기술은 PlugIN과 UI에서 지원하고 있으며, 사용법 또한 script.aculo.us와 마찮 가지로 매우 간단하며, 강력한 효과를 보입니다.
 
참고 URL :
Script.aculo.us : http://script.aculo.us/
Posted by 1010
반응형

Downloading jQuery

From jQuery JavaScript Library

Jump to: navigation, search

Contents

About The Code

The code itself is written rather cleanly in an attempt to self-document. If you've spotted some areas of code that could be improved, please feel free to discuss it on the Development mailing list. All input is gladly appreciated!

All of the code is available in two formats:

  • Compressed (which allows you to have a significantly smaller file size) and
  • Uncompressed (good for debugging and to understand what is behind the magic).

If you're interested in downloading Plugins developed by jQuery contributors, please visit the Plugins page.

jQuery is provided under the following MIT and GPL licenses.

Download jQuery

This is the recommended version of jQuery to use for your application. The code in here should be stable and usable in all modern browsers.

The minified version, while having a larger file size than the packed version, is generally the best version to use on production deployments. The packed version requires non-trivial client-side processing time to uncompress the code.

Current Release

Past Releases

Nightly Builds

The source code in the Subversion repository, mentioned below, is also built and made available on a nightly basis. This is mostly for people who either do not have access to the Subversion repository, or who don't want to go to the trouble of checking out a copy from the repository, and then building jQuery themselves.

The nightly files are available at http://code.jquery.com/nightlies/. Inside that directory the following files are available:

Subversion (SVN)

Note: The following is quite advanced. If you wish to just use a more-recent version of jQuery, please try one of the nightly builds, mentioned previously.

All source code is kept under Subversion control, which you can browse online. There's a download link available for any file or directory, if you only want to download a portion of the jQuery code.

If you have access to Subversion, you can connect to the repository here:

svn co http://jqueryjs.googlecode.com/svn/trunk

You can also check out a specific version of jQuery from subversion at:

svn co http://jqueryjs.googlecode.com/svn/tags/<version>
e.g. svn co http://jqueryjs.googlecode.com/svn/tags/1.0.4

If you want to build your own copy of jQuery from the Subversion repository, you will need to build it.

Note: The jQuery UI code has moved to a separate repository:

svn co http://jquery-ui.googlecode.com/svn/tags

Build Requirements

jQuery currently requires the following components to be installed:

  • A build system (either make or ant works):
    • make: Available on most Unix-based system (Unix, BSD, OSX, Cygwin)
    • ant: Available on any platform with JDK and ANT installed
  • java: A copy of Java, version 1.4.0 or later

Build Process

You will now need to use the build system that you chose previously - either make or ant.

First, go into the main jQuery directory (the root directory will contain six directories: jquery, plugins, qunit, themes, tools and ui; go into jquery).

If you're using make:

  • To create jQuery: make
    • This will create jquery.js, jquery.pack.js, and jquery.lite.js in the dist directory
    • This will create cat.xml and index.xml in the docs directory (as well as style information)
    • This will build tests in the test directory
  • To just build docs: make docs
  • To just build packed jQuery: make pack
  • To just build tests: make test

If you're using ant:

  • To create jQuery: ant
    • This will create jquery.js, jquery.pack.js, and jquery.lite.js in the dist directory
    • This will create cat.xml and index.xml in the docs directory (as well as style information)
    • This will build tests in the test directory
  • To just build docs: ant docs
  • To just build packed jQuery: ant pack
  • To just build tests: ant test
Posted by 1010
01.JAVA/Java2008. 11. 19. 14:19
반응형

■ 환경 설정

개발 환경 설정에는 다음과 같이 3가지 방법이 있다.

1. JSDK 1.3이하 버젼 & JCE 1.2.1 글로벌 버전 JCE 1.2.1 버전은 http://java.sun.com 사이트에서 회원가입을 해야지 Down 받을수 있다. JCE는 미국에서 무기로 관주 되기 때문에 글로벌 버전은 미국, 케나다 버전과 다르다.

2. JSDK 1.4에는 Java Cryptography Extension 1.2.1 버전이 포함되어 있다.

3. 다운 받은 JCE의 압축을 풀고 lib방 밑에 있는 모든 jar파일을[JavaHome]jrelibext방으로 카피한다. 그리고 JCE 알고리즘을 사용하기 위해서 SunJCE 프로바이터를 설치 해야 한다.

설치하기 위해서는 [JavaHome]jrelibsecurityjava.security 파일에 다음을 추가한다.

security.provider.1=sun.security.provider.Sun,

security.provider.2=com.sun.crypto.provider.SunJCE


■ 서로 다른 개념들

1. 보안 != 암호 : 애플리케이션에 암호를 추가하는 것이 애플리케이션을 안전하게 하지 못한다.

2. 올바른 보안 모델 != 버그가 없는 구현 : 훌륭한 보안 모델이라고 해도 구현 과정에서의 버그는 공겨자의 대상이 될 수 있다.

3. 테스트 != 공식적인 증명

4. 컴포넌트 보안 != 전반적인 시스템 보안

5. 자바 보안 != 애플릿 통제

Base 64

Base64는 바이트 배열을 아스키 문자로 표현하기 위한 시스템이다. Base64체계는 RFC1521의 Section5.2에 완전하게 기술되어 있다. sun.misc.BASE64Encoder는 바이트 배열을 가지고 base64 disit를 가지 문자열을 생성한다. 이에 대응하는 클래스 BASE64Decoder는 문자열을 가지고 원래 바이트 배열을 생성한다.

Sun에서는 Base64를 지원할 의무가 없다.

■ 예제 프로그램

//-- Masher 메시지 축약

package test.crypto.part1;

import java.security.*;

import java.io.*;

import sun.misc.*;

public class Masher {

public Masher() {

}

private void exec(String targetFileName) {

try {

// MD5알고리즘을 이용한 메시지 축약 객체를 생성한다.

MessageDigest md = MessageDigest.getInstance("MD5");

FileInputStream fin = new FileInputStream(targetFileName);

byte[] buffer = new byte[8192];

int length;

while ( (length = fin.read(buffer)) != -1 ) {

md.update(buffer,0,length);

}

byte[] raw = md.digest();

// 출력 가능한 문자열로 변환한다.

BASE64Encoder encoder = new BASE64Encoder();

String base64 = encoder.encode(raw);

System.out.println(base64);

} catch(NoSuchAlgorithmException nalgoe) {

System.err.println(nalgoe);

} catch(FileNotFoundException fnote) {

System.err.println(fnote);

} catch(IOException ioe) {

System.err.println(ioe);

}

}

public static void main(String[] args) {

if(args.length < 1) {

System.out.println("메시지 축약의 대상 파일을 선택하여 주십시요");

System.exit(0);

}

String targetFileName = args[0];

Masher masher = new Masher();

masher.exec(targetFileName);

}

}


매시지 축약은 데이터를 증명하지만, 메시지에 대해서는 전혀 알 수 없다.

// DES알고리즘을 이용한 대칭키 암복호화

package test.crypto.part1;

import javax.crypto.*;

import java.io.*;

import java.security.*;

import sun.misc.*;

public class SecretWriting {

public SecretWriting() {

}

public void exec(String args[]) throws Exception{

// key를 얻어 생성한다.

Key key;

try{

ObjectInputStream in = new ObjectInputStream(new FileInputStream("SecretKey.ser"));

key = (Key)in.readObject();

in.close();

} catch (FileNotFoundException fnote) {

// ser Key 파일이 없으면 실행된다.

// DES 대칭키 알고리즘을 정의해서 키 제너레이터를 생성한다.

KeyGenerator keygenerator = KeyGenerator.getInstance("DES");

// 랜덤 함수로 초기화한다.

keygenerator.init(new SecureRandom());

// 키를 생성한다.

key = keygenerator.generateKey();

// 생성된 키 객체를 바이널리 파일로 저장한다.

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("SecretKey.ser"));

out.writeObject(key);

out.close();

}

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");

// -e문자열이 없으면 복호화 한다. 다음은 암호화 한다.

if(args[0].indexOf("e") != -1) {

cipher.init(Cipher.ENCRYPT_MODE,key);

String amalgam = args[1];

for(int i = 2; i < args.length; i++) {

amalgam += " "+args[i];

}

byte[] stringBytes = amalgam.getBytes("UTF8");

byte[] raw = cipher.doFinal(stringBytes);

BASE64Encoder encoder = new BASE64Encoder();

String base64 = encoder.encode(raw);

System.out.println(base64);

} else if(args[0].indexOf("d") != -1) {

cipher.init(Cipher.DECRYPT_MODE,key);

BASE64Decoder decoder = new BASE64Decoder();

byte[] raw = decoder.decodeBuffer(args[1]);

byte[] stringBytes = cipher.doFinal(raw);

String result = new String(stringBytes, "UTF8");

System.out.println(result);

}

}

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

if(args.length < 2) {

System.out.println("사용예 java tesst.crypto.part1.SecretWriting -[e|d] STRING1 STRING2 ...");

System.exit(0);

}

SecretWriting secretWriting = new SecretWriting();

secretWriting.exec(args);

}

}

DES 알고리즘은 동일한 키를 생성하여 암호화와 복호화가 이루워지는 대칭키 방식이다.

Chapter 2 기본기

■ 보안의 3대 규칙

1. 기밀성(Confidentially) : 비인가 된 사람은 내용을 볼 수 없어야 한다.

① 대칭암호화 : 송신측과 수신측이 동일한 키를 사용한다.(비밀키, 개인키 방식)


② 비대칭 암호화 : A의 공개키로 암호화 한 내용은 A의 개인키로만 풀 수 있다. 비대칭 암호화는 대칭 암호화에 비해 상당히 느리다.


2. 무결성(Integrity) : Date가 불법수정되지 못하게 보장한다. 암호화된 메시지 축약을 서명(signature)이라고 한다.


3. 인증(Authentication) : 상호 교신하는 사람이 각각 믿을수 있는 객체임을 보장한다.

인증서는 한 사람에 의해 발급되는 문장으로 다른 사람의 공개키를 가지는 어떤 값이다. 필수적으로 인증서는 서명된 공개키이다.


■ 알고리즘

비대칭 암호화와 서명은 다양한 키 크기를 가진다. 적절한 키 크기를 선태가하는 것은 사용자와 애플리케이션에 달려 있다.

명 칭
타 입
비 고

MD-5
메시지 축약
128비트 메시지 축약 생성

저항력에 약간의 허점을 발견

SHA-1
메시지 축약
160비트의 메시지 축약 생성

저항력이 증가

HmacMD5와 HmacSHA1
메시지 인증 코드


DSA
서명
512 ~ 1024비트 까지의 키 생성

ElGamal 서명
서명


DES
대칭 암호화


DESede
대칭 암호화


PBEWithMD5AndDES
대칭 암호화


ElGamal 암호
비대칭 암호화


DH
키 교환

표) 암호화 알고리즘

클래스/인터페이스
정의

java.security.cert.Certificate
암호인증

javax.crypto.Cipher
암호화

java.security.Key. java.security.PrivateKey, java.security.PublicKey, javax.crypto.SecretKey
서명이나 암호화에 사용되는키

javax.crypto.KeyAgreement
비밀키 교환 프로토콜

java.security.KeyFActory
공개키와 비밀키의 형식 변환

javax.crypto.KeyGenerator
대칭암호문에 사용될 키 생성

java.security.KeyPairGenerator
암호화와 인증에 사용된 공개키와 비밀키 생성

javax.crypto.Mac
메시지 인증 코드(MAC)

java.security.MessageDigest
암호화 해시함수

javax.crypto.SecretKeyFactory
비밀키의 형식 변환

java.security.SecureRandom
난수생성

java.security.Signature
전자서명

표) JDK와 JCE에 포함된 암호화 클래스

개념클래스
Sun이 지원하는 암호화 알고리즘
SunJCE가 지원하는 암호화 알고리즘

Cipher

DES, Desede, PBEWithMD5AndDES

KeyAgreement

DH

KeyFactory
DSA


KeyGenerator

DES,DESede

KeyPairGenerator Mac
DSA


Mac

HmacMD5, HmacSHA1

MessageDigest
MD5, SHA-1


SecretKeyFactory

DES, Desede, PBEWithMD5AndDES

Signature
DSA

표) 표준 알고리즘 이름

Chapter 3 난수

Chapter 4 키관리

■ Key 인터페이스

1. java.security.Key 인터페이스( 암호화 키를 캡슐화 )

- public String getAlgorithm() : 키가 사용된 암호 알고리즘 이름을 리턴

- public byte[] getEncoded() : 키의 암호화 값을 구할 수 있다.

- public String getFormat() : 암호화 하는데 사용된 키 포맷의 이름을 리턴한다.

- 자식 인터페이스 : java.security.PublicKey, java.security.PrivateKey,

javax.crypto.SecretKey(JCE)

2 java.security.KeyPair 클래스( 공개키와 개인키 )

- publicKeyPair(PublicKey publicKey, PrivateKey, privateKey) : 주어진 공개키와 개인키로 KeyPair를 생성한다.

- public PublicKey getPublic() : 공개키를 리턴한다.

- public PrivateKey getPrivate() : 개인키를 리턴한다.

■ 키 생성기

1. java.security.KeyPairGenerator( 비대칭 방식 JDK에 포함 )

- public KeyPair generateKeyPair () : 열쇠 페어를 생성합니다.

- public final KeyPair genKeyPair () : 열쇠 페어를 생성합니다.

- public String getAlgorithm () : 이 열쇠 페어 제네레이터의 알고리즘의 표준명을 돌려줍니다.

- public static KeyPairGenerator getInstance (String algorithm) : 지정된 다이제스트 알고리즘을 구현하는 KeyPairGenerator 오브젝트를 작성합니다.

- public static KeyPairGenerator getInstance (String algorithm, String provider) : 지정된 프로바이더로부터 지정된 알고리즘이 사용 가능한 경우에, 그 프로바이더가 제공한 알고리즘을 구현하는 KeyPairGenerator 오브젝트를 작성합니다.

- public final Provider getProvider () : 이 열쇠 페어 제네레이터 오브젝트의 프로바이더를 돌려줍니다.

- pubic void initialize (AlgorithmParameterSpec params) : 제공된 파라미터를 사용하여 KeyPairGenerator를 초기화 한다.

- public void initialize (AlgorithmParameterSpec params, SecureRandom random) : 제공된 파라미터를 사용하여 KeyPairGenerator를 초기화 한다.

- public void initialize (int keysize) : 랜덤 비트의 소스 역할을 하는 새로운 SecureRandom을 생성하는 것을 제외하고 임의의 키 사이즈에 대하여 열쇠 페어 제네리이터를 초기화합니다.

- pubic void initialize (int keysize, SecureRandom random) : 제공된 랜덤 비트 소스를 사용하여 임의의 키 사이즈 대하는 열쇠 페어 제네레이터를 초기화합니다.

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");

kpg.initialize(1024);

KeyPair pair = kpg.getKeyPair();


2. javax.crypto.KeyGenerator( 대칭 방식 JCE에 포함 )

- public final SecretKey generateKey() : 새로운 랜덤 SecretKey를 생성한다.

- public String getAlgorithm() : KeyGenerator 객체에 사용된 알고리즘의 이름을 리턴합니다.

- public static KeyGenerator getInstance(.String algorithm) : 주어진 알고리즘으로 인스턴스 생성

- pubic static KeyGenerator getInstance(String algorithm, String provider) : 주어진 알고리즘과 프로바이터로 인스턴스 생성

- pubic Provider getProvider() : 사용된 프로바이터 리턴

- public void init(AlgorithmParameterSpec params) : 제공된 파라미터를 사용하여 초기화 한다.

- public void init(AlgorithmParameterSpec params, SecureRandom random) : 제공된 파라미터를 사용하여 초기화 한다.

- public void init(int keysize) : 주어진 크기로 키를 생성하기 위하여 초기화한다.

- public void init(int keysize, SecureRandom random) : 주어진 키와 랜덤소스로 초기화 한다.

- public void init(java.security.SecureRandom random) : 주어진 랜덤소스로 초기화 한다.

KeyGenerator kg = KeyGenerator.getInstance("DES");

kg.init(new SecureRandom());

SecretKey key = kg.generateKey()


■ 키 해석기

키를 저장하는 방법중 하나는 키를 직렬화 하여 저장하는것과 단순히 바이트의 배열과 같이 키를 저장하거나 전송하는 방법이 있다. 키 객체를 바이트로 또는 역으로 변환하는 방법이 다음의 클래스에 정의 되어있다.

1. javax.crypto.spec.SecretKeySpec( 바이트 배열을 비밀키로 변환하는 가장 간단한 방법 )

- SecretKeySpec(byte[] key, int offset, int len, String algorithm) : offset과 제공된 바이트의 배열의 len 바이트를 사용하여 SecretKeySpec을 생성한다. 키는 제공된 알고리즘을 따른다.

- SecretKeySpec(byte[] key, String algorithm) : 제공된 바이트 배열을 사용하여 SecretKeySpec을 생성한다. 키는 제공된 알고리즘을 따른다.

SecureRandom sr = new SecureRandom();

byte[] keyBytes = new byte[20];

sr.nextBytes(keyBytes);

SecretKey key = new SecretKeySpec(keyBytes, "HmacSHA1");


2. javax.crypto.SecretKeyFactory

- public static final SecretKeyFactory getInstance(String algorithm) : 주어진 알고리즘에 대하여 새로운 SecretKeyFactory를 생성한다 알고리즘은 “DES"와 같은 대칭 암호 알고리즘이다.

- pubic static final SecretKeyFactory getInstance(String algorithm, String provider) : 주어진 프로바이더로 SecretKeyFActory를 생성한다.

- public final SecretKey generateSecret(KeySpec keySpec) : KeySpec를 SecretKey로 변환하기 위하여 사용된다.

public SecertKey makeDESKey(byte[] input, int offset)

throws NoSuchAlgorithmException, InvalidkeyException, InvalidkeySpecException{

SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");

KeySpec spec = new DESKeySpec(input, offset);

return desFactory.generateSecret(spec);

}


- public final KeySpec getKeySpec(SecretKey key, java.lang.Class keySpec) : 주어진 SecretKey로부터 KeySpec을 생성한다.

public byte[] makeBytesFromDESKey (SecretKey key)

throw NoSuchAlgorithmException, InvaildKeySpecException {

SecretKeyFactory desFactory = SecretKeyFactory.getInstance("DES");

DESKeySpec spec =

(DESKeySpec)desFactory.getKeySpec(Key, DESKeySpec.class);

return spec.getKey();

}


3. java.security.KeyFactory

- public static final KeyFactory getInstance (String algorithm) : 지정된 다이제스트 알고리즘을 구현하는 KeyFactory 오브젝트를 작성합니다. 알고리즘 이름은 비대칭 암호 알고리즘 이름이거나 “DSA"와 같은 서명 알고리즘 이어야 합니다.

- public static final KeyFactory getInstance (String algorithm, String provider) : 지정된 프로바이더로부터, 지정된 알고리즘의 KeyFactory 오브젝트를 작성합니다.

- public final PrivateKey generatePrivate (KeySpec keySpec) : 지정된 열쇠 사양 (열쇠 데이터)으로부터 개인키를 생성하는데 사용

- public final PublicKey generatePublic (KeySpec keySpec) : 지정된 열쇠 사양 (열쇠 데이터)으로부터 공개키를 생성하는데 사용

- public final KeySpec getKeySpec (Key key, Class keySpec) : 주어진 키로부터 키 스펙을 생성한다.

■ 키 교환 프로토콜

1. javax.crypto.KeyAgreement

- public static final KeyAgreement getInstance(String algorithm) : 주어진 알고리즘을 사용하여 새로운 KeyAgreement를 생성한다. 이름은 “DH"와 같은 키교환 알고리즘이어야 한다.

- public static final KeyAgreement getInstance(String algorithm, String provider) : 주어진 알고리즘과 프로바이더로 새로운 KeyAgreement를 생성한다.

- public final void init(Key key) : 제공된 키를 사용하는 KeyAgreement를 초기화 한다.

- public final void init(Key key, AlgorithmParameterSpec params) : 주어진 키와 알고리즘 지정 파라미터를 사용하여 KeyAgreement를 초기화 한다.

- public final void init(.Key key, AlgorithmParameterSpec params, SecureRandom random) : 주어진 키와 알고리즘 지정 파라미터 그리고 랜덤 소스를 사용해서 KeyAgreement를 초기화 한다.

- public final void init(Key key, SecureRandom random)

- public final Key doPhase(Key key, boolean lastPhase)

- public final byte[] generateSecret()

- public final int generateSecret(byte[] sharedSecret, int offset)

- public final SecretKey generateSecret(java.lang.String algorithm)

- public final String getAlgorithm()

- public final Provider getProvider()

// --< Skip Server >

package test.crypto.part5;

import java.security.*;

import java.net.*;

import java.io.*;

import java.security.spec.*;

import javax.crypto.*;

import sun.misc.*;

public class SkipServer {

public SkipServer() {

}

public void exec(int port) throws Exception {

//Diffie-Hellman 키 쌍 생성

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");

kpg.initialize(Skip.sDHParameterSpec);

KeyPair keypair = kpg.genKeyPair();

// 연결을 기다린다.

ServerSocket ss = new ServerSocket(port);

System.out.println("요청을 기다리고 있습니다.... port : "+port);

Socket s = ss.accept();

DataOutputStream out = new DataOutputStream(s.getOutputStream());

DataInputStream in = new DataInputStream(s.getInputStream());

/**

* 첫번째 클라이언트는 서버에 바이트 배열의 코드화된

* Difie-Hellman공개키를 보낸다.

* KeyFactory가 그 키를 재구성하기 위해 사용된다.

*/

// 공개키를 받는다.

byte[] keyBytes = new byte[in.readInt()];

in.readFully(keyBytes);

KeyFactory kf = KeyFactory.getInstance("DH");

X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(keyBytes);

PublicKey theirPublicKey = kf.generatePublic(x509Spec);

// 우리의 키를 클라이언트에게 보낸다.

keyBytes = keypair.getPublic().getEncoded();

out.writeInt(keyBytes.length);

out.write(keyBytes);

/**

* 이제 개인키와 클라이언트의 공개키를 사용해서 보안값을 계산할수 있다.

* 그 보안 값은 Diffie-Hellman 키를 생성

* 하기 위해 사용된 계수만큼 길다. 이 경우 보안값은

* 1024비트 길이를 가진다.

*/

KeyAgreement ka = KeyAgreement.getInstance("DH");

ka.init(keypair.getPrivate());

ka.doPhase(theirPublicKey,true);

byte[] secret = ka.generateSecret();

out.close();

in.close();

BASE64Encoder encoder = new BASE64Encoder();

System.out.println(encoder.encode(secret));

}

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

if(args.length < 1) {

System.out.println("포트 번호를 입력해주셔야 합니다...");

System.exit(0);

}

SkipServer skipServer = new SkipServer();

skipServer.exec(Integer.parseInt(args[0]));

}

}


//--- < Skip Client >

package test.crypto.part5;

import java.security.*;

import java.net.*;

import java.io.*;

import java.security.spec.*;

import javax.crypto.*;

import sun.misc.*;

public class SkipClient {

public SkipClient() {

}

public void exec(String ip, int port) throws Exception {

//Diffie-Hellman 키 쌍 생성

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");

kpg.initialize(Skip.sDHParameterSpec);

KeyPair keypair = kpg.genKeyPair();

// 네트워크 연결

Socket s = new Socket(ip, port);

DataOutputStream out = new DataOutputStream(s.getOutputStream());

DataInputStream in = new DataInputStream(s.getInputStream());

// 공개키 전송

byte[] keyBytes = keypair.getPublic().getEncoded();

out.writeInt(keyBytes.length);

out.write(keyBytes);

// 공개키 수신

keyBytes = new byte[in.readInt()];

in.readFully(keyBytes);

KeyFactory kf = KeyFactory.getInstance("DH");

X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(keyBytes);

PublicKey theirPublicKey = kf.generatePublic(x509Spec);

/**

* 이제 개인키와 클라이언트의 공개키를 사용해서 보안값을 계산할수 있다. 그 보안 값은 Diffie-Hellman 키를 생성

* 하기 위해 사용된 계수만큼 길다. 이 경우 보안값은 1024비트 길이를 가진다.

*/

KeyAgreement ka = KeyAgreement.getInstance("DH");

ka.init(keypair.getPrivate());

ka.doPhase(theirPublicKey,true);

byte[] secret = ka.generateSecret();

out.close();

in.close();

BASE64Encoder encoder = new BASE64Encoder();

System.out.println(encoder.encode(secret));

}

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

if(args.length < 2) {

System.out.println("서버 아이피와 포트 번호를 입력해주셔야 합니다...");

System.exit(0);

}

SkipClient skipClient = new SkipClient();

skipClient.exec(args[0], Integer.parseInt(args[1]));

}

}

■ KeyStore 클래스의 키 관리 패러다임

1. 인스턴스 생성

- public static final KeyStore getInstance (String type) : 지정된 타입의 키 스토어 오브젝트를 작성합니다. KeyStore ks = KeyStore.getInstance("JKS");

- public static final KeyStore getInstance (String type, String provider) : 지정된 프로바이더로부터, 지정된 키 스토어 타입의 키 스토어 오브젝트를 작성합니다. KeyStore ks = KeyStore.getInstance("JKS", "SUN");

2. 로딩과 저장

- public final void load (InputStream stream, char[] password) : 지정된 입력 Stream로부터 이 키 스토어를 로드합니다.

- public final void store (OutputStream stream, char[] password) : 지정된 출력 Stream에 이 키 스토어를 격납 해, 지정된 패스워드로 그 완전성을 보호합니다

향후 내용 추가 요망....

Chapter 5 인증

인증에 유요한 세가지 암호화 개념

- 메시지 축약(message digest)은 대용량 데이터 집합을 나타내는 식별자를 생성한다.

- 전자 서명(digital signature)은 데이터의 무결성을 증명하는데 사용한다.

- 인증서(certificate)는 암호적으로 공개키의 안전한 컨테이너로 사용된다.

■ 변경된 메시지 축약

package test.crypto.part6;

import java.security.*;

import java.io.*;

import sun.misc.*;

public class MessageDigestTester {

public MessageDigestTester() {

}

private void exec(String targetFileName) {

try {

// MD5알고리즘을 이용한 메시지 축약 객체를 생성한다.

MessageDigest md = MessageDigest.getInstance("MD5");

// 주어진 파일에 대한 축약 값 계산

DigestInputStream in = new DigestInputStream(new FileInputStream(targetFileName), md);

byte[] buffer = new byte[8192];

while ( in.read(buffer) != -1 ) {

}

byte[] raw = md.digest();

// 출력 가능한 문자열로 변환한다.

BASE64Encoder encoder = new BASE64Encoder();

String base64 = encoder.encode(raw);

System.out.println(base64);

} catch(NoSuchAlgorithmException nalgoe) {

System.err.println(nalgoe);

} catch(FileNotFoundException fnote) {

System.err.println(fnote);

} catch(IOException ioe) {

System.err.println(ioe);

}

}

public static void main(String[] args) {

if(args.length < 1) {

System.out.println("메시지 축약의 대상 파일을 선택하여 주십시요");

System.exit(0);

}

String targetFileName = args[0];

MessageDigestTester masher = new MessageDigestTester();

masher.exec(targetFileName);

}

}


■ 암호화된 패스워드 로그인

클라이언트에서 서버로 평문을 전송하는 것을 피하기 위해서, 클라이언트는 평문 대신에 패스워드 메시지를 축약하여 보내게 되며, 서버는 보유하고 있는 패스워드 사본의 메시지 축약을 비교하여 두 개의 메시지 축약 내용이 같을 경우에 클라이 언트를 인증하게 된다.

//--- < masher Server >

package test.crypto.part6;

import java.util.*;

import java.net.*;

import java.io.*;

import java.security.*;

public class MasherServer {

public MasherServer() {

}

public void exec(int port) throws Exception {

ServerSocket ss = new ServerSocket(port);

System.out.println("요청을 기다리고 있습니다.... port : "+port);

Socket s = ss.accept();

DataInputStream in = new DataInputStream(s.getInputStream());

// 클라이언트가 보낸 순서로받는다.

String user = in.readUTF();

long time = in.readLong();

double randomQ = in.readDouble();

int leng = in.readInt();

byte[] masherBytesIn = new byte[leng];

in.readFully(masherBytesIn);

byte[] masherBytesOut = userMasher.makeDigest(user, getPassword(), time, randomQ);

if(isUser(masherBytesIn, masherBytesOut)) {

System.out.println("Login");

} else {

System.out.println("No password");

}

in.close();

}

private String getPassword() {

return "rlarudwls";

}

private boolean isUser(byte[] inBytes, byte[] outBytes){

return MessageDigest.isEqual(inBytes, outBytes);

}

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

if(args.length < 1) {

System.out.print("포트를 입력하여 주십시요....");

System.exit(0);

}

MasherServer ms = new MasherServer();

ms.exec(Integer.parseInt(args[0]));

}

}

//---< masherClient >

package test.crypto.part6;

import java.util.*;

import java.net.*;

import java.io.*;

public class MasherClient {

public MasherClient() {

}

public void exec(String user, String password, String host, int port) throws Exception {

Date date = new Date();

long time = date.getTime();

double randomQ = Math.random();

byte[] masherBytes = userMasher.makeDigest(user, password, time, randomQ);

Socket s = new Socket(host, port);

DataOutputStream out = new DataOutputStream(s.getOutputStream());

out.writeUTF(user);

out.writeLong(time);

out.writeDouble(randomQ);

out.writeInt(masherBytes.length);

out.write(masherBytes);

out.flush();

out.close();

}

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

if(args.length < 2) {

System.out.print("서버 주소와 포트를 입력하여 주십시요....");

System.exit(0);

}

String user = "inter999";

String password = "rlarudwls";

MasherClient mc = new MasherClient();

mc.exec(user, password, args[0], Integer.parseInt(args[1]));

}

}

package test.crypto.part6;

import java.io.*;

import java.security.*;

public class userMasher {

public static byte[] makeDigest(String user, String password, long time, double randomQ)

throws NoSuchAlgorithmException {

MessageDigest md = MessageDigest.getInstance("SHA");

md.update(user.getBytes());

md.update(password.getBytes());

md.update(makeBytes(time, randomQ));

return md.digest();

}

public static byte[] makeBytes(long time, double randomQ) {

try {

ByteArrayOutputStream byteout = new ByteArrayOutputStream();

DataOutputStream dataout = new DataOutputStream(byteout);

dataout.writeLong(time);

dataout.writeDouble(randomQ);

return byteout.toByteArray();

} catch (IOException ioe) {

return new byte[0];

}

}

}

■ 이중 암호화 패스워드 로그인

메시지 축약을 사용하여 패스워드 정보를 보호하는 강력한 방법으로 이중 암호화 기법이 있는데, 이의 구성은 “암호화 패스워드 로그인”에 추가적으로 타임스템프와 난수를 포함한다. 즉 두 번째 축약에서 처음 축약메시지와 타임스템프, 난수를 이용하여 축약한다.

■ MAC

이 클래스는 메시지 인증 코드(MAC)에 대한 API를 정의한다. MAC은 비밀키를 공유하는 두 집단 사이에서 전송되는 정보의 무결성을 검사할 수 있다. MAC은 공개키/개인키가 아니라 비밀키와 함께 생성된다는 점을 제외하면 디지털 서명과 비슷하다. MAC 클래스는 알고리즘과 무관하며 제공자-기반이다. 정적 getInstance() 팩토리 메소드 중 하나를 호출하여 희망하는 MAC 알고리즘의 이름을 지정하여 MAC 객체를 얻는다.

“SunJCE"제공자는 ”HmacMD5", "HmacSHA1"이라는 두 개의 알고리즘을 구현한다.

1. Mac 객체를 얻은 후에는 init() 메소드를 호출하여 SecretKey를 지정하여 이 Mac 객체를 초기화 한다.

2. Mac 객체를 얻고 초기화 한 후에는, Mac이 계산될 데이터를 지정한다. 단순히 단일 바이트 배열을 처리 할때는 doFinal()에 전달하고, 스트리밍이나 다양한 위치에 저장된다면 update()를 여러번 호출하여 처리한다.

SecureRandom sr = new SecureRandom();

byte[] keyBytes = new byte[20];

sr.nextBytes(keyBytes);

SecretKey key = new SecretKeySpec(keyBytes, "HmacSHA1");

Mac m = Mac.getInstance("HmacSHA1");

m.init(key);

m.update(inputData);

byte[] mac = m.doFinal();


■ 서명(java.security.Signature)

서명은 두 가지 보안 서비스(인증과 무결성) 즉, 메시지가 변조되어 오지 않는 것과 메시지가 어떤 사람으로부터 보내졌는지를 보장해준다. 서명은 서명한 사람의 개인키를 가지고 암호화한 메시지 축약이다. 서명한 사람의 공개키만이 서명을 복호화 할 수 있으며, 이것이 인증을 제공한다. 메시지 축약이 서명으로부터 복호화한 메시지 축약과 같다면, 무결성 역시 보장되는 것이다.

1. Signature 객체는 정적 팩토리 메소드인 getInstance()중의 하나를 원하는 전자 서명 알고리즘과 선택적으로 알고리즘의 제공자를 지정하면서 호출하여 얻을 수있다.

2. 전자 서명은 본질적으로 공개키 암호화 알고리즘으로 암호화된 메시지 축약이다. 따라서 전자 서명 알고리즘을 지정하려면, 축약 알고리즘과, 암호화 알고리즘을 모두 지정해야한다.

3. 기본 “SUN"제공자에서 지원되는 유일한 알고리즘은 ”SHA1WwithDSA"이다.

4. 전자 서명의 생성을 위한 초기화를 하려면 initSign()을 호출하고 서명 생성을 위한 개인키를 지정해야한다.

5. 서명의 검증을 위한 초기화를 하려면 initVerify()를 호출하고 사인자(signer)의 공개키를 지정해야 한다.

6. Signature 객체가 초기화 되었으면 update()를 한번 이상 호출하여 사인되거나 검증될 바이트를 지정한다.

7. 마지막으로 전자 서명을 생성하기 위해 sign()을 호출하면서 사인이 저장될 바이트 배열을 넘겨준다.


// 핼퍼클래스

package acdpu.pki;

import java.io.Serializable;

import java.security.PrivateKey;

import java.security.PublicKey;

public class PKIHelper implements Serializable {

private String userId;

private String passwd;

private String createDate;

private String destroyDate;

private PrivateKey privatekey;

private PublicKey publickey;

public String getUserId() {

return userId;

}

public void setUserId(String newUserId) {

userId = newUserId;

}

public String getPasswd() {

return passwd;

}

public void setPasswd(String newPasswd) {

passwd = newPasswd;

}

public String getCreateDate() {

return createDate;

}

public void setCreateDate(String newCreateDate) {

createDate = newCreateDate;

}

public String getDestroyDate() {

return destroyDate;

}

public void setDestroyDate(String newDestroyDate) {

destroyDate = newDestroyDate;

}

public PrivateKey getPrivatekey() {

return privatekey;

}

public void setPrivatekey(PrivateKey newPrivatekey) {

privatekey = newPrivatekey;

}

public PublicKey getPublickey() {

return publickey;

}

public void setPublickey(PublicKey newPublickey) {

publickey = newPublickey;

}

}

// 컨트롤러

package acdpu.pki;

import java.security.*;

import acdpu.pki.exception.*;

public class PKIController {

public PKIController() {

}

public PrivateKey createKeyPair(String userid, String passwd)

throws PKICreateException, IncorrectUserException, TermExpirationException, PKIDBHandlerException {

try{

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA", "SUN");

kpg.initialize(1024,SecureRandom.getInstance("SHA1PRNG"));

KeyPair keypair = kpg.genKeyPair();

PKIDBHandler.userConfirm(userid, passwd);

PKIHelper pkihelper = new PKIHelper();

pkihelper.setUserId(userid);

pkihelper.setPasswd(passwd);

pkihelper.setPrivatekey(keypair.getPrivate());

pkihelper.setPublickey(keypair.getPublic());

PKIDBHandler.saveKeyPair(pkihelper);

return pkihelper.getPrivatekey();

} catch (NoSuchProviderException nope) {

throw new PKICreateException("NoSuchProvider");

} catch (NoSuchAlgorithmException noae) {

throw new PKICreateException("NoSuchAlgorithm");

}

}

public void loginPKI(String userid, String passwd, byte[] signature)

throws PKIInvalidException, IncorrectUserException, TermExpirationException, PKIDBHandlerException {

PKIDBHandler.userConfirm(userid, passwd);

PKIDBHandler.verify(userid, passwd, signature);

}

public static void main(String[] args) {

PKIController pKIController = new PKIController();

}

}

// 데이터 모델

package acdpu.pki;

import java.sql.*;

import java.io.*;

import acdpu.pki.exception.*;

import java.security.*;

import java.security.spec.*;

public class PKIDBHandler {

public static boolean saveKeyPair(PKIHelper pkihelper)

throws PKIDBHandlerException {

Connection con = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try {

Class.forName("oracle.jdbc.driver.OracleDriver");

con = DriverManager.getConnection("jdbc:oracle:thin:@ 218.145.231.3:1522:ora8", "itdev", "itdev");

con.setAutoCommit(false);

StringBuffer sbSQL = new StringBuffer();

sbSQL.append("update TB_PKI set privatekey = ?, publickey = ?, indate=sysdate where userid='"+pkihelper.getUserId()+"'");

pstmt = con.prepareStatement(sbSQL.toString());

ByteArrayInputStream privateKeywriter = new ByteArrayInputStream(pkihelper.getPrivatekey().getEncoded());

ByteArrayInputStream publicKeywriter = new ByteArrayInputStream(pkihelper.getPublickey().getEncoded());

pstmt.setBinaryStream(1,privateKeywriter,privateKeywriter.available());

pstmt.setBinaryStream(2,publicKeywriter,publicKeywriter.available());

pstmt.executeUpdate();

privateKeywriter.close();

publicKeywriter.close();

con.commit();

return true;

} catch(ClassNotFoundException cnote) {

throw new PKIDBHandlerException("PKIDBHandler.saveKeyPair Method Error : Message = "+cnote.getMessage());

} catch(IOException io) {

throw new PKIDBHandlerException("PKIDBHandler.saveKeyPair Method Error : Message = "+io.getMessage());

} catch(SQLException e) {

try{

con.rollback();

con.setAutoCommit(true);

}catch(Exception er){}

throw new PKIDBHandlerException("PKIDBHandler.saveKeyPair Method Error : Message = "+e.getMessage());

} finally {

try {

con.setAutoCommit(true);

if(rs !=null ) {

rs.close();

rs=null;

}

if(pstmt !=null ) {

pstmt.close();

pstmt = null;

}

if(con!=null && !con.isClosed()) {

con.close();

con =null;

} else {

con=null;

}

} catch(Exception e) {

rs = null;

pstmt = null;

con = null;

}

}

}

public static void verify(String userid, String passwd, byte[] signature)

throws PKIInvalidException, PKIDBHandlerException {

Connection con = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

try {

Class.forName("oracle.jdbc.driver.OracleDriver");

con = DriverManager.getConnection("jdbc:oracle:thin:@ 218.145.231.3:1522:ora8", "itdev", "itdev");

StringBuffer sbSQL = new StringBuffer();

sbSQL.append("select publickey from TB_PKI where userid ='"+userid+"'");

pstmt = con.prepareStatement(sbSQL.toString());

rs = pstmt.executeQuery();

&

Posted by 1010
90.개발관련문서2008. 11. 19. 14:09
반응형

java.lang.OutOfMemoryError

 

                     2005-05-31     학렬    ㈜아이티플러스 기술지원부

 

 

이 문서는 기술지원 또는 개발 시 java.lang.OutOfMemoryError 를 만났을 때 원인 파악 및 해결방안 입니다.

 

 

java.lang.OutOfMemoryError 에는 크게 2가지 패턴이 있다고 볼 수 있습니다.(전적으로 개인적인 생각이지만..^^)

Java heap 메모리가 정말로 Full 되서 나는 종류가 있고 그렇지 않은데도 나는 종류가 있습니다.

그 둘 중에 어는 것 인지부터 가려내는 것이 가장 먼저 선행되어야 합니다.

Java 가상머신에는 메모리 구조가 여러단계로 나뉘어 져 있으므로 어느 영역에 의해 java.lang.OutOfMemoryError 가 나는지 알기 위해 JAVA OPTION으로 싸이트가 안정화 되기 전까진 verbosegc 또는 -XX:+PrintGCDetails  옵션을 추가해 놓는 것이 java.lang.OutOfMemoryError 났을 때를 대비해 좋은 습관이라 할 수 있습니다.

 

-verbosegc 또는  -XX:+PrintGCDetails  옵션으로 로그에 남는 heap 메모리 정보를 본 후 java.lang.OutOfMemoryError 가 날 때 heap이 꽉 차서 나는 것인지 아닌지 부터 판단합니다.

 

1.     Heap Memory Full 차지 않았을 때

1)     Perm 영역이 full 되는 경우

 

Permanent generation is full...

increase MaxPermSize (current capacity is set to: 134217728 bytes)

 

[Full GC[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor31282]

 810207K->802132K(1013632K), 8.3480617 secs]

<GC: 2 4  2465625.831280 10348 0 31 113802808 105534632 286326784 0 0 35782656 715849728 715848840 715849728 134217720 134023296 134217728 8.348677 8.348677 >

Passwd Check =============

<2005. 5. 19. 오전 9 32 23 KST> <Error> <HTTP> <BEA-101017> <[ServletContext(id=2536415,name=/,context-path=)] Root cause of ServletException.

java.lang.OutOfMemoryError

위와 같은 case 인 경우네는 Java 가상머신중에 Perm 영역이 full 차는 경우 입니다. 

Perm 영역에는 class object 및 관련된 meta data가 로드되는 곳인데 싸이트가 매우 많은 수의 class를 사용하는 경우 늘려줘야 하는 case도 있습니다.

얼마가 적정한 사이즈란 정답이 없는 것 같고 max가 계속 늘어나지 않고 일정한 사이즈를 유지 하면 됩니다.

 

             위 에러가 났을때는 -XX:MaxPermSize=256m  옵션으로 사이즈를 적당하게 늘려주는게 방

             법이며 늘려주었는데도 불구하고 Full 차는 시간만 늘어날 뿐 계속 사이즈가 늘어난다면 이 영역은 일반 비즈니스 프로그램으로 핸들링 할 수 없는 영역이므로 WAS 제품의 버그 및 jdk 버그로 보는 것이 일반적입니다.

       

2)     MAXDSIZ 사이즈 관련

  - Exception in thread "CompileThread0" java.lang.OutOfMemoryError: requested 32756 bytes for ChunkPool::allocate

Possible causes:

         - not enough swap space left, or

         - kernel parameter MAXDSIZ is very small.

-          java.lang.OutOfMemoryError: unable to create new native thread

 

위 두 에러가 나는 이유는 Data 사이즈가 Full 차서 더 이상 메모리 할당을 할 수 없다는 java.lang.OutOfMemoryError 입니다.

 

Jdk도 내부적으로 c 라이브러리를 쓰고 jni를 통해서 c프로그램을 호출할 수 도 있는 환경에서 Data 영역이상으로 메모리 사용 시 위 에러를 만날 수 있습니다.

Heap 영역에는 java heap C heap이 있는데 C heap Data 메모리 영역에 영향을 미치는 것으로 보이며 보통 C의 전역 변수들이 잡히는 영역입니다.

 

위 현상을 만났을 때는 hp os MAXDSIZ가 너무 작게 잡혀있지 않은지 확인 후 적당한 크기로 늘려 줘야 합니다.

 

Glance 에서 shift+m 을 누른 후 jvm pid를 누르면 java가 사용하는 Data 사이즈를 모니터링 할 수 있습니다.

모니터링을 통해 적정한 사이즈로 MAXDSIZ를 늘려주어야 하며 만일 늘려 준게 에러 발생의 시간만 지연 시킬 뿐 계속 사용량이 늘어난다면 이는 사용하는 c라이브러리 쪽에 메모리 릭 버그가 있는 것이므로 c라이브러리를 체크 하셔야 합니다.

java.lang.OutOfMemoryError: unable to create new native thread

이 경우는 프로그램에서 Thread pool 프로그램 실수로 필요이상으로 쓰레드가 생성되는 경우도 과도하게 메모리를 사용할 수 있으므로 jvm 쓰레드 덤프를 통해 과도한 쓰레드가 생성되지 않았는지도 확인해 보셔야 합니다.

 

2.     Heap Full 찾을 때

이 경우는 java가 사용하는 heap 영역이 Full 되서 java.lang.OutOfMemoryError 가 나는 경우 인데 두 가지 패턴이 있습니다.

순간적으로 대량의 데이터를 메모리에 올리는 프로그램이 실행되어 문제를 야기 할수 있으며 다른 한 가지는 조금씩 메모리 릭이 발생하여 점차적으로 메모리가 쌓여 가는 경우 입니다.

두 가지 중에  어느 것인지 구별하는 것이 중요하며 이를 위해서도 마찬가지로 -verbosegc 또는  -XX:+PrintGCDetails  로그를 통해 순간적으로 메모리가 차는 것인지 조금씩 메모리가 차는 것인지를 확인하셔야 합니다.

 

1) 특정 프로그램의 특정시점의 과도한 메모리 사용에 의한 경우

                특정 프로그램이 과도하게 heap 메모리 이상 메모리를 사용하면서

java.lang.OutOfMemoryError가 발생하는 경우는 이 에러가 발생하는 시점의 쓰레드 덤프를 통해 어느 프로그램인지 쉽게 찾을 수 있습니다.

쓰레드 덤프에 메모리를 쓸만한 프로그램은 어느 정도의 자바프로그램 경험이 있으면 찾을 수 있습니다.

 

Ex)

"ExecuteThread: '36' for queue: 'default'" daemon prio=10 tid=0x0048e7b0 nid=48 lwp_id=4139729 runnable [0x23f32000..0x23f30500]

          at java.net.SocketInputStream.socketRead(Native Method)

          at java.net.SocketInputStream.read(Unknown Source)

          at oracle.net.ns.Packet.receive(Unknown Source)

          at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.net.ns.NetInputStream.read(Unknown Source)

          at oracle.jdbc.ttc7.MAREngine.unmarshalUB1(MAREngine.java:718)

          at oracle.jdbc.ttc7.MAREngine.unmarshalSB1(MAREngine.java:690)

          at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:373)

          at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1405)

          at oracle.jdbc.ttc7.TTC7Protocol.fetch(TTC7Protocol.java:889)

          - locked <0x35e8e3b0> (a oracle.jdbc.ttc7.TTC7Protocol)

          at oracle.jdbc.driver.OracleResultSetImpl.next(OracleResultSetImpl.java:242)

          - locked <0x36f66c98> (a oracle.jdbc.driver.OracleResultSetImpl)

          at weblogic.jdbc.pool.ResultSet.next(ResultSet.java:180)

          at Dcard.AAA.ejb.monitor.member.wbbb.WACBean.getInfoList(WACBean.java:5789)

 

java.lang.OutOfMemoryError 가 날 상황에 쓰레드 덤프를 두 세번 떠서 같은 쓰레드 번호로 위 같은 로직이 오래 결려있다면 이는 프로그램에서 while(rs.next()) 를 오랜 기간 돌면서 메모리에 DB로부터 읽어서 올리고 있다는 것을 의미 합니다 대량 데이터 조회가 일어나는 경우인 것 입니다.

 

이런 식으로 특정 프로그램의 특정 시점에 과도한 메모리 사용으로 인한 java.lang.OutOfMemoryError 에러는 쓰레드 덤프를 통해 찾을 수 있습니다.

-- 물론 2번에서 설명 할 heap dump를 통해서도 찾을 수 있습니다.

 

2) 메모리 릭에 의해 조금씩 메모리가 쌓인 경우

JVM위 에서 실행중인 프로그램중에 어떤 것이 GC 대상에서 제외되는 영역에 data를 조금씩 쌓고 있다는 얘기입니다.

GC 대상에서 제외되는 영역은 다음과 같은 곳이 있습니다.

- Http Session에 넣는 데이터..(세션 타임아웃 또는 invilidate 씨 까지 제외됨)

- Static 변수

- 서블릿 또는 jsp의 멤버변수 ( WAS 기동 후 최초 호출 시 인스턴스 화 되어 WAS가 내려 갈 때 까지 사라지지 않음 )

- EJB의 멤버변수( pool안에서 객체가 존재하는 한 GC대상에서 제외)

          위 같은 영역에 프로그램에서 data add 하는 구조를 메모리 릭 이라고 할 수 있습니다.

           IBM 또는 SUN JDK 인 경우에는 heapdump를 통해서 분석하여 어느 데이터가 메모리를 많이 잡고 있는지를 알 수 있습니다.

           Heapdump 사용법 및 분석 법은 다음을 참조 하시면 됩니다.

 http://www.alphaworks.ibm.com/aw.nsf/FAQs/heaproots

http://www-1.ibm.com/support/docview.wss?uid=swg21190476

http://www-1.ibm.com/support/docview.wss?rs=180&context=SSEQTP&q1=heapdump+solaris&uid=swg21190608&loc=en_US&cs=utf-8&lang=en

http://www.skywayradio.com/tech/WAS51/IBMHeapDump/

Posted by 1010
98..Etc/Log4J2008. 11. 19. 14:07
반응형

JSP에서 원하는 Appender 선택하여 쓰기


참고로 이글의 원저자는 제가 아니므로 퍼가셔서 사용하실때 신중해주시기 바랍니다



만약 log4j 가 처음이라면 이 카테고리의 다음 포스트를 먼저 필독하세요


- log4j 웹에서 사용하기

- log4j 고급스럽게 사용하기

 

 

 

I. 먼저 log4j 프로퍼티 파일입니다

log4j.properties

log4j.rootLogger=INFO, stdout1, stdout2


log4j.logger.jsp1=INFO,stdout1
log4j.additivity.jsp1=false


log4j.logger.jsp2=INFO,stdout2
log4j.additivity.jsp2=false


log4j.appender.stdout1=org.apache.log4j.ConsoleAppender
log4j.appender.stdout1.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout1.layout.ConversionPattern=jsp1 appender log %d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


log4j.appender.stdout2=org.apache.log4j.ConsoleAppender
log4j.appender.stdout2.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout2.layout.ConversionPattern=jsp2 appender log %d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n


log4j.logger.jsp1=INFO, stdout1
log4j.logger.jsp2=INFO, stdout2
jsp1과 jsp2의 두개의 logger를 정의합니다

jsp1 logger는 appender로 stdout1을 사용하며, jsp2 logger는 appender로 stdout2로 사용한다는 의미입니다


log4j.additivity.jsp1=false

additivity 속성은 jsp1 logger를 상위 로거(root logger)의 속성을 삭송받지 않겠다는 의미입니다

만약 이 속성이 없으면 동일한 메세지가 여러번 로깅될 것입니다

이하 속성은

http://www.jakartaproject.com/article/jakarta/1110438405982 등의 사이트를 참고하세요


II. JSP 샘플 소스

test_jsp1_appender.jsp

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.Logger" %>

<%!
 static Logger logger1 = Logger.getLogger("jsp1");
%>

<%
logger1.warn("warn");
%>

로깅 메세지

jsp1 appender log2005-11-07 13:05:23,687 WARN  [http-8080-Processor5] jsp1 (test_jsp1_appender_jsp.java:48)     - warn


test_jsp2_appender.jsp

<%@ page contentType="text/html;charset=MS949"
 import="org.apache.log4j.Logger" %>

<%!
 static Logger logger2 = Logger.getLogger("jsp2");
%>

<%
logger2.warn("warn");
%>

로깅 메세지

jsp2 appender log2005-11-07 13:05:58,031 WARN  [http-8080-Processor4] jsp2 (test_jsp2_appender_jsp.java:48)     - warn

Posted by 1010
98..Etc/Log4J2008. 11. 19. 14:04
반응형

아래 글은 SKT 소액 결재 개발팀 손정호 님이 작성하신 글임을 알려 드립니다.

참고로 preparedStatement에서 적용한 예 입니다.

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

Log4j Summary

이번 WebChannel 개발시에 적용된 Log4j 환경을 바탕으로 작성한 간단한 summary입니다.

1. 다운로드

다운로드http://logging.apache.org/log4j/docs/download.html
매뉴얼http://logging.apache.org/log4j/docs/documentation.html
API spechttp://logging.apache.org/log4j/docs/api/index.html

2. 구조
Log4j는 크게 3가지 요소로 구성되어 있습니다.
① Logger : logging 메시지를 Appender에 전달합니다.
② Appender : 전달받은 logging 메시지를 원하는 곳으로 보내는 매개체의 역할을 합니다.
   아래 표는 Appender의 종류입니다. API에서 보고 이해가 된 선에서 적었습니다.
ConsoleAppender        로그 메시지를 콘솔에 출력합니다.
DailyRollingFileAppender        로그 메시지를 파일로 저장합니다.
DatePattern 옵션에 따라 원하는 기간마다 로그파일을 갱신합니다.
ExternallyRolledFileAppender        
FileAppender        직접적으로 사용되지 않고 DailyRollingFileAppender와 RollingFileAppender의 superclass로 사용되는듯 합니다.
JDBCAppender        로그 메시지를 DB에 저장합니다. 현재는 완벽하지 않으니 왠만하면 차기 버전에서 사용하라고 하는 것 같습니다.
JMSAppender        로그 메시지를 JMS Topic으로 보냅니다.
NTEventLogAppender        NT 이벤트 로그를 위한 Appender. 윈도우에서만 사용가능합니다.
NullAppender        내부적으로만 사용되는 Appender입니다.
RollingFileAppender        로그 메시지를 파일로 저장합니다. 설정된 size를 초과하면 로그파일이 갱신됩니다.
SMTPAppender        로그 메시지를 지정된 이메일로 발송합니다.
SocketAppender        로그 메시지를 socket을 이용해서 지정된 곳으로 보냅니다.
SocketHubAppender        위와 비슷하게 사용하는듯 합니다.
SyslogAppender        로그 메시지를 원격 syslog deamon으로 보냅니다.
TelnetAppender        로그 메시지를 telnet을 통해 보낸다는 것 같습니다. 원격 모니터링, 특히 servlet의 모니터링에 유용하다고 합니다.
WriterAppender        FileAppender처럼 주로 superclass로서 사용되는듯 합니다.
③ Layout : logging 메시지의 출력 형식을 지정합니다.
        - 아래에서 설명.

3. 로깅레벨
FATAL : 가장 크리티컬한 에러가 발생했을 때 사용합니다.
ERROR : 일반적인 에러가 발생했을 때 사용합니다.
WARN : 에러는 아니지만 주의가 필요할 때 사용합니다.
INFO : 일반적인 정보가 필요할 때 사용합니다.
DEBUG : 일반적인 정보를 상세히 나타낼 때 사용합니다.

로깅레벨의 우선순위는 FATAL이 가장 높고 DEBUG가 가장 낮습니다.
예를 들어 레벨을 WARN으로 설정하면 WARN이상되는 로그(FATAL, ERROR, WARN)만
출력합니다.

4. 환경설정
- Log4j의 환경설정은 직접 코드에서 메서드를 이용하는 방법과 properties 파일을 이용하는 방법, XML파일을 이용하는 방법이 있습니다.
① 코드에서 설정
String layout = "%d %-5p [%t] %-17c{2} (%13F:%L) %3x - %m%n";
String logfilename = "DailyLog.log";
String datePattern = ".yyyy-MM-dd ";

PatternLayout patternlayout = new PatternLayout(layout);
DailyRollingFileAppender appender = new DailyRollingFileAppender(patternlayout, logfilename, datePattern);
logger.addAppender(appender);
logger.setLevel(Level.INFO);
logger.fatal("fatal!!");

위 코드처럼 설정하시면 됩니다.


② properties 파일로 설정
#---------- file logging ----------
log4j.rootLogger=INFO, rolling
#---------- consol logging -----------
#log4j.rootLogger=INFO, stdout
#---------- file, console logging -----------
#log4j.rootLogger=INFO, stdout, rolling
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender
log4j.appender.rolling.File=/WEB_BACKUP1/pgw_log/webchannel.log
log4j.appender.rolling.Append=true
#---------- every day renew ------------
log4j.appender.rolling.DatePattern='.'yyyy-MM-dd
#---------- every month renew ------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM
#---------- every week renew ------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-ww
#---------- every 12hours renew -------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-a
#---------- every hour renew --------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-HH
#---------- every min renew --------------
#log4j.appender.rolling.DatePattern='.'yyyy-MM-dd-HH-mm
log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n


위 properties 파일은 실제 WebChannel에 적용한 파일입니다.
- log4j.rootLogger=INFO, rolling
        : 로깅레벨을 ‘INFO’로 하고 ‘rolling’이라는 이름의 Appender를 사용한다.
        위 properties파일에는 ConsoleAppender(stdout)와 DailyRollingFileAppender(rolling)가
정의되어 있습니다.
- log4j.rootLogger=INFO, stdout : console에만 출력
- log4j.rootLogger=INFO, stdout, rolling : console과 file 로 출력
위처럼 설정이 가능합니다.
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
        : ConsoleAppender의 이름은 ‘stdout’으로 한다.
- log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender
        : DailyRollingFileAppender의 이름은 ‘rollong’으로 한다.
- log4j.appender.rolling.File=/WEB_BACKUP1/pgw_log/webchannel.log
        : 로그파일의 위치와 파일명을 지정한다.
- log4j.appender.rolling.Append=true
        : 서버 restart시에도 파일이 reset되지 않는다.
- log4j.appender.rolling.DatePattern='.'yyyy-MM-dd
        : DatePattern 을 ‘매일갱신’으로 설정. 매일 자정이 지나면
파일명 뒤에 날짜가 붙는다.
        ex) webchannel.log.2005-11-21
- log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
        : layout을 PatternLayout으로 설정.
- log4j.appender.rolling.layout.ConversionPattern=[%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
        : 로그의 출력 형식을 설정. 아래 설명.

# log4j.appender.rolling.MaxFileSize=500KB
: 파일의 최대size 설정하는 부분인데 서버 기동시 최초에 이 부분의 property를 읽지 못했다는 경고가 자꾸 떠서 삭제 했습니다. 설정하지 않으면 Default로 10MB가 설정된다고 합니다.

#### properties 파일의 변경사항은 server restart시에 적용됩니다. ####
③ XML 파일로 설정
현재 잘 모르니 넘어가겠습니다.-_-


5. 설정 포맷
① DatePattern 설정 포맷
'.'yyyy-MM         매달 첫번째날에 로그파일을 변경합니다
'.'yyyy-ww         매주의 시작시 로그파일을 변경합니다.
'.'yyyy-MM-dd        매일 자정에 로그파일을 변경합니다.
'.'yyyy-MM-dd-a        자정과 정오에 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH        매 시간의 시작마다 로그파일을 변경합니다.
'.'yyyy-MM-dd-HH-mm        매분마다 로그파일을 변경합니다.




② PatternLayout 설정 포맷
%p        debug, info, warn, error, fatal 등의 로깅레벨이 출력된다.
%m        로그내용(코드상에서 설정한 내용)이 출력됩니다.
ex) logger.info("log"); 라고 코딩했다면 ‘log’가 로그 내용임.
%d        로깅 이벤트가 발생한 시간을 기록합니다.
포맷은 %d{HH:mm:ss, SSS}, %d{yyyy MMM dd HH:mm:ss, SSS}
같은 형태로 사용하며 SimpleDateFormat에 따른 포맷팅을 하면 된다
%t        로그이벤트가 발생된 쓰레드의 이름을 출력합니다.
%%        % 표시를 출력하기 위해 사용한다.
%n        플랫폼 종속적인 개행문자가 출력된다. \r\n 또는 \n 일것이다.
%c        카테고리를 표시합니다.
ex) 카테고리가 a.b.c 처럼 되어있다면
%c{2}로 설정하면 b.c 가 출력됩니다.
%C        클래스명을 포시합니다.
ex) 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면
%C{2}는 xyz.SomeClass 가 출력됩니다
%F        로깅이 발생한 프로그램 파일명을 나타냅니다.
%l        로깅이 발생한 caller의 정보를 나타냅니다
%L        로깅이 발생한 caller의 라인수를 나타냅니다
%M        로깅이 발생한 method 이름을 나타냅니다.
%r        어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds)
%x        로깅이 발생한 thread와 관련된 NDC(nested diagnostic context)를
출력합니다.
%X        로깅이 발생한 thread와 관련된 MDC(mapped diagnostic context)를
출력합니다.

ex) [%d] %-5p  at %C{3}.%M(%13F:%L) %3x - %m%n
 [2005-11-23 10:43:21,560] INFO   at
pgw.database.PGWBoardDAO.selectList(PGWBoardDAO.java:146) -
========== PGWBoardDAO#selectList ==========

포맷의 각 색깔별로 출력되는 실제 예입니다. 포맷 중간에 원하는 단어(at)나
기호(`.` , `-`)등을 넣으면 그대로 출력됩니다.



6. 실제 적용 예

다운받은 log4j.jar파일을 원하는 디렉토리에 복사하고 weblogic의
startWebLogic.cmd내의 classpath에 잡아줍니다. buildpath도 잡아주셔야 합니다.

① PGWBoardDAO.java
//import 해줍니다.
import org.apache.log4j.Logger;
.
//중략/

public class PGWBoardDAO extends PGWDAO {
    //parameter로 받은 이름의 instance를 생성합니다.
    static Logger logger = Logger.getLogger("PGWBoardDAO");
.
//중략/
.
public PGWBean selectList(HashMap hashMap) throws Exception {
.
/중략/
.
//            pstmt = conn.prepareStatement(sql.toString());
//LoggableStatement instance생성. LoggableStatement는 아래에서 설명.
            pstmt = new LoggableStatement(conn, sql.toString());

.
//중략/
.
pstmt.setInt(nIdx++, ((curPage-1)*listSize) + 9);
          pstmt.setInt(nIdx++, (curPage-1)*listSize);
        //주어진 로그내용을 ‘INFO’레벨로 출력합니다.
getQueryString()으로 ‘?’가 실제데이터로 치환된 query를 출력합니다.
            logger.info("\n======== PGWBoardDAO#selectList ========\n "
                        + ((LoggableStatement)pstmt).getQueryString() +
                       "\n========================================\n");


.
//중략/
.

        } catch (SQLException se) {
            System.out.println("PGWBoardDAO.selectList SQLException ====" + se);
           //Exception은 ‘ERROR’레벨로 출력합니다.
            logger.error("\n==== PGWBoardDAO#selectList Exception ====" , se );
            return null;
        } catch (Exception e) {
            System.out.println("PGWBoardDAO.selectList Exception ====" + e);
            logger.error("\n==== PGWBoardDAO#selectList Exception ====" , e );
            return null;
        } finally {
.
//중략/


- 위 코드에서 INFO 레벨의 로그는 주어진 로그를 출력하고,
ERROR 레벨의 로그는 발생한 Exception을 로그로 출력합니다.

로그의 출력메서드는 2가지 형식을 지원합니다.
logger.fatal(Object message)        logger.fatal(Object message, Throwable t)
logger.error(Object message)        logger.error(Object message, Throwable t)
logger.warn(Object message)          logger.warn(Object message, Throwable t)  
logger.info(Object message)          logger.info(Object message, Throwable t)  
logger.debug(Object message)         logger.debug(Object message, Throwable t)

- Throwble 타입의 변수를 parameter로 받는 메서드를 이용하면 원하는 위치에서
원하는 Exception을 발생시킬 수도 있습니다.

- 위 코드에서 INFO 레벨의 로그는 주어진 내용를 출력하고,
ERROR 레벨의 로그는 발생한 Exception을 로그로 출력합니다.


② LoggableStatement.java
- 이 클래스는 query를 로그로 출력할 때 부가적으로 필요한 클래스로 PreparedStatement의 ‘?’를 실제 데이터로 치환해서 출력하는 기능을 합니다.
이 클래스는 Interface인 PreparedStatement를 구현하는 클래스로 파일이름은 임의로 정하셔도 됩니다.
클래스내에는 PrepareddStatement의 메서드를 오버라이딩한 메서드와 넘어온 데이터를 ArrayList에 넣어주는 메서드, 그리고 query의 ‘?’를 치환해 리턴해주는 메서드를 구현합니다.

//PreparedStatement 와 ArrayList를 import 해줍니다.
//메서드 오버라이딩시에 필요한 클래스도 추가적으로 import 해줍니다.
import java.sql.PreparedStatement;
import java.util.ArrayList;

public class LoggableStatement implements PreparedStatement {

        private ArrayList parameterValues;
 
    private String sqlTemplate;

    private PreparedStatement wrappedStatement;

//connection.prepareStatement(String sql) 대신에 사용할 생성자 입니다.
//PreparedStatement Object를 생성, query를 String에 담고 ArrayList를 생성합니다.
    public LoggableStatement(Connection connection, String sql)
            throws SQLException {
            wrappedStatement = connection.prepareStatement(sql);
            sqlTemplate = sql;
            parameterValues = new ArrayList();
    }

.
//중략/
.



//실제로 필요한 메서드만 오버라이딩 하고, 나머지는 auto generate하시면 됩니다.
//여기서는 query문 실행관련 메서드와 setInt, setString, setDate, setCharacterStream 을 오버라이딩 했습니다.
        public boolean execute() throws java.sql.SQLException {
            return wrappedStatement.execute();
    }

        public boolean execute(String sql) throws java.sql.SQLException {
            return wrappedStatement.execute(sql);
    }

        public int[] executeBatch() throws java.sql.SQLException {
            return wrappedStatement.executeBatch();
    }

        public java.sql.ResultSet executeQuery() throws java.sql.SQLException {
            return wrappedStatement.executeQuery();
    }

        public java.sql.ResultSet executeQuery(String sql)
            throws java.sql.SQLException {
            return wrappedStatement.executeQuery(sql);
    }

        public int executeUpdate() throws java.sql.SQLException {
            return wrappedStatement.executeUpdate();
    }

        public int executeUpdate(String sql) throws java.sql.SQLException {
            return wrappedStatement.executeUpdate(sql);
    }

        public java.sql.Connection getConnection() throws java.sql.SQLException {
            return wrappedStatement.getConnection();
    }

       
public void setCharacterStream(
            int parameterIndex,
            java.io.Reader reader,
            int length)
            throws java.sql.SQLException {
            wrappedStatement.setCharacterStream(parameterIndex, reader, length);
            saveQueryParamValue(parameterIndex, reader);

    }

        public void setDate(int parameterIndex, java.sql.Date x)
            throws java.sql.SQLException {
            wrappedStatement.setDate(parameterIndex, x);
            saveQueryParamValue(parameterIndex, x);
    }

        public void setDate(
            int parameterIndex,
            java.sql.Date x,
            java.util.Calendar cal)
            throws java.sql.SQLException {
            wrappedStatement.setDate(parameterIndex, x, cal);
            saveQueryParamValue(parameterIndex, x);
    }

        public void setInt(int parameterIndex, int x)
                        throws java.sql.SQLException {
                        wrappedStatement.setInt(parameterIndex, x);
            saveQueryParamValue(parameterIndex, new Integer(x));
        }

        public void setString(int parameterIndex, String x)
                        throws java.sql.SQLException {        
                        wrappedStatement.setString(parameterIndex, x);
            saveQueryParamValue(parameterIndex, x);
        }
       
//넘어온 데이터를 ArrayList에 담아주는 메서드입니다.
        private void saveQueryParamValue(int position, Object obj) {
                String strValue;
                if (obj instanceof String || obj instanceof Date) {
                        strValue = "'" + obj + "'";
                } else {
                        if (obj == null) {
                              strValue = "null";
                        } else {
                                strValue = obj.toString();
                        }
                }
                while (position >= parameterValues.size()) {
                parameterValues.add(null);
                }
                parameterValues.set(position, strValue);
        }
       
        //instance생성시 String에 넣어둔 query의 ‘?’를 ArrayList에 담긴 실제 데이터로
//치환해서 리턴해 줍니다.
        public String getQueryString() {
                //여기서 query를 String에도 담아준 이유는 webLogic의 jdk가 1.3 버전으로
//StringBuffer의 indexOf(String str) 메서드를 사용할 수 없었기 때문입니다.
//다른 방법이 있으시면 알려주세요..
                String sql = sqlTemplate;
                StringBuffer query = new StringBuffer(sqlTemplate);
                int idx = 0;
               
                if(!parameterValues.isEmpty())
                {
                        for(int i=1;i < parameterValues.size();i++)
                        {
                                idx = sql.indexOf("?");
                                query.replace(idx, idx+1, (String)parameterValues.get(i));
                                sql = query.toString();
                        }
                        parameterValues = null;
                        return query.toString();
                }
                else
                {
                        parameterValues = null;
                        return query.toString();
                }
        }
}


- 다음은 실제 출력문입니다.

[2005-11-23 13:50:19,030] INFO at pgw.database.listDAO.modify(listDAO.java:543)   -
========== llistDAO#modify#if Customer ==========
UPDATE ACKLIST
   SET NM_USER = 'aaaaaaaaaa',
       NO_SSN = '2222222222222',
       NO_MINHEADER = '222',
       NO_MINNUMBER = '22222222',
       REASON = '22222222222222222444444444444444444444',
       ID_MODIFY = 'pbadmin',
       DT_MODIFY = SYSDATE
WHERE SEQ_NUM = '460'
   AND TYPE = '2'
Posted by 1010
54.iBATIS, MyBatis/iBatis2008. 11. 19. 14:01
01.JAVA/Java2008. 11. 19. 13:55
반응형




1. 폰트파일(nGulim.ttf)를 폰트 매트릭스 파일(nGulim.xml)로 바꾼다

java -cp D:\work\FopToPdf\WebContent\WEB-INF\lib\fop.jar;D:\work\FopToPdf\WebContent\WEB-INF\lib\avalon-framework.jar;D:\work\FopToPdf\WebContent\WEB-INF\lib\commons-logging.jar;D:\work\FopToPdf\WebContent\WEB-INF\lib\commons-io.jar org.apache.fop.fonts.apps.TTFReader D:\Temp\fop\nGulim.ttf D:\Temp\fop\nGulim.xml


2. 폰트파일과 폰트매트릭스 파일을 컨피그에 등록.

<font metrics-url="D:\Temp\fop\nGulim.xml" embed-url="D:\Temp\fop\nGulim.ttf" kerning="yes">
    <font-triplet name="NewGulim" style="normal" weight="normal"/>
    <font-triplet name="NewGulim" style="normal" weight="bold"/>
</font>

3. 컨피그를 사용하겠다고 알림

// 유저가 설정한 컨피그 파일을 사용한다. 밑에서 유저 에이전트를 생성하기 전에 컨피그 파일을 설정해야 폰트 등이 적용된다
fopFactory.setUserConfig(new File("d:/Temp/fop/mycfg.xml")); 


FOUserAgent foUserAgent = fopFactory.newFOUserAgent();

.

.

.


4. fo 파일을 EUC-KR로 사용, 사용할 폰트를 설정

<?xml version="1.0" encoding="EUC-KR"?>
<fo:root font-family="NewGulim" font-size="12pt" font-style="normal" font-weight="normal" text-align="center" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name='simpleA4' page-height='29.7cm' page-width='21cm' margin-top='2cm' margin-bottom='2cm' margin-left='2cm' margin-right='2cm'>
      <fo:region-body/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference='simpleA4'>
    <fo:flow flow-name='xsl-region-body'>
      <fo:block>안녕</fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

Posted by 1010
05.JSP2008. 11. 19. 13:53
반응형

JExcelApi(jxl.jar 다운로드)


http://www.andykhan.com/jexcelapi/index.html 에서 download JExcelApi에 가면
(http://www.andykhan.com/jexcelapi/download.html) tar.gz로 되어 있는데 압축풀면 jxl.jar있음


POI다운로드
http://jakarta.apache.org/poi/index.html /download/release


[엑셀파일읽기]

<%@ page language="java" %>
<%@ page contentType="text/html; charset=euc-kr"%>
<%@ page import="java.io.File,jxl.*"%>
<%


Workbook workbook = Workbook.getWorkbook(new File("E:/_Workspace/blr/blr/cms/excel/data/Book1.xls"));


Sheet sheet = workbook.getSheet(0);
Cell a1 = sheet.getCell(0,0);
Cell b2 = sheet.getCell(1,1);
Cell c3 = sheet.getCell(0,2);


String stringa1 = a1.getContents();
String stringb2 = b2.getContents();
String stringc3 = c3.getContents();


workbook.close();


%>


<%=stringa1%>
<%=stringb2%>
<%=stringc3%>


[엑셀파일로 저장]


<%@ page language="java" %>
<%@ page contentType="text/html; charset=euc-kr"%>
<%@ page import="java.io.File,java.util.Date,jxl.*,jxl.write.*"%>
<%
WritableWorkbook workbook = Workbook.createWorkbook(new File("E:/_Workspace/blr/blr/cms/excel/data/aaa.xls"));


WritableSheet sheet = workbook.createSheet("First Sheet", 0);
Label label = new Label(0,2,"A label record");
sheet.addCell(label);


// java.lang.Number 인지 jxl.write.Number  구분해야지^^


jxl.write.Number number = new jxl.write.Number(3,4,3.1415);
sheet.addCell(number);


workbook.write();
workbook.close();
%>


[POI로 테이블에 값넣기] poi.jsp참조


/***************************************************************************************/


엑셀파일처리 POI,JXL비교해 보았습니다.


10000번 for문을 돌려 첫번째 칼럼에 데이타를 입력하였습니다.


이걸 10번 반복한 체크시간입니다.




측정시간단위(밀리세컨)
D:\>java writeTest
============= jxl write time =============
0=>write time::719
1=>write time::281
2=>write time::250
3=>write time::266
4=>write time::234
5=>write time::266
6=>write time::234
7=>write time::266
8=>write time::234
9=>write time::329
=============      end      =============
============= poi write time =============
0=>write time::1110
1=>write time::922
2=>write time::1031
3=>write time::734
4=>write time::1328
5=>write time::766
6=>write time::797
7=>write time::1515
8=>write time::1719
9=>write time::2890
=============      end      =============



거의 2~3배 가까이 시간의 차이가 있더군여.. 단순히 엑셀파일만 다룬다면
jxl패키지를 사용하시는게 훨씬 좋을듯 합니다.

Posted by 1010
01.JAVA/Java2008. 11. 19. 13:50
반응형

ⅰ. 엑셀을 자바로 읽을(쓰는것 포함) 수 있도록 하는 방법은 jxl과 poi 두가지 방법이 있는데 우선 그나마 간단한 jxl 방법을 몇자 적어 보도록 하겠다.
( jxl과poi차이나 특성, 프로젝트 정보등은 검색엔진을 이용하길 바란다. )

 우선
http://www.andykhan.com/jexcelapi/download.html 에 가서 최신jexcelapi.tar 파일을 다운로드 하고 압축을 풀면 파일안에 jxl.jar파일이 있다. 이 jar파일을 인식 시키기 위하여, 자바가 설치된 곳의 라이브러리 폴더에 이 파일을 넣는다. (예 : C:/Program Files/Java/jdk1.6.0_01/jre/lib/ext/jxl.jar).

 쓰기 등을 원하거나 다른 것을 원할때는
http://www.andykhan.com/jexcelapi/tutorial.html로 가면 tutorial이 있으니 이걸 참고하길 바란다.

--참고로 엔디칸인가 하는 주인장 한테 메일 보내 봤는데 답장이 없으니 편지 보내지는 말자.

ⅱ. 그럼 예문을 만들어 보면

/***************************************************************
*  기          능   :  엑셀파일 읽어 String으로 반환
*     Function    :  getData(int row) row : 읽을 시작행 번호
*  참          조   :  C:/Program Files/Java/jdk1.6.0_01/jre/lib/ext/jxl.jar
*  Return value  :  String
*  작    성    자  :  유 진 철
*  작    성    일  :  2007-08-17
/***************************************************************/

import jxl.*;
import java.io.*;
import java.util.*;

public class ReadXLS
{
   String filename = null;

   //ReadXLS 생성자
   public ReadXLS(String filename)
   {
      this.filename = filename.trim();  
   }

   //String 반환하는 메소드
   public String getData(int row) throws Exception
   {
      //파일 생성및 데이터 선언
      StringBuffer cellData = new StringBuffer();                     
      File file = new File(filename); 

      //존재여부 판단
      if(file.exists())
      {
         //파일여부 판단
         if(file.isFile())
         {
            StringTokenizer st = new StringTokenizer(filename, ".");
            String xls = null;

            //파일 확장자 구하기
            while(st.hasMoreTokens())
            {
               xls = st.nextToken();  
            }

            //확장자 엑셀파일 여부판단
            if(xls.equals("xls"))
            {
               //엑셀정보 에서 쉬트정보 가져오기
               Workbook workbook = Workbook.getWorkbook(file);
               Sheet sheet = workbook.getSheet(0);
              
              //데이터 생성및 구분자 삽입 col=>[xxx] / row=>\n
               for (int i=row; i<sheet.getRows(); i++ )
               { 
                  for (int j=0; j<sheet.getColumns(); j++ )
                  { 
                     Cell cell = sheet.getCell(j,i);
                     cellData.append("["+cell.getContents().trim()+"]");                                  
                  }
                  cellData.append("\n");
               }            
               workbook.close();
            }
            else
            {
               throw new Exception("엑셀파일이 아닙니다.");
            }

         }
         else
         {
            throw new Exception("파일이 아닙니다.");
         }
      }
      else
      {        
         throw new Exception("존재하지 않는 이름 입니다.");
      }           
      return new String(cellData);//String 반환
   }//end getData()

   public static void main(String [] args)
   {
      try
      {
         ReadXLS readxls = new ReadXLS("ex.xls");
         String xls = readxls.getData(0); //0번 행 부터 읽기      
         System.out.println(xls );
      }//End Of try
      catch (Exception e)
      {
         e.printStackTrace();
      }//End Of catch     
   }//End Of Main 
  
}


/*
다음과 같은 프로그램을 컴파일 해서 돌리면(물론 같은 폴더에 ex.xls라는 엑셀 파일을 하나 실험용으로 만들어서 넣어둔다.)
[xxx][xxx][xxx]...
[xxx][xxx][xxx]
[][][][][][][][]
[][][][][][][][]
.
.
.
이런 식으로 결과가 나온다.
프로그램에서 파일겍체를 만들거나 하는것은 안전한 실행을 위해서 한것이고 핵심은 색상이 다른 부분을 중점적으로 보면 될것이다.
*/


ⅰ. 엑셀을 자바로 읽는방법 두번째를 작성하여 보도록 하겠다.

  POI프로젝트는 아파치구룹의 자카르타 프로젝트 일환으로 poor object importalble과 비슷한 약자였다. (확실하지는 않다ㅡ.ㅡ;) 아무튼 혼자 만으로는 빈약하다는 뜻인거 같다.
그리고 poi자체로 토란이라는 뜻도 있단다. 역시 빈약하다.
아무튼 모든 아파치 구룹이 그러하듯 
http://mirror.apache-kr.org/poi/release/bin/
 가서 zip최신걸로, 덜렁 받아 압축풀고 클레스 패스 잡아준다.
 추신 : POI는 Microsoft Format File을 액세스 할 수 있는 API를 제공한다고 한다.
(엑셀만 할수 있는 것이 아니란 말이다.)

 참고로
http://apache.org/ 가서 poi 선택하고 javadocs가면 API있다.
영어되면 다른 무궁한 프로젝트도 참고 하길 바란다. 

ⅱ. 역시 예문을 만들어 보면


/***************************************************************
*  기          능    :  엑셀파일 읽어 String으로 반환
*     Function     :  getData(), getData(String sheets, String rows, String cols),
                       :  xlsFormDate..., getXLSDate...
*  참 조 :  C:/Program Files/Java/jdk1.6.0_01/jre/lib/ext/poi-3.0.1-FINAL-20070705.jar
            :  C:/Program Files/Java/jdk1.6.0_01/jre/lib/ext/poi-contrib-3.0.1-FINAL-20070705.jar
            :  C:/Program Files/Java/jdk1.6.0_01/jre/lib/ext/poi-scratchpad-3.0.1-FINAL-20070705.jar
*  Return  value :  String
*  작    성    자  :  유 진 철
*  작    성    일  :  2007-12-17
/***************************************************************/

import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.model.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.*;

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;

public class ReadXLS
{
   //필드 선언 엑셀파일이름, 내용, 읽을범위
   private String filename = null;
   private HSSFWorkbook hssfworkbook = null;
   private int startSheet =  0;
   private int endSheet   = -1;
   private int startRow   =  0;
   private int endRow     = -1;
   private int startCol   =  0;
   private int endCol     = -1;

   //ReadXLS 생성자
   public ReadXLS(String filename) throws Exception
   {     
      File file = new File(filename); 

      //존재여부 판단
      if(file.exists())
      {
         //파일여부 판단
         if(file.isFile())
         {
            StringTokenizer st = new StringTokenizer(filename, ".");
            String xls = null;

            //파일 확장자 구하기
            while(st.hasMoreTokens())
            {
               xls = st.nextToken();  
            }

            //확장자 엑셀파일 여부판단
            if(xls.equals("xls"))
            {
               this.filename = filename;
               POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(filename));
               hssfworkbook = new HSSFWorkbook(fs);              
            }
            else
            {
               throw new Exception("엑셀파일이 아닙니다.");
            }

         }
         else
         {
            throw new Exception("파일이 아닙니다.");
         }
      }
      else
      {        
         throw new Exception("존재하지 않는 이름 입니다.");
      }        
   }

   //String 반환하는 메소드
   public String getData() throws Exception
   {
      return getData("ALL","ALL","ALL");
   }

   //String 반환하는 메소드
   public String getData(String sheets, String rows, String cols) throws Exception
   {
      //입력받은 값을 엑셀파일 읽을범위 값으로 전환
      StringTokenizer stTok = new StringTokenizer(sheets, ",");
      StringTokenizer rwTok = new StringTokenizer(rows,   ",");
      StringTokenizer clTok = new StringTokenizer(cols,   ",");

      String startSheetTok = null;
      String endSheetTok   = null;
      String startRowTok   = null;
      String endRowTok     = null; 
      String startColTok   = null;
      String endColTok     = null; 

      int sheetCounts = stTok.countTokens();
      int rowCounts   = rwTok.countTokens();
      int colCounts   = clTok.countTokens();

      //쉬트범위 판단
      if(sheetCounts == 2)
      {
         startSheetTok = stTok.nextToken();
         endSheetTok   = stTok.nextToken();
        
         try
         {
            startSheet = Integer.parseInt(startSheetTok);
            if (startSheet<0) { startSheet = 0; }    
         }
         catch(NumberFormatException ne){}

         try
         {  
            endSheet   = Integer.parseInt(endSheetTok);             
         }
         catch(NumberFormatException ne){}    
      }

      //행범위 판단
      if(rowCounts == 2)
      {
         startRowTok = rwTok.nextToken();
         endRowTok   = rwTok.nextToken();
        
         try
         {
            startRow = Integer.parseInt(startRowTok);
            if (startRow<0) { startRow = 0; }    
         }
         catch(NumberFormatException ne){}

         try
         {  
            endRow   = Integer.parseInt(endRowTok);             
         }
         catch(NumberFormatException ne){}    
      }

      //열범위 판단
      if(colCounts == 2)
      {
         startColTok = clTok.nextToken();
         endColTok   = clTok.nextToken();
        
         try
         {
            startCol = Integer.parseInt(startColTok);
            if (startCol<0) { startCol = 0; }    
         }
         catch(NumberFormatException ne){}

         try
         {  
            endCol   = Integer.parseInt(endColTok);             
         }
         catch(NumberFormatException ne){}    
      }
      //읽어서 처리하는 메소드 호출
      return execute();
   }

   //실행 메소드
   private String execute() throws Exception
   {
      StringBuffer cellData = new StringBuffer();
     
      //읽는범위 유효성검사 및 조정
      int sheetNum = hssfworkbook.getNumberOfSheets()-1;
      if((startSheet-endSheet)>0 || endSheet>sheetNum)
      {           
         endSheet = sheetNum;
      }
     
      //읽는범위 만큼 실행
      for (int k = startSheet; k <= endSheet; k++)
      {
        
         HSSFSheet sheet = hssfworkbook.getSheetAt(k);
         if(sheet!=null)
         {           
            int       rowNum  = sheet.getLastRowNum();
            if((startRow-endRow)>0 || endRow>rowNum)
            {           
               endRow = rowNum;
            }

            for (int r = startRow; r <= endRow; r++)
            {              
               HSSFRow row   = sheet.getRow(r);
               if(row!=null)
               {                 
                  int    colNum = row.getLastCellNum()-1;
                  if((startCol-endCol)>0 || endRow>colNum)
                  {           
                     endCol = colNum;
                  }

                 
                  for (int c = startCol; c <= endCol; c++)
                  {                    
                    HSSFCell cell  = row.getCell((short)c);
                     String   value = null;
                     if(cell!=null)
                     {
                        //셀타입 구분
                        switch (cell.getCellType())
                        {
                           case HSSFCell.CELL_TYPE_BLANK   :                             
                              value = "["+""
                              + "]";
                              break;

                           case HSSFCell.CELL_TYPE_BOOLEAN :                             
                              value = "["+cell.getBooleanCellValue()
                              + "]";
                              break;

                           case HSSFCell.CELL_TYPE_ERROR   :                            
                              value = "["+cell.getErrorCellValue()
                              + "]";
                              break;

                           case HSSFCell.CELL_TYPE_FORMULA :                             
                              value = "["+cell.getCellFormula()                             
                              + "]";
                              break;

                           case HSSFCell.CELL_TYPE_NUMERIC :                             
                              DecimalFormat dft = new DecimalFormat("########################.########");
                              value = "["+dft.format(cell.getNumericCellValue())
                              + "]";
                              break;

                           case HSSFCell.CELL_TYPE_STRING :                                                     
                              value = "["+cell.getRichStringCellValue().getString()
                              + "]";
                              break;

                           default :
                        }//End Of switch
                       
                        cellData.append(value);
 
                     }//End Of if cell
                    
                     else{cellData.append("[]");}                    

                  }//End Of for c++
                  cellData.append("\n");
               }//End Of if row
            }//End Of for r++
         }//End Of if sheet
      }//End Of for k++
     
      return new String(cellData);//String 반환
   }

   /*
   Date and Time Pattern        Result 
   "yyyy.MM.dd G 'at' HH:mm:ss z"   2001.07.04 AD at 12:08:56 PDT 
   "EEE, MMM d, ''yy"           Wed, Jul 4, '01 
   "h:mm a"                  12:08 PM 
   "hh 'o''clock' a, zzzz"       12 o'clock PM, Pacific Daylight Time 
   "K:mm a, z"               0:08 PM, PDT 
   "yyyyy.MMMMM.dd GGG hh:mm aaa"   02001.July.04 AD 12:08 PM 
   "EEE, d MMM yyyy HH:mm:ss Z"   Wed, 4 Jul 2001 12:08:56 -0700 
   "yyMMddHHmmssZ"              010704120856-0700 
   "yyyy-MM-dd'T'HH:mm:ss.SSSZ"   2001-07-04T12:08:56.235-0700
   */

   //원하는 페턴으로 문자형 날짜전달
   public static String xlsFormDate(String Pattern, String Date) throws Exception
   {     
      int date = Integer.parseInt(Date.trim());
      return xlsFormDate(Pattern, date);      
   }

   //원하는 페턴으로 문자형 날짜전달
   public static String xlsFormDate(String Pattern, int Date)
   {
      Calendar cal = Calendar.getInstance();
      cal.clear();  
      cal.add(cal.DATE, Date-25569);
      SimpleDateFormat sdt = new SimpleDateFormat(Pattern);
      return sdt.format(cal.getTime());
   }
  
   //Date 객체전달
   public static Date getXLSDate(String Date) throws Exception
   {     
      int date = Integer.parseInt(Date.trim());
      return getXLSDate(date);      
   }

   //Date 객체전달
   public static Date getXLSDate(int Date)
   {
      Calendar cal = Calendar.getInstance();
      cal.clear();  
      cal.add(cal.DATE, Date-25569);     
      return cal.getTime();
   }  

   public static void main(String [] args)
   {
      try
      {
         ReadXLS readxls = new ReadXLS("ex.xls");
         String xls = readxls.getData("0,0","ALL","ALL");        
         System.out.println(xls );

         /* //날짜 메소드 실험후 주석 처리함
         String Date = ReadXLS.xlsFormDate("yyyy-MM-dd hh:mm", "39423");
         System.out.println("Date : "+Date );

         Date aa = ReadXLS.getXLSDate("39423");
         System.out.println("Object Date : "+aa.toString());
        */

      }//End Of try
      catch (Exception e)
      {
         e.printStackTrace();
      }//End Of catch     
   }//End Of Main 
  
}

/*
똑같이 프로그램을 컴파일 해서 돌리면(물론 같은 폴더에 ex.xls라는 엑셀 파일을 하나 실험용으로 만들어서 넣어둔다.)
[xxx][xxx][xxx]...
[xxx][xxx][xxx]
[][][][][][][][]
[][][][][][][][]
.
.
.
이런 식으로 결과가 나온다.
이것 역시 필요없는 부분이 많은데 이것은 신경쓰지 말고 색상 있는 부분만 보면 된다. 좀더 편리하게 날짜를 데이터베이스에 넣거나(xlsFormDate), 지수를 소수로 표현하기 위하여(DecimalFormat) 사용한 겍체가 몇게 있다.  
*/

Posted by 1010
01.JAVA/Java2008. 11. 19. 13:48
반응형

Orinoco - A Java API to generate PDF documents

This is the home page of Orinoco: a Java API allowing Java developers to generate PDF documents.

Yet another PDF generator?

There are many Java PDF generators available - why bother with another one? The motivation arose when trying to use a commercially available PDF generator to deliver adhoc reports through a browser. The PDF generator offered everything: charts, drawings, images etc., but all that was required was merely to lay out some text in a tabular format with a few headings in bold. The tool we were using could certainly do this, but when generating larger reports (around 70 pages) it was taking so long to generate the PDF that the HTTP request timed out and the users ended up with nothing.

Rather than spend the time finding another generator and negotiating licensing agreements I decided to write a PDF generator which satisfied our meagre functional requirements and focussed on delivering the generated document quickly.

Orinoco offers the functionality needed to generate text reports (no graphics) and it is very quick: it can generate a document of a couple of hundred pages in a few seconds.

Features

  • Allows presentation of text in a variety of fonts and styles
  • Headers, footers and page numbering
  • Layout data in tables, with headings
  • Background shading
  • Tabs
  • Paper sizes and page orientation
  • Automatically handles line wrapping and page breaks

    Click here to see a sample

    This example shows the extended character set supported with orinoco, together their octal character codes

    Limitations

    Only the "standard" set of postscript fonts are supported (Times Roman, Helvetica,Courier etc). There is no support for drawing (other than straight lines) or embedding images.

    Using the library

    Orinoco requires a set of font information files, which are packaged along with the distribution in a subdirectory called fonts. Whenever the API is invoked it will look for this subdirectory under the system property called "resources".

    The easiest way to set this system property is to use the -D option when invoking the JVM eg.

    java -Dresources=/path/to/resources ...

    Orinoco will therefore expect to find the fonts directory on the system as /path/to/resources/fonts

    Demo

    To invoke the demo program which generates this PDF document, open a command line prompt in the "orinoco" directory, which was created when the distribution was untarred:

    java -classpath orinoco.jar -Dresources=resources orinoco.demo.Test -pdf test.pdf

    Note the use of -D option to set the resources system property. This points to the immediate subdirectory "resources" and orinoco will look in here for the subdirectory called "fonts".

    Examine the source code src/orinoco.demo/Test.java to see how the orinoco API can be used to generate PDF documents.

    Installation

    Orinoco comes packaged as a zipped tar file, called something like orinoco_1_0_3.tar.gz. To unpack on UNIX systems, at the command line type

    gunzip orinoco_1_0_3.tar.gz      followed by
    tar xf orinoco_1_0_3.tar

    On Linux systems this can be accomplished within the single command

    tar zxf orinoco_1_0_3.tar.gz

    On Windows/NT systems, the archive may be unpacked visually using a utility such as Winzip.

    Whatever the unpacking process, the application will be placed in a subdirectory called orinoco. The top level directory contains this html page and the pre-built jar file, orinoco.jar. The resources directory contains the fonts subdirectory, which in turn contains the important font information files. The docs directory contains the javadoc documentation for the public classes, the build directory contains the buildfile (requires ant ) and the src directory contains the source code for the java classes.

    Licensing

    Orinoco is issued on under the GNU Lesser General Public License. For further information click here.

    Download Orinoco

    Change History

    Return to my home directory

    This site last updated 18th December, 2007

  • Posted by 1010
    01.JAVA/Java2008. 11. 19. 13:47
    반응형

    Java Excel API - A Java API to read, write and modify Excel spreadsheets

    This is the home page of Java Excel API - open source Java API which allows Java developers to read Excel spreadsheets and to generate Excel spreadsheets dynamically. In addition, it contains a mechanism which allows java applications to read in a spreadsheet, modify some cells and write out the new spreadsheet.

    This API allows non Windows operating systems to run pure Java applications which can both process and deliver Excel spreadsheets. Because it is Java, this API may be invoked from within a servlet, thus giving access to Excel functionality over internet and intranet web applications.

    Features

  • Reads data from Excel 95, 97, 2000 workbooks
  • Reads and writes formulas (Excel 97 and later only)
  • Generates spreadsheets in Excel 2000 format
  • Supports font, number and date formatting
  • Supports shading and colouring of cells
  • Modifies existing worksheets
  • Supports image creation
  • Preserves macros on copy
  • Customizable logging

    Limitations

  • JExcelApi does not generate or chart, graph or macro information. This information is however preserved when spreadsheets are copied
  • When adding images to a sheet, only PNG image formats are supported

    Getting started

    The distribution comes with a number of demo programs which illustrate how the API may be used.

    Reading Spreadsheets

    When reading a spreadsheet, the demo programs may be used "as is" to convert Excel files to CSV and XML formats in a reasonable manner.

    java -jar jxl.jar -csv myspreadsheet.xls

    To view the spreadsheet as XML, invoke the demo as follows

    java -jar jxl.jar -xml myspreadsheet.xls

    In order to present the data the demo uses the classes xlrd/CSV.java and xlrd/XML.java respectively. For more sophisticated processing, these classes may be used as a starting point. Click here for a tutorial.

    Generating Spreadsheets

    The write demo illustrates the functionality accessible within JExcelApi to generate spreadsheets. The spreadsheet generated by the demo includes different fonts, number formatting, date formatting, colours and borders.

    To generate the demo spreadsheet, invoke JExcelApi as follows:

    java -jar jxl.jar -write myspreadsheet.xls

    This will generate the sample spreadsheet called myspreadsheet.xls in the current working directory. The class used to generate this spreadheet is jxl/Write.java. This may be used as a starting point for bespoke processing.

    Copying Spreadsheets

    JExcelApi may be used to copy and modify a spreadsheet. Included with the JExcelApi is a spreadsheet called jxlrwtest.xls, which is hardcoded into the demo program. If this spreadsheet is passed as a command line argument to the demo, then a copy of this spreadsheet will be generated, with the second sheet containing modified values.

    DO NOT MODIFY THE DEMO SPREADSHEET otherwise the modification demo will not work.

    To run this demo, from the directory containing jxlrwtest.xls type

    java -jar jxl.jar -rw jxlrwtest.xls myoutput.xls

    This will generate an output spreadsheet called myoutput.xls. The first sheet (called "original") is unchanged, but the second sheet (called "modified" has had its cell contents changed, as indicated by the labels.

    The class for the modification demo is jxl/ReadWrite.java.

    Requirements

    JExcelApi requires Java 2 JDK to run.

    When dealing with large spreadsheets, particularly when using the copy functionality, it is recommended that users allocate sufficient memory to the JVM using the -Xms and -Xmx options on the java command line.

    Installation

    JExcelApi comes packaged as a zipped tar file, called something like jexcelapi_2_0.tar.gz. To unpack on UNIX systems, at the command line type

    gunzip jexcelapi_2_0.tar.gz      followed by
    tar xf jexcelapi_2_0.tar

    On Linux systems this can be accomplished within the single command

    tar zxf jexcelapi_2_0.tar.gz

    On Windows/NT systems, the archive may be unpacked visually using a utility such as Winzip.

    Whatever the unpacking process, the application will be placed in a subdirectory called jexcelapi. The top level directory contains this html page and the pre-built jar file, jxl.jar. The docs directory contains the javadoc documentation for the public classes, the build directory contains the buildfile (requires ant ) and the src directory contains the source code for the java classes.

    Excel Versions

    JExcelApi will read workbooks created in Excel 95, 97 and 2000, and will generate workbooks that can be read by Excel 97 and later.

    Licensing

    JExcelApi is issued on under the GNU Lesser General Public License. For further information click here.

    Further Notes

    A tutorial is available for those who wish guidance on how to use the API for reading, writing and copying spreadsheets.

    When writing out spreadsheets, JExcelApi has limited support for graphs charts and macros during the copy process, but they cannot be created via the API.

    For further technical information, including how JExcelApi handles dates and unicode characters, read the technical notes

    Download JExcelApi

    Change History



    I endeavour to answer all emails, but it's taking up more and more time. Before emailing me with a question please check the FAQ first.

    Eric Jung has set up a yahoo group  here. As well as providing a discussion forum I will also post a message to this group whenever a new version of JExcelApi is released.

    Stefano has ported JExcelApi to .net. You can access the software here
    Evgeniy has ported 2.6.2 to C#, which you can download here

    Acknowledgements

    From version 2.6.5, JExcelApi uses JFlex to parse Excel formulas. The JFlex runtime is distributed with JExcelApi, should you wish attempt a rebuild of JXL. However, at runtime JXL only uses the generated lexical parser and none of the actual JFlex runtime code, so users of JExcelApi are not tied to the JFlex GPL rules, only the JExcelApi LGPL agreements.

    More information about JFlex can be here

    Make a Donation

    JExcelApi is free software and will remain so. If JExcelApi has been of benefit to you or your company, perhaps you might like to make a voluntary donation to JExcelApi using PayPal

    Return to my home directory

    This site last updated 27th October, 2008

  • Posted by 1010
    05.JSP2008. 11. 19. 13:43
    반응형

    <%@ page language="java" contentType="application/vnd.ms-excel; name='My_Excel', text/html; charset=euc-kr"%>
    <%
    response.setHeader("Content-Disposition",
    "inline; filename=excel_" +new java.sql.Date(System.currentTimeMillis()) + "_.xls");
    response.setHeader("Content-Description", "JSP Generated Data");
    %>
    <html><body><table><tr><td>아아아</td><td>우우우</td></tr>
    <tr><td>우이이</td><td>아요에</td></tr>
    </table></body></html>

    예제인데요. 정말 쉽다 ^^;

    브라우져로 날짜별로 받습니다 jsp호출시 excel 파일로 인식하여 다운로드를 하거나, 열게 됩니다.
    Posted by 1010
    05.JSP2008. 11. 19. 13:41
    반응형

    JExcelApi(jxl.jar 다운로드)


    http://www.andykhan.com/jexcelapi/index.html 에서 download JExcelApi에 가면
    (http://www.andykhan.com/jexcelapi/download.html) tar.gz로 되어 있는데 압축풀면 jxl.jar있음


    POI다운로드
    http://jakarta.apache.org/poi/index.html /download/release


    [엑셀파일읽기]

    <%@ page language="java" %>
    <%@ page contentType="text/html; charset=euc-kr"%>
    <%@ page import="java.io.File,jxl.*"%>
    <%


    Workbook workbook = Workbook.getWorkbook(new File("E:/_Workspace/blr/blr/cms/excel/data/Book1.xls"));


    Sheet sheet = workbook.getSheet(0);
    Cell a1 = sheet.getCell(0,0);
    Cell b2 = sheet.getCell(1,1);
    Cell c3 = sheet.getCell(0,2);


    String stringa1 = a1.getContents();
    String stringb2 = b2.getContents();
    String stringc3 = c3.getContents();


    workbook.close();


    %>


    <%=stringa1%>
    <%=stringb2%>
    <%=stringc3%>


    [엑셀파일로 저장]


    <%@ page language="java" %>
    <%@ page contentType="text/html; charset=euc-kr"%>
    <%@ page import="java.io.File,java.util.Date,jxl.*,jxl.write.*"%>
    <%
    WritableWorkbook workbook = Workbook.createWorkbook(new File("E:/_Workspace/blr/blr/cms/excel/data/aaa.xls"));


    WritableSheet sheet = workbook.createSheet("First Sheet", 0);
    Label label = new Label(0,2,"A label record");
    sheet.addCell(label);


    // java.lang.Number 인지 jxl.write.Number  구분해야지^^


    jxl.write.Number number = new jxl.write.Number(3,4,3.1415);
    sheet.addCell(number);


    workbook.write();
    workbook.close();
    %>


    [POI로 테이블에 값넣기] poi.jsp참조


    /***************************************************************************************/


    엑셀파일처리 POI,JXL비교해 보았습니다.


    10000번 for문을 돌려 첫번째 칼럼에 데이타를 입력하였습니다.


    이걸 10번 반복한 체크시간입니다.




    측정시간단위(밀리세컨)
    D:\>java writeTest
    ============= jxl write time =============
    0=>write time::719
    1=>write time::281
    2=>write time::250
    3=>write time::266
    4=>write time::234
    5=>write time::266
    6=>write time::234
    7=>write time::266
    8=>write time::234
    9=>write time::329
    =============      end      =============
    ============= poi write time =============
    0=>write time::1110
    1=>write time::922
    2=>write time::1031
    3=>write time::734
    4=>write time::1328
    5=>write time::766
    6=>write time::797
    7=>write time::1515
    8=>write time::1719
    9=>write time::2890
    =============      end      =============



    거의 2~3배 가까이 시간의 차이가 있더군여.. 단순히 엑셀파일만 다룬다면
    jxl패키지를 사용하시는게 훨씬 좋을듯 합니다.

    Posted by 1010
    01.JAVA/Java2008. 11. 19. 13:39
    반응형

    출처 : http://pcguy7.springnote.com/pages/420735

    jxl_read.java

    jxl_write.java


    안녕하세요. Sharing Java 운영자 아기팬더 입니다. 자바를 이용하여 엑셀을 다루는 방법이 여러가지 있습니다.


    관심이 많아서 네이버를 통해서 학습을 하고자 했는데 일관된 예제들과 생각보다는 부족한 설명으로 인해 많은 이해하기 위해


    많은 시간을 보낸 것 같습니다. 개인적으로 공부차원에서 오늘 맘잡고 정리하여 공유합니다. 주석을 완전히 달면서 API 문서를


    보려고 하니 생각보다 시간이 많이 걸리더군요. 이클립스를 주로 다루기 때문에 코딩하고 실행하였을 때 이클립스 상에서는


    오류가 없었습니다. 혹시라도 실행이 안 되면 답글 달아주시면 바로 수정하겠습니다.


    저는 jxl api를 이용하여 정리하였습니다. 참고 바랍니다.


    1. 준비사항


        당연히 이클립스를 사용하신다면 jxl api(링크주소) 중에서 jexcelapi_2_6_4.zip 를 다운 받아서 사용하시는 프로젝트 파일

        주변에 압축을 풀어주세요.

        이클립스 메뉴바에서 현재의 프로젝트명을 오른쪽 클릭 - Build Path - Add External Archives 클릭한 후
        jxl API를 다운받아서 압축을 푼 곳에서 jxl.jar 파일을 찾아서 삽입시켜야 해요.

        배포를 고려한다면 엄한 곳에서 가져오지는 마세요^^


    2. 실전


        jxl api 폴더 내의 doc폴더 안을 보시면 java api와 똑 같은 형태의 api문서를 확인하실 수 있습니다. 너무 자세하죠 ?

        이제부터 주석을 꼼꼼히 보시면서 실행해 보시면 기분이 좋아지실 겁니다. ^^


    3. Jxl_Write.java (엑셀 파일을 생성하는 부분)


    //babypanda(2007.07.24)


    import java.io.File; // 파일 생성을 위해서 필요
    import java.io.FileNotFoundException; // 파일 생성을 위해서 필요
    import java.io.IOException; // 파일 생성을 위해서 필요


    // 아래의 jxl 부분을 이클립스에서 사용하시기 위해서는 메뉴바에서 현재의 프로젝트명을 오른쪽 클릭 - Build Path - Add External

        Archives 클릭한 후
    // jxl API를 다운받아서 압축을 푼 곳에서 jxl.jar 파일을 찾아서 삽입시켜야 해요. 꼭.... 반드시.... 무조건....
    // 배포를 고려한다면 엄한 곳에서 가져오지는 마셈. 가까운 곳에 압축을 풀어서 불러오셈. ^^


    import jxl.Workbook; // 엑셀 파일 관리를 위해 처음과 끝에 해당하는 기본이 되는 추상 클래스

    import jxl.write.WritableWorkbook; // 실제 엑셀 파일 관리를 위해 Workbook, Sheet을 생성하는 Swing의 Frame과 같은 사막의 오아시스 역할하는 추상 클래스
    import jxl.write.WritableSheet; // 쉬트를 관리하는 인터페이스
    import jxl.write.WritableCellFormat; // 셀의 포멧 관련 클래스
    import jxl.write.WriteException; // 셀의 쓰기 오류를 관리하기 위한
    import jxl.write.Label; // 라벨 관리 클래스
    //import jxl.write.Blank; // 빈셀 관리 클래스

    import jxl.format.*; // 셀 정렬, 보더, 컬러 부분 관련 클래스 임포트


    public class Jxl_Write{

         public static void  main(String args[]) throws FileNotFoundException, IOException, WriteException{
         // 예외처리를 아예 해주고 내려옵니다.
     
         WritableWorkbook myWorkbook = Workbook.createWorkbook(new File("jxl_Smile.xls")); // 파일이름을 정하여 생성한다.

         WritableSheet mySheet = myWorkbook.createSheet("first sheet", 0); // WritableSheet는 인터페이스
         // WritableWorkbook에서 메소드를 이용하여 생성. 0번, 즉 첫번째 쉬트를 first sheet라는 이름으로 생성한다.

       

         WritableCellFormat numberFormat = new WritableCellFormat(); // 번호 셀 포멧 생성
         WritableCellFormat nameFormat = new WritableCellFormat(); // 이름 셀 포멧 생성
         WritableCellFormat dataFormat = new WritableCellFormat(); // 데이터 셀 포멧 생성

       

         // 번호 레이블 셀 포멧 구성(자세한 것은 링크 된 API를 참조하셈) 참고사항 : 여기 부분에서 WriteException이 발생하네요.
         // 그러나 상단에서 미리 예외 처리를 해서 상관 없겠네요.

         numberFormat.setAlignment(Alignment.CENTRE); // 셀 가운데 정렬
         numberFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 셀 수직 가운데 정렬
         numberFormat.setBorder(Border.ALL, BorderLineStyle.THICK); // 보더와 보더라인스타일 설정
         numberFormat.setBackground(Colour.ICE_BLUE); // 여름에 맞는 색깔 ? ^^
     
         // 이름 레이블 셀 포멧 구성(자세한 것은 링크 된 API를 참조하셈)
         nameFormat.setAlignment(Alignment.CENTRE); // 셀 가운데 정렬
         nameFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 셀 수직 가운데 정렬
         nameFormat.setBorder(Border.BOTTOM, BorderLineStyle.HAIR); // 보더와 보더라인스타일 설정
         nameFormat.setBackground(Colour.GOLD); // 여름에 맞는 색깔 두번째 ? ^^


         // 데이터 셀 포멧 구성
         dataFormat.setAlignment(Alignment.CENTRE); // 셀 가운데 정렬
         dataFormat.setVerticalAlignment(VerticalAlignment.CENTRE); // 셀 수직 가운데 정렬


         // 쉬트의 컬럼 넓이 설정

         mySheet.setColumnView(0, 8); // 쉬트의 번호 컬럼(0번째)의 넓이 설정. setCloumnView(몇번째 컬럼, 넓이)
         mySheet.setColumnView(1, 15); // 쉬트의 이름 컬럼(1번째)의 넓이 설정
         mySheet.setColumnView(2, 20); // 쉬트의 비고 컬럼(2번째)의 넓이 설정


         // 라벨을 이용하여 해당 셀에 정보 넣기 시작

         Label numberLabel = new Label(0, 0, "학번", numberFormat); // 학번 라벨(열,행,"문장",포멧)
         mySheet.addCell(numberLabel); // 쉬트의 addCell 메소드를 사용하여 삽입

         Label nameLabel = new Label(1, 0, "성명", nameFormat); // 성명 라벨(열,행,"문장",포멧)
         mySheet.addCell(nameLabel); // 쉬트의 addCell 메소드를 사용하여 삽입


         //Blank blank = new Blank(2, 0, numberFormat); // 빈 셀(열,행,포멧) -- 필요 시 주석 처리 풀고 사용하셈. ^^
         //sheet.addCell(blank);


         Label postScript = new Label(2, 0, "비고", nameFormat); // 비고 라벨(열,행,"문장",포멧)
         mySheet.addCell(postScript); // 쉬트의 addCell 메소드를 사용하여 삽입

           for(int no=1; no<6; no++){
              Label numberLabels = new Label(0, no, "["+no+"]", dataFormat); // 데이터 포멧에 맞게 1에서 5까지 번호 생성
              mySheet.addCell(numberLabels); // 셀에 삽입
           
              Label nameLabels =new Label(1, no, (char)(no+64)+"", dataFormat); // 데이터 포멧에 맞게 대문자 A에서 E까지 생성
              mySheet.addCell(nameLabels); // 셀에 삽입
          }

         // 라벨을 이용하여 해당 셀에 정보 넣기 끝


         myWorkbook.write(); // 준비된 정보를 엑셀 포멧에 맞게 작성
         myWorkbook.close(); // 처리 후 메모리에서 해제 처리
         }
    }


    4. Jxl_Read.java (엑셀파일을 읽어오는 부분)


    //babypanda(2007.07.24)

    import java.io.*; // 파일 입력 관련 클래스
    import jxl.*; // jxl 관련 클래스


    public class Jxl_Read{
         public static void  main(String args[]) throws FileNotFoundException, IOException,jxl.read.biff.BiffException{
        // 이번에도 파일과 엑셀 파일 입력 관련 예외 선언을 미리 해주고 들어옵니다.


         Workbook myWorkbook = Workbook.getWorkbook(new File("jxl_Smile.xls")); // 파일을 읽어 와서...
         Sheet mySheet = myWorkbook.getSheet(0); // 정확한 쉬트를 입력 받아서...
     
         System.out.print("학번\t성명\t비고\t\n"); // 엑셀 제목을 적어 주고
     
              for(int no=1;no<6;no++){ // 행의 갯수 만큼 돌리고
                   for(int i=0;i<3;i++){ // 열의 갯수 만큼 돌려서
                            Cell myCell = mySheet.getCell(i,no); // 셀의 행과 열의 정보를 가져온 후...
                            System.out.print(myCell.getContents()+"\t"); // 텝의 거리 만큼 열을 나열 하고...
              //getContents()메소드에 대해

              //Quick and dirty function to return the contents of this cell as a string. 이라고 API에 쓰여 있더군요.
                   }
                System.out.println(); // 행이 바뀔 때 마다 개행하여 출력해 보셈.
              }
         }
    }


    5. 실행화면


    1) 엑셀에 쓰기




     

    2) 엑셀 파일의 비고란에 글자를 입력한 후 저장하여 읽어오면 ?





    Posted by 1010
    01.JAVA/Java2008. 11. 19. 13:38
    반응형

    자바 JXL API 를 이용한 Excel 파일 만들기
     
    1. JXL API 다운 받기
     
    2. JSP에서 사용할 class 만들기
     
    3. JSP에서 적용하기
     
    4. 요구 사항에 맞게 확장하기
     
     
    1. 환경 설정
     
    JAVA에서 Excel을 만들기 위해서는 JXL API 나 POI를 이용해야 한다.
     
    우선 이번장에서는 JXL을 이용하여 만드는 방법에 대해서 소개하기로 한다.
     
    Java Excel API - A Java API to read, write and modify Excel spreadsheets ( 이하 JXL )은
     
    다음과 같은 홈페이지에서 다운 받을 수 있다
     
     
    파일 다운 받기 : 
     
     
    API 정보  :
     
     
     
    우선 사이트에서 가장 최신 버젼의 JExcelApi를 다운 받는다.
     
    압축을 해제한 후에 각 사용자 환경에 맡게 jar 파일을 옮긴다.
     
    ( 일반 JAVA User - j2sdk 폴더 밑에 jrelibext 파일로 옮긴다. )
     
     
    2. JSP에서 사용할 class 만들기
     
     
    1. Parameter 정보
     
    JSP에서 class로 넘겨주는 정보는 다음과 같다.
     
    Vector data  :: Query를 통해 나온 Recordset 집합
     
    String[] column  ::  column 이름 <- Excel 에서 Head 역할
     
    int[] columntype :: column 타입 <- 문자형, 정수형, 실수형 으로 구분하였다.
     
    String FilePath :: Excel 파일을 저장하기위한 절대 경로
     
    String SheetName :: Sheet 이름
     
     
    2. Excel File 생성하기
     
    Excel 파일음 다음과 같이 생성을 한다
     
    WritableWorkbook workbook = Workbook.createWorkbook(new File(FilePath));
    WritableSheet sheet = workbook.createSheet(SheetName, 0);
     
    - FilePath :: Excel 파일을 저장하기위한 절대 경로
    - SheetName :: 시트 이름
    - 0 :: 시트 인덱스 번호
     
     
    3. Cell Type 지정하기
     
    a. Text 형
    jxl.write.WritableCellFormat format_column = new WritableCellFormat();
    jxl.write.WritableCellFormat format_data = new WritableCellFormat();

     
    b. 정수형 ( 1000단위 마다 , 찍기 X )
    jxl.write.WritableCellFormat format_integer1 = new WritableCellFormat(NumberFormats.INTEGER);

     
    c. 정수형 ( 1000단위 마다 , 찍기 O )
    jxl.write.NumberFormat moneytype1 = new NumberFormat("###,##0");
    jxl.write.WritableCellFormat format_integer2 = new WritableCellFormat(moneytype1);

     
    d. 실수형 ( 1000단위 마다 , 찍기 X )
    jxl.write.WritableCellFormat format_float1 = new WritableCellFormat(NumberFormats.FLOAT);
     
    e. 실수형 ( 1000단위 마다 , 찍기 0 , 소수점 2자리 허용 )
    jxl.write.NumberFormat moneytype2 = new NumberFormat("###,##0.00");
    jxl.write.WritableCellFormat format_float2 = new WritableCellFormat(moneytype2);
     
    4. CELL Color & BackGround 지정하기
                           
    format_column.setBackground(jxl.format.Colour.GRAY_25 );
    format_column.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THIN );
       
    .
    .
     
     
    5. DB To Excel
     
    a. Head 부분 생성하기
     
       for ( cellnum = 0; cellnum < column.length; cellnum++ ) {
        label = new jxl.write.Label(cellnum,0,column[cellnum],format_column);
        sheet.addCell(label);
       }
     
    b. Data 집어 넣기
       for ( rownum = 1; rownum <= data.size() ; rownum++) {
        dataResult = (String[])data.get(rownum-1);
     
        for (cellnum = 0; cellnum < dataResult.length - 1; cellnum++) {
          num = new jxl.write.Number(cellnum, rownum, Long.parseLong(dataResult[cellnum+1]),format_integer2);
          sheet.addCell(num);
        }
       }
                                      
     
    3. JSP에서 사용하기
    <%@ page import="java.util.Vector, crm.util.Util, java.sql.*" contentType="text/html; charset=euc-kr" %>
    <jsp:useBean id="cExcel" class="crm.util.CreateExcel" scope="page"/>
     
     
    cExcel.CreateExcelFile(queryResult,column,columntype,file_path+file_name,sheet_name,str_search);
     
     
    4. 요구 사항에 맞게 확장하기

    JXL API를 제공하는 홈페이지에 가면 JXL API SDK를 다운 받을 수 있다.
     
    JXL API SDK를 다운 받은 후 사용자 요구 사항에 맞게 수정을 하면 될 것이다.
     
     
    원본 : #. 자바 JXL API 를 이용한 Excel 파일 만들기
    Posted by 1010
    01.JAVA/Java2008. 11. 19. 13:37
    반응형



    http://okjsp.pe.kr/seq/122183

    jxl은 대용량데이터를 엑셀문서를 통해 입력할때 속도가 빠릅니다.
    단점은 엑셀형식으로 데이터를 받았을때 제대로 된 엑셀이 아니라 조작이 좀 그렇습니다.
    반대로 poi는 데이터를 엑셀문서로 다운받았을때 제대로 된 엑셀문서라 현업들이 바로 조작하고 사용하기가 편합니다.
    하지만 데이터를 넣을때 소량은 상관없지만 수만개이상넣을때..좀 느립니다.
    그래서 저도 지금까지 4,5번해봤지만 데이터를 넣을때는 jxl로 데이터를 받을때는 poi로 합니다.
    Posted by 1010
    91..개발관련프로그램2008. 11. 19. 13:17
    반응형

    We suggest the following mirror site for your download:

    http://ftp.kaist.ac.kr/pub/Apache/

    Other mirror sites are suggested below. Please use the backup mirrors only to download PGP and MD5 signatures to verify your downloads or if no other mirrors are working.

    HTTP

    FTP

    Backup Sites

    Please use the backup mirrors only to download PGP and MD5 signatures to verify your downloads or if no other mirrors are working.

    http://www.apache.org/dist/
    http://www.eu.apache.org/dist/

    The full listing of mirror sites is also available.
    The procedure for setting up new mirrors is described in How to become a mirror.

    Verify the integrity of the files

    It is essential that you verify the integrity of the downloaded files using the PGP or MD5 signatures. Please read Verifying Apache Software Foundation Releases for more information on why you should verify our releases.

    The PGP signatures can be verified using PGP or GPG. First download the KEYS as well as the asc signature file for the relevant distribution. Make sure you get these files from the main distribution site, rather than from a mirror. Then verify the signatures using

    % pgpk -a KEYS
    % pgpv downloaded_file.asc
    or
    % pgp -ka KEYS
    % pgp downloaded_file.asc
    or
    % gpg --import KEYS
    % gpg --verify downloaded_file.asc

    Alternatively, you can verify the MD5 signature on the files. A unix program called md5 or md5sum is included in many unix distributions. It is also available as part of GNU Textutils. Windows users can get binary md5 programs from here, here, or here.

    Posted by 1010
    98..Etc/Etc...2008. 11. 17. 21:23
    반응형

    Vmware를 이용한 Ubuntu 설치 방법


    저는 Vmware 6.x 버전을 사용했습니다. Ubuntu Linux는 8.04 버전이며 여기서 다운로드 합니다. 저는 32bit 로 Daum 서버에서 다운로드 했습니다. 로케이션에 보시면 Daum서버가 있으니 그걸 이용하세요.

    Windows에 Vmware와 Ubuntu의 이미지가 준비 되었다면 이제 본격적으로 Ubuntu를 설치해 보겠습니다.

    Vmware에서 New Virtual Machine 을 누릅니다.
    Menu -> File -> New -> Virtual Machine
    or
    Crtl + N


    이런 화면이 나오게 됩니다.

    다음 을 눌러 줍니다.


    Guest의 OS를 선택하는 부분입니다.
    리눅스를 선택하시고 우분투를 선택합니다.


    버추얼 머신이 만들어 장소와 이름을 지정해 줍니다.


    이제 네트워크를 선택할 차례입니다. 네트워크는 4가지 선택을 할 수가 있습니다.
    첫번째 Use bridged networking은 많이들 사용하지만 가끔 문제가 생긴다고 보고되고 있습니다. 그 문제가 호스트(Windows)가 인터넷을 사용할 경우 게스트에서 인터넷이 안 될 경우도 있고 게스트가 인터넷을 사용할 경우 호스트가 인터넷이 안되는 경우가 있다고 하더군요.

    두번째 NAT 방식은 쉽게 말하면 호스트가 라우터의 기능을 하게 됩니다. 그래서 게스트에게 IP를 나눠 주지요. 설명하기 편하게 호스트가 "공유기"가 되어 게스트에게 IP를 할당해 주게 됩니다. 여기서 NAT를 선택해 주시면 됩니다.

    세번째 Use Host Only는 말 그대로 호스트만 인터넷이 되는 것입니다. 게스트는 인터넷이 안돼죠.

    Virtual Machine의 하드디스크를 설정하는 부분입니다.
    하드디스크의 용량과 어떤 방식을 사용할 것인지 선택합니다.
    우분투 리눅스는 4GB USB에도 설치가 가능합니다. 6GB 면 충분하다고 생각해서 저는 6 GB를 선택했습니다. 기본은 8 GB입니다.


    아래의 체크 버튼 Allocate all disk space now는 Ubuntu가 설치될 공간을 미리 만들어 놓는 것입니다. 가상 하드디스크는 파일로 만들어지게 되는데 이것을 선택하면 6GB 의 파일을 미리 만들어 놓고 시작하게 됩니다. 체크를 해제하게 되면 6GB 까지 사용 가능하지만 디스크 사용량에 따라서 파일의 크기가 점점 늘어나는 형식입니다. 물론 6GB 이상은 안돼겠지요.


    자 이제 Virtual Machine이 다 만들어 졌습니다.
    세부 설정으로 넘어갑니다.


    Edit virtual machine setting을 선택합니다.


    여기서 Memory의 크기나 CD의 마운트 등을 할 수 있습니다.
    다른것은 모두 기본으로 놔두고 Floppy는 사용하지 않으니 Floppy는 삭제 해 줍니다.
    그리고 CD-ROM을 선택합니다.


    CD-ROM을 선택한 뒤 오른쪽에서 Use ISO image를 선택하시고 Browser 버튼을 눌러 앞서 다운로드한 Ubuntu의 이미지를 불러옵니다. 그리고 OK버튼을 누르시면 됩니다.

    이제 새로 맞춘 새 컴퓨터의 전원을 넣어 볼 차례입니다.
    아이콘의 재생 버튼을 누릅니다.


    한국어를 선택해 줍니다.


    맨위의 설치하지 않고 우분투 사용해 보기 를 누르시고 진행 합니다.


    부팅 중 입니다.

    부팅이 완료 되었습니다. 이제 Ubuntu를 사용해 볼 수도 있으며 설치도 할 수 있습니다. 우리는 설치를 하기 위한 것이므로 몇 가지 설정을 마친 뒤 바로 설치를 하도록 하겠습니다.


    설정이란 네트워크 설정을 하는 것 입니다. 우분투는 가상 랜카드를 인식하게 되는데 이를 무선랜 카드로 인식합니다.
    우분투의 오른쪽 위의 모니터가 두개 겹쳐있는 아이콘을 클릭합니다. 이 아이콘은 네트워크를 뜻하는 아이콘 입니다. 클릭하게 되면 메뉴가 펼쳐집니다.

    + 왜 인터넷을 연결하고 설치를 해야하죠?
    인터넷을 연결하고 설치를 하는 이유는 간단합니다. 한국어 지원을 받기 위해서 입니다. CD에는 한글패키지 중 몇가지가 빠져있어서 CD로만 설치를 진행하면 나중에 한글팩 설치를 따로 해줘야 하는 불편함이 있습니다. 인터넷을 연결하고 설치를 진행하게 되면 자동으로 한글팩을 다운로드 받아 설치 해 주게 됩니다.


    여기서 마지막 메뉴인 Maual configuration을 눌러 줍니다.


    위와 같이 Wired connection을 선택하고 옆의 Properties 버튼을 누릅니다.


    가운데 작은 창이 하나 뜨고 Enable roaming mode 가 체크되어 있는데 이를 체크해제해 주시고 Configuration 항목을 DHCP 방식으로 바꿔 주시고 OK버튼을 누르세요


    설정이 되었습니다. 이제 Close를 누르시고 인터넷이 되는지 확인해 볼 차례입니다.


    Firefox를 실행시킵니다. Firefox는 인터넷 익스플로러와 같은 인터넷 브라우져 입니다.


    잘 되는군요. 저는 youtube 사이트로 한번 가보았습니다. 여러분들도 자주 가는 사이트로 한번 들어가 보세요.
    그럼 설치를 진행 하도록 하겠습니다. Firefox를 끄시고 바탕화면의 설치아이콘을 더블 클릭 해주세요


    자동으로 한국어가 선택 됩니다. 앞으로를 누르세요.


    자동으로 서울의 시간대가 선택되어있습니다. 앞으로를 누르세요.


    여기서 중요한 키보드 설정입니다. 대부분의 사람들이 기본 설정인 USA의 키보드를 선택하는데요. 그렇게 설치하시면 나중에 한/영키가 안먹어서 다시 설정을 해 주어야 하는 번거로움이 있습니다. 왼쪽으 스크롤 바를 올려 보시면 Korea, Republic of 가 있습니다 이를 선택하시고 오른쪽에서 101/104 키를 선택해 주시면 나중에 한/영키가 자동으로 반영 됩니다.

    다음은 파티션의 설정부분인데 네이티브로 Ubuntu를 설치한다면 몰라도 가상머신에서 돌리는 것이므로 파티션 설정은 자동으로 해 놓고 넘어 갑니다. 계속 앞으로를 눌러주세요.
    설치가 진행될때 까지요.

    여기까지 Vmware를 이용한 Ubuntu 설치였습니다.

    이제 설치가 모두 끝나고 재부팅이 끝났나요?

    마지막으로 우분투를 설치하고 바로 설정해 줘야 할 것이 있습니다.


    제 글만 잘 따라오시면 됩니다.

    메뉴에서 "시스템" -> "관리" -> "소프트웨어 소스" 를 클릭합니다.


    여기서 다운로드 위치 의 수정을 해야 합니다. 처음엔 대한민국 서버가 선택되어있는데
    이것을 Daum서버로 바꾸어 주어야 합니다. 대한민국 서버로는 총 세개가 있는데, 카이스트서버와 Daum서버와 letsopen서버가 있습니다. 주로 카이스트 서버와 다음서버를 많이 사용하는데 카이스트서버는 메인서버와 동기화가 잘 되어있지않아 누락된 패키지가 몇개 있습니다. 그래서 동기화와 다운로드 속도가 안정적인 Daum 서버를 선택합니다.
    Other를 누르면 Daum서버를 고를 수 있습니다.

     

    서버선택
    버튼을 누르고 닫기를 누르시면 다시읽기가 나옵니다 그것을 눌러주시면 됩니다.
    이제 업데이트 목록이 뜰텐데요, 128개 정도 됩니다. 전부 업데이트 해 줍니다.

    업데이트 후 재부팅을 합니다. 재부팅 후 마음대로 우분투를 사용하시면 됩니다.
    우분투의 세팅과 설치가 끝났습니다.




    추가 : 당신이 필요한 패키지

    vi 를 사용하신다면
    터미널에서
    sudo apt-get install vim-full

    c언어를 공부하신다면

    터미널에서
    sudo apt-get install build-essential

    emacs 를 사용하신다면
    터미널에서
    sudo apt-get install emacs


    수고하셨습니다.
    Posted by 1010