캠핑과 개발


가끔 서버에서 주기적으로 어떠한 작업을 하고자 할때 리눅스에서는 크론탭을 사용하여 주기적으로 어떠한 작업을 처리합니다.
이런 주기적 작업을 처리하기위해 Spring에서 지원해 주는 Quartz스케쥴러를 통해 크론탭과 같은 역할을 하는 스케쥴러를 작성할 수 있습니다.
이번에는 Spring 과 Quartz를 연동하여 스케줄러를 작성해 보겠습니다.

작업순서는
스프링 기본 세팅 -> Quartz 세팅 순으로 작업하겠습니다.

1. 스프링 기본 설정
1) springframework.org 로 이동하셔서 스프링 라이브러리를 다운 받습니다.

위와 같은 페이지가 뜨면 해당사항을 입력하시고 Access Download 를 클릭하셔서 다운로드 페이지로 이동합니다. (귀찮으신 분들은 하단의 파란색으로 "download page"를 선택하시면 입력하시지 않고도 다운로드 페이지로 이동하실수 있습니다.

많은 버전의 라이브러리 중 spring-framework-2.5.6.SEC02.zip 를 다운 받습니다. 다른 버전을 다운 받으셔도 상관없습니다만 버전에 따라 세팅 내용이 조금 씩 달라지므로 같은 버전의 라이브러리로 진행하는 것이 나을 것같네요~^^.

2) 이렇게 라이브러리까지 다운로드 받고 나면 Eclipse와 같은 IDE에서 Dynamic Web Project를 선택하여 Project를 한개 생성합니다.
(저는 SpringQuartz 라는 이름으로 생성했습니다.)

3) 프로젝트가 생성되면 프로젝트 안에 /WEB-INF/lib 디렉토리에 스프링 라이브러리를 압축 푼 곳에 있는 dist/spring.jar 파일을 추가합니다.
* 팁 : 프로젝트를 진행하다 보면 위와같이 라이브러리 버전이 없는 jar파일을 그냥 추가하는 경우가 있는데 나중에 라이브러리를 업데이트 해야 할일이 생기게 되면 위와같이 spring.jar 라고 되어있으면 지금 적용되어 있는 버전이 몇 인지 알수가 없습니다. 그렇기 때문에 항상 라이브러리 추가하실때는 추가하시는 라이브러리의 버전 번호를 파일이름 뒤에 추가하는 습관을 들이 시는게 좋습니다.
     ex) spring-2.5.6.jar

4) 프로젝트 안에 생성된 web.xml에 Spring을 사용하기 위한 세팅을 추가해 줍니다.
* 저는 Quartz를 사용하기 위한 최소한의 Spring 세팅을 해놓았기 때문에 세팅 내용이 단순합니다. 만약 웹프로젝트와 함께 Quartz를 사용하신다면 웹에 맞게 설정하시고 사용하셔야 함을 알려드립니다.^^
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"      
  4.     xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee      
  5.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  id="WebApp_ID" version="2.5">    <listener>  
  6.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>     
  7.     </listener>      
  8.     <context-param>          
  9.         <param-name>contextConfigLocation</param-name>         
  10.         <param-value>/WEB-INF/config/applicationContext*.xml</param-value>  
  11.     </context-param>  
  12. </web-app>  


5) 쿼츠 라이브러리를 다운로드 받고 라이브러리를 추가해 줍니다.
쿼츠 라이브러리 다운로드 하신다음 압축을 풀어 줍니다.
해당 라이브러리를 프로젝트의 lib 디렉토리에 복사하여 넣어줍니다.
- quartz-all-1.8.3.jar
- 압축푼 lib 디렉터리의 log4j-1.2.14.jar
- 압축푼 lib 디렉터리의 slf4j-api-1.5.10.jar
- 압축푼 lib 디렉터리의 slf4j-log4j12-1.5.10.jar
를 추가 해 줍니다.
마지막으로 apache의 commons-logging-1.1.1.jar 를 다운로드 하셔서 위와 같이 프로젝트의 lib에 추가해주시면 라이브러리 추가는 끝이 납니다.

6) Quartz의 핵심적인 기능을 할 /WEB-INF/config/applicationConext.xml 을 작성합니다.
스케쥴러의 핵심 세팅은 3가지 정도 입니다.
하나. 실제 주기적으로 실행될 클래스 등록
둘. 스케줄러가 동작하는 interval time 설정
셋. 실제 동작하게 끔 설정

이런 세가지가 있겠습니다.

스케줄러 동작방식에는 두가지가 존재 합니다.
-Simple : interval time이 간단하게 동작하는 방식으로 몇초, 혹은 몇분, 몇시간 단위로 작동하고 싶을때 사용합니다.
<Simple type setting>
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:context="http://www.springframework.org/schema/context"  
  4.        xmlns:p="http://www.springframework.org/schema/p"  
  5.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans      
  7.                            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  8.                            http://www.springframework.org/schema/context   
  9.                            http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
  10.     <!-- 하나.주기적으로 실행될 클래스 설정 -->  
  11.     <!-- property name은 jobClass로 fix, value는 사용자가 작성한 class 파일 위치 -->  
  12.     <bean id="simpleQuartzJob" class="org.springframework.scheduling.quartz.JobDetailBean">  
  13.         <property name="jobClass" value="net.test.quartz.SimpleQuartzJob"/>  
  14.     </bean>  
  15.   
  16.     <!-- 둘.스케줄러의 interval time 설정 -->  
  17.     <!-- 쿼츠에는 아래와 같이 몇초에 한번씩 돌게 하는 Simple type 과 -->  
  18.     <!-- 무슨 요일 몇시에 한번씩 돌게 하는 날짜로 지정하는 Cron type 이 있다. -->  
  19.     <!-- 현재는 Simple type으로 세팅 -->  
  20.     <!-- jobDetail은 위에서 설정한 실제 동작할 클래스 id를 적어준다 -->  
  21.     <!-- startDelay는 서버 시작후 몇초 뒤에 시작할지 세팅(ms 단위)  -->  
  22.     <!-- repeatInterval은 몇 초에 한번씩 실행될 건지 세팅(ms 단위: 현재 1초) -->  
  23.     <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  
  24.         <property name="jobDetail" ref="simpleQuartzJob"/>  
  25.         <property name="startDelay" value="1000"/>  
  26.         <property name="repeatInterval" value="1000"/>  
  27.     </bean>  
  28.     <!--셋. 실제 동작하게끔 설정 -->  
  29.     <!--ref bean은 위에서 설정한 interval time 아이디를 넣어주면 됨  -->  
  30.     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  31.         <property name="triggers">  
  32.             <list>  
  33.                 <ref bean="simpleTrigger"/>  
  34.             </list>  
  35.         </property>  
  36.         <!-- Quartz 실행시 세팅 -->  
  37.         <property name="quartzProperties">  
  38.             <props>  
  39.                 <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>  
  40.                 <prop key="org.quartz.threadPool.threadCount">5</prop>  
  41.                 <prop key="org.quartz.threadPool.threadPriority">4</prop>  
  42.                 <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>  
  43.                 <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>  
  44.             </props>  
  45.         </property>  
  46.     </bean>  
  47. </beans>  

-Cron : linux 의 Cron tab 과 같은 역할을 하는 타입니다. 즉 몇월, 몇일 몇시에 동작하게 하고 싶으면 Cron type을 사용하시면 됩니다.
<Cron type setting>
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:context="http://www.springframework.org/schema/context"  
  4.        xmlns:p="http://www.springframework.org/schema/p"  
  5.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.        xsi:schemaLocation="http://www.springframework.org/schema/beans      
  7.                            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  8.                            http://www.springframework.org/schema/context   
  9.                            http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
  10.     <!--하나. 주기적으로 실행될 클래스 설정 -->  
  11.     <bean id="cronQuartzJob" class="org.springframework.scheduling.quartz.JobDetailBean">  
  12.         <property name="jobClass" value="net.test.quartz.CronQuartzJob"/>  
  13.     </bean>  
  14.        
  15.     <!--둘. 스케줄러의 interval time 설정-->  
  16.     <!--cronExpression을 통해서 스캐줄러 주기를 설정한다. -->  
  17.     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
  18.         <property name="jobDetail" ref="cronQuartzJob"/>  
  19.         <property name="cronExpression" value="0/1 * * * * ?"/>  
  20.     </bean>  
  21.        
  22.     <!--셋. 실제 동작하게끔 설정 -->  
  23.     <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  24.         <property name="triggers">  
  25.             <list>  
  26.                 <ref bean="cronTrigger"/>  
  27.             </list>  
  28.         </property>  
  29.         <property name="quartzProperties">  
  30.             <props>  
  31.                 <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>  
  32.                 <prop key="org.quartz.threadPool.threadCount">5</prop>  
  33.                 <prop key="org.quartz.threadPool.threadPriority">4</prop>  
  34.                 <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>  
  35.                 <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>  
  36.             </props>  
  37.         </property>  
  38.     </bean>  
  39. </beans>  


Cron type을 사용하려면 CronExpression을 알아야 합니다.

*Cron Expression
cron expression의 각각의 필드는 다음을 나타낸다.(왼쪽 -> 오른쪽 순)
 필드 이름  허용 값  허용된 특수 문자
 Seconds  0 ~ 59  , - * /
 Minutes  0 ~ 59  , - * /
 Hours  0 ~ 23  , - * /
 Day-of-month  1 ~ 31  , - * ? / L W
 Month  1 ~12 or JAN ~ DEC   , - * /
 Day-Of-Week  1 ~ 7 or SUN-SAT  , - * ? / L #
 Year (optional)  empty, 1970 ~ 2099  , - * /

Cron Expression 의 특수문자
'*' : 모든 수를 나타냄. 분의 위치에 * 설정하면 "매 분 마다" 라는 뜻.
'?' : day-of-month 와 day-of-week 필드에서만 사용가능. 특별한 값이 없음을 나타낸다.
'-' : "10-12" 과 같이 기간을 설정한다. 시간 필드에 "10-12" 이라 입력하면 "10, 11, 12시에 동작하도록 설정" 이란 뜻.
',' : "MON,WED,FRI"와 같이 특정 시간을 설정할 때 사용한다. "MON,WED,FRI" 이면 " '월,수,금' 에만 동작" 이란 뜻.
'/' : 증가를 표현합니다. 예를 들어 초 단위에 "0/15"로 세팅 되어 있다면 "0초 부터 시작하여 15초 이후에 동작" 이란 뜻.
'L' : day-of-month 와 day-of-week 필드에만 사용하며 마지막날을 나타냅. 만약 day-of-month 에 "L" 로 되어 있다면 이번 달의 마지막에 실행하겠다는 것을 나타냄.
'W' : day-of-month 필드에만 사용되며, 주어진 기간에 가장 가까운 평일(월~금)을 나타낸다. 만약 "15W" 이고 이번 달의 15일이 토요일이라면 가장가까운 14일 금요일날 실행된다. 또 15일이 일요일이라면 가장 가까운 평일인 16일 월요일에 실행되게 된다. 만약 15일이 화요일이라면 화요일인 15일에 수행된다.
"LW" : L과 W를 결합하여 사용할 수 있으며 "LW"는 "이번달 마지막 평일"을 나타냄
"#" : day-of-week에 사용된다. "6#3" 이면 3(3)번째 주 금요일(6) 이란 뜻이된다.1은 일요일 ~ 7은 토요일 

 Expression  Meaning
 "0 0 12 * * ?"  매일 12시에 실행
 "0 15 10 ? * *"  매일 10시 15분에 실행
 "0 15 10 * * ?"  매일 10시 15분에 실행
 "0 15 10 * * ? *"  매일 10시 15분에 실행
 "0 15 10 * * ?  2010"   2010년 동안 매일 10시 15분에 실행
 "0 * 14 * * ?"  매일 14시에서 시작해서 14:59분 에 끝남
 "0 0/5 14 * * ?"  매일 14시에 시작하여 5분 간격으로 실행되며 14:55분에 끝남
 "0 0/5 14,18 * * ?"  매일 14시에 시작하여 5분 간격으로 실행되며 14:55분에 끝나고, 매일 18시에 시작하여 5분간격으로 실행되며 18:55분에 끝난다.
 "0 0-5 14 * * ?"  매일 14시에 시작하여 14:05 분에 끝난다.

* 시간에 맞춰 돌아가는 스케줄러에서 다른 클래스를 사용하고 싶을 때는 다음과 같이 설정합니다.
  1. <!-- 스프링 DI : 사용할 Service 객체를 생성 -->  
  2. <bean id="quartzJobService" class="net.test.quartz.service.impl.QuartzJobServiceImpl"/>  
  3.   
  4. <bean id="simpleQuartzJob" class="org.springframework.scheduling.quartz.JobDetailBean">  
  5.     <property name="jobClass" value="net.test.quartz.SimpleQuartzJob"/>  
  6.     <!-- 사용하고자 하는 class의 bean id를 등록 -->  
  7.     <property name="jobDataAsMap">  
  8.         <map>  
  9.             <entry key="quartzJobService">  
  10.                 <ref local="quartzJobService"/>  
  11.             </entry>  
  12.         </map>  
  13.     </property>  
  14. </bean>  

 *두가지 스케줄러를 동시에 실행 시킬때
  1. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  2.     <property name="triggers">  
  3.         <!--트리거를 두개 생성후 아래와 같이 세팅 -->  
  4.         <list>  
  5.             <ref bean="simpleTrigger"/>  
  6.             <ref bean="cronTrigger"/>  
  7.         </list>  
  8.     </property>  
  9.     <property name="quartzProperties">  
  10.         <props>  
  11.             <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>  
  12.                 <prop key="org.quartz.threadPool.threadCount">5</prop>  
  13.                 <prop key="org.quartz.threadPool.threadPriority">4</prop>  
  14.                 <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop>  
  15.                 <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>  
  16.         </props>  
  17.     </property>  
  18. </bean>  


7) 실제 작동할 Class파일 생성
  1. package net.test.quartz;   
  2.   
  3. import net.test.quartz.service.QuartzJobService;   
  4.   
  5. import org.quartz.JobExecutionContext;   
  6. import org.quartz.JobExecutionException;   
  7. import org.springframework.scheduling.quartz.QuartzJobBean;   
  8.   
  9. public class SimpleQuartzJob extends QuartzJobBean{   
  10.     //실행될 클래스는 꼭 QuartzJobBean을 상속받아야 되며    
  11.     //executeInternal method를 override 하면 자동으로 이 메소드가 실행   
  12.   
  13.     //Spring의 DI를 사용하여 Service객체를 setting   
  14.     //DI를 사용하지 않는다면 필요 없는 부분   
  15.     private QuartzJobService quartzJobService;   
  16.     public void setQuartzJobService(QuartzJobService quartzJobService) {   
  17.         this.quartzJobService = quartzJobService;   
  18.     }   
  19.   
  20.   
  21.     @Override  
  22.     protected void executeInternal(JobExecutionContext ex)throws JobExecutionException {   
  23.         quartzJobService.printLog();   
  24.     }   
  25.        
  26. }  


위와 같은 방식으로 Spring과 Quartz를 사용하여 스케줄러를 사용할 수 있습니다.

함께 업로드 하는 파일은 제가 직접 작업한 프로젝트이구요. 함께 확인 해 보시면 쉽게 쿼츠를 사용하실수 있으실 겁니다.~^^



출처 : http://javastore.tistory.com/96


로컬자원을 서버에 전송하기 위해 우리는 FileReference Class를 사용하면 된다.
FileReference로 파일을 서버에 전송하는 방법은 많이 공개가 되어 있다.
알다시피 FileReference의 browse()함수를 호출한 뒤, select 이벤트가 발생시 upload() 함수를 이용하여 선택한 로컬자원을 서버로 보낸다.

서버에서는 아주 단순하게 서버 임시 저장소에 저장된 파일을 원하는 곳에 복사하기만 하면 된다.
php의 경우 move_uploaded_file() 메소드를 사용하면 되겠다.

그럼 Flex 시행도중 캡쳐한 화면을 저장하는 경우에도 위와 같은 방법으로 저장이 가능할까?

답은 "된다"


나는 예전에 ImageSnapshot 클래스를 이용해 base64로 변환해서 서버로 전송한 뒤에 base64를 decode하여 저장하는 방법에 대해서 언급한적이 있다. (http://blog.jidolstar.com/301 참고)
이 방법의 단점은 이미지가 큰 경우 base64로 encode, decode 하는 과정에서 서버성능 및 클라이언트 성능에 따라 속도 및 부하에 영향을 준다. 그러므로 이 방법으로는 PNGEncoder 및 JPGEncoder로 PNG, JPG 파일 형식에 맞는 데이타를 만들었다고 해도, FileReference와 같이 데이타를 전송을 할 수 없었다.

하지만 Google을 열심히 돌아다녔다니 이 문제점에 대한 해결의 실마리를 찾을 수 있었다.
(역시 Google!!!)

간단히 방법을 요약하자면
화면을 BitmapData로 만들어 PNGEncoder나 JPGEncoder를 이용하여 encode한 다음, 그 결과값인 byteArray값을 서버에 전송한다. 전송된 데이타는 FileReference에서 upload()을 이용해 보낸 파일을 저장할때와 동일하게 저장하면 되겠다.

1. BitmapData로 캡쳐해라.

아래 target은 캡쳐할 UIComponent와 같은 DisplayObject 객체이다.

BitmapData로 캡쳐
var bitmapData:BitmapData = new BitmapData(target.width, target.height, true, 0xFFFFFF);
var drawingRectangle:Rectanglenew Rectangle(0, 0, target.width, target.height);
bitmapData.draw(target, new Matrix(), null, null, drawingRectangle, false);

단, BitmapData를 이용해서 화면을 캡쳐할 대상이 외부 동영상이나 사진같은 거라면 crossdomain.xml 에 대한 check가 있어야 한다. 컨텐츠 로드시 checkPolicyFile 속성을  true로 설정할 필요가 있겠다.
그리고 2880px 이상의 크기는 BitmapData로 만들 수 없다.



2. JPG나 PNG로 Encode 하여 ByteArray를 얻는다.


Flex 3 SDK에는 mx.graphics.codec 패키지에 JPGEncoder와 PNGEncoder가 있다. 인터넷을 뒤져보면 GIFEncoder등도 있을것이다. Flex 2 환경에서 작업한다면 Google code에 Adobe AS3 Corelib에 이들이 제공된다. 만약 JPGEncoder를 사용한다면 다음과 같이 하면 되겠다.

JPGEncoder를 이용하여  JPG  ByteArray값 만들기
import mx.graphics.codec.JPGEncoder;

var byteArray:ByteArray = new JPGEncoder().encode(bitmapData);


Flex 3 SDK는 이러한 Encoder가 IImageEncoder로 구현되었다. 필요하다면 언제 어디서나 Encoder를 바꿔야 하는 경우 IImageEncoder를 사용하는 것이 좋을 수 있겠다.
가령 아래 예제처럼 말이다.

다양한 Image Encoder 사용하기
import mx.graphics.codec.*;

var imageType:String = "jpg";
var imageEncoder:IImageEncoder;
if( imageType.toUpperCase() == "JPG" ) imageEncoder= new JPEGEncoder();
else if( imageType.toUpperCase() == "PNG" ) imageEncoder= new PNGEncoder();
var byteArray:ByteArray = imageEncoder.encode(bitmapData);



 

3. 서버에 ByteArray를 전송한다.

데이타를 전송할때는 FileReference를 사용하지 않는다.
바로 URLLoader와 URLRequest만 이용해서 전송이 가능하다. 참고 데이타는 POST방식으로 URLVariable을 이용해서 보낼 수 있다.

Flex/AIR 데이터 전송 방법
//assumed variable declarations
//var byteArray:ByteArray = 2번째 단계에서 JPG 데이타를 얻었다.
//var fileName:String = "desiredfilename.jpg" //저장할 파일 이름이다. 아무거나 적자!
//var uploadPath:String = "저장할 때 사용되는 서버측 script 경로"
//var parameters:URLVariables = 이미지 이외에 다른 보낼 다른 데이타가 있다면 이것을 이용한다.
//function onComplete(eventObj:Event):void {  성공적으로 데이타를 전송했을때 핸들러 함수 정의
//function onError(eventObj:ErrorEvent):void {  이미지 전송을 실패했을때 핸들러 함수 정의

var urlRequest:URLRequest = new URLRequest();
urlRequest.url = uploadPath;
//urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = UploadPostHelper.getPostData(file, byteArray, parameters);
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
urlRequest.requestHeaders.push( new URLRequestHeader( 'Content-Type', 'multipart/form-data; boundary=' +UploadPostHelper.getBoundary()) );

var urlLoader:URLLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.addEventListener(Event.COMPLETE, onComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
urlLoader.load(urlRequest);


위에 진한 부분에 대한 클래스는 아래에 정의되어 있다. 당신은 이 클래스가 어떻게 구성되었는가 열심히 공부할 필요가 없다.(원한다면 해도 된다. 말리지 않음 ^^)

UploadPostHelper Class (Language : java)
package {

    import flash.events.*;
    import flash.net.*;
    import flash.utils.ByteArray;
    import flash.utils.Endian;

    /**
     * Take a fileName, byteArray, and parameters object as input and return ByteArray post data suitable for a UrlRequest as output
     *
     * @see http://marstonstudio.com/?p=36
     * @see http://www.w3.org/TR/html4/interact/forms.html
     * @see http://www.jooce.com/blog/?p=143
     * @see http://www.jooce.com/blog/wp%2Dcontent/uploads/2007/06/uploadFile.txt
     * @see http://blog.je2050.de/2006/05/01/save-bytearray-to-file-with-php/
     *
     * @author Jonathan Marston
     * @version 2007.08.19
     *
     * This work is licensed under a Creative Commons Attribution NonCommercial ShareAlike 3.0 License.
     * @see http://creativecommons.org/licenses/by-nc-sa/3.0/
     *
     */

    public class UploadPostHelper {

        /**
         * Boundary used to break up different parts of the http POST body
         */

        private static var _boundary:String = "";

        /**
         * Get the boundary for the post.
         * Must be passed as part of the contentType of the UrlRequest
         */

        public static function getBoundary():String {

            if(_boundary.length == 0) {
                for (var i:int = 0; i < 0x20; i++ ) {
                    _boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
                }
            }

            return _boundary;
        }

        /**
         * Create post data to send in a UrlRequest
         */

        public static function getPostData(fileName:String, byteArray:ByteArray, parameters:Object = null):ByteArray {

            var i: int;
            var bytes:String;

            var postData:ByteArray = new ByteArray();
            postData.endian = Endian.BIG_ENDIAN;

            //add Filename to parameters
            if(parameters == null) {
                parameters = new Object();
            }
            parameters.Filename = fileName;

            //add parameters to postData
            for(var name:String in parameters) {
                postData = BOUNDARY(postData);
                postData = LINEBREAK(postData);
                bytes = 'Content-Disposition: form-data; name="' + name + '"';
                for ( i = 0; i < bytes.length; i++ ) {
                    postData.writeByte( bytes.charCodeAt(i) );
                }
                postData = LINEBREAK(postData);
                postData = LINEBREAK(postData);
                postData.writeUTFBytes(parameters[name]);
                postData = LINEBREAK(postData);
            }

            //add Filedata to postData
            postData = BOUNDARY(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Disposition: form-data; name="Filedata"; filename="';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData.writeUTFBytes(fileName);
            postData = QUOTATIONMARK(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Type: application/octet-stream';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);
            postData = LINEBREAK(postData);
            postData.writeBytes(byteArray, 0, byteArray.length);
            postData = LINEBREAK(postData);

            //add upload filed to postData
            postData = LINEBREAK(postData);
            postData = BOUNDARY(postData);
            postData = LINEBREAK(postData);
            bytes = 'Content-Disposition: form-data; name="Upload"';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);
            postData = LINEBREAK(postData);
            bytes = 'Submit Query';
            for ( i = 0; i < bytes.length; i++ ) {
                postData.writeByte( bytes.charCodeAt(i) );
            }
            postData = LINEBREAK(postData);

            //closing boundary
            postData = BOUNDARY(postData);
            postData = DOUBLEDASH(postData);

            return postData;
        }

        /**
         * Add a boundary to the PostData with leading doubledash
         */

        private static function BOUNDARY(p:ByteArray):ByteArray {
            var l:int = UploadPostHelper.getBoundary().length;

            p = DOUBLEDASH(p);
            for (var i:int = 0; i < l; i++ ) {
                p.writeByte( _boundary.charCodeAt( i ) );
            }
            return p;
        }

        /**
         * Add one linebreak
         */

        private static function LINEBREAK(p:ByteArray):ByteArray {
            p.writeShort(0x0d0a);
            return p;
        }

        /**
         * Add quotation mark
         */

        private static function QUOTATIONMARK(p:ByteArray):ByteArray {
            p.writeByte(0x22);
            return p;
        }

        /**
         * Add Double Dash
         */

        private static function DOUBLEDASH(p:ByteArray):ByteArray {
            p.writeShort(0x2d2d);
            return p;
        }

    }
}



한가지 중요한 정보를 언급하겠다.
URLLoader를 이용해 서버에 전송할때, 프로그램이 같은 도메인상에 있는 경우에는 보안문제가 없다. 하지만 다른 도메인에 위치한 서버로 이미지를 전송할때는 반드시 crossdomain.xml을 check해야한다.

1. Security.loadPolicyFile(http://다른도메인/crossdomain.xml); 를 URLLoader의 load()함수를 호출하기 전에 호출한다.

2. Flash Player 9.0.124.0 버전부터는 HTTP Header 보안취약점을 해결하기 위해서 cross domain 정책이 변경되었는데.... 서버측에 있는 crossdomain.xml에 allow-http-request-headers-from가 추가되어져야 한다. 이것은 HTTP 헤더 전송을 허용할지 결정해준다.

crossdomain.xml (Language : xml)
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
      <allow-access-from domain="*.jidolstar.com" />
      <allow-http-request-headers-from domain="*.jidolstar.com" headers="*"/>
</cross-domain-policy>

위 처럼 서버측 crossdomain.xml에 allow-http-request-headers-from을 추가함으로 다른 도메인간에 HTTP 헤더 전송을 허용할 수 있다.

서로 다른 도메인에 SWF와 서버측 코드가 배치되어 있다면 반드시 이 사실을 숙지하길 바란다.


3. Flash Player 10에서는 사용자 인터렉션이 반드시 필요하다.

다음글을 참고하세요.

http://blog.jidolstar.com/411 


 

4. 서버측 코드 작성

만약 위 3번 코드에서 var parameters:URLVariables를 아래와 같이 작성했다고 하자.

URLVariables 설정 (Language : java)
var parameters:URLVariables = new URLVariables();
parameters.method = "id";
parameters.userId = "2000321";


그럼 PHP 코드로 아래와 같은 방법처럼 만들면 되겠다.(테스트는 안해봤음)

PHP 코드 예제 (Language : php)
<?php
$method = $_POST['method'];
$userId = $_POST['userId'];
$file_temp = $_FILES['Filedata']['tmp_name'];
$file_name = $_FILES['Filedata']['name'];
$file_size = $_FILES['Filedata']['size'];

if( $method == "id" )
{
  $movePath = "/home/myPath/images/$userId_$file_name";
}
else
{
  $movePath = "/home/myPath/images/time_".time()."_".$file_name;
}

move_uploaded_file($file_temp,$movePath);

echo "save Complete";
?>


마지막 save Comple 메시지를 받기 위해서는 Flex의 Complete 이벤트 발생시 아래와 같은 방법으로 받으면 되겠다. 이것을 알아내는데도 많이 힘들었다. 일종의 팁이다. ^^;

데이타 받기 (Language : java)
var loader:URLLoader = URLLoader(event.target);
var bytedata:ByteArray = loader.data;
var strData:String = bytedata.toString();
trace( strData)


실제 업무에도 잘 이용하고 있다.
이미지 에디터 등을 만들때 아주아주 유용한 자료가 될 것이다.

누가 예제 프로그램 만들어서 트랙백 걸어 주시면 고맙겠다.


자료 출처 
http://marstonstudio.com/2007/08/19/how-to-take-a-snapshot-of-a-flash-movie-and-automatically-upload-the-jpg-to-a-server-in-three-easy-steps/


지돌스타 블로그내 참고자료
 - ImageSnapshot 클래스에 대해 : http://blog.jidolstar.com/301
 - FileReference의 UploadCompleteData 이벤트 : http://blog.jidolstar.com/324
 - 동영상 캡쳐 방법 : http://blog.jidolstar.com/215


 

글쓴이 : 지돌스타(http://blog.jidolstar.com/352)

//DB 생성 파일 위치
    var dbFile : File = File.desktopDirectory.resolvePath("application.db");
    
    //table생성
    var conn:SQLConnection = new SQLConnection(); //DB를 연결합니다..
    conn.open(dbFile);    
    var syntax:String = "CREATE TABLE IF NOT EXISTS testTable (" +
   "no INTEGER PRIMARY KEY AUTOINCREMENT," +
   "title TEXT," +
   "url TEXT" +
   ")";
  sendQuery(conn, syntax);
  
  //스키마 정보 확인
  try {
   conn.loadSchema();
   var schemaResult:SQLSchemaResult = conn.getSchemaResult();
   if (schemaResult) {
    for(var obj:String in schemaResult.tables){
     var table:SQLTableSchema = schemaResult.tables[obj] as SQLTableSchema;
     log("[" + table.name + "] 스키마(Schema)");
     for(var prop:String in table.columns){
      var column:SQLColumnSchema = table.columns[prop] as SQLColumnSchema;
      log("name:" + column.name + ",dataType:" + column.dataType + ",primaryKey:" + column.primaryKey + ",allowNull:" + column.allowNull + ",autoIncrement:" + column.autoIncrement + ",defaultCollationType:" + column.defaultCollationType);
     }
    }
   }
  } catch(e:Error) {
   log("테이블이 없습니다.");
  }
  
  //등록
  syntax = "INSERT INTO testTable (title, url) VALUES ('Adobe AIR Devpia.', 'http://airdev.tistory.com/')"; //no는 자동으로 증가
  sendQuery(conn, syntax);
  syntax = "INSERT INTO testTable (title, url) VALUES ('아폴로케이션[Apollocation]', 'http://cafe.naver.com/apollocation')"; //no는 자동으로 증가
  sendQuery(conn, syntax);
  
  //조회
  var syntax:String = "SELECT * FROM testTable";
  var responder:Responder = new Responder(
   function(e:SQLResult):void {
    var result:Array = e.data;
    var numRows:int = result.length;
    for(var i:int = 0; i < numRows; i++){
     log("필드 번호 :" + i);
     for(var columnName:String in result[i]){
      log(columnName + " :" + result[i][columnName]);
     }
    }
   }
  );
  sendQuery(conn, syntax, -1, responder);
  
  //DB 삭제
  syntax = "DROP TABLE testTable";
  sendQuery(conn, syntax);


private function sendQuery(conn:SQLConnection, syntax:String, prefetch:int=-1, responder:Responder=null):void { //쿼리 실행
  var stm:SQLStatement = new SQLStatement();
  stm.sqlConnection = conn;
  stm.text = syntax;
  stm.execute(prefetch, responder); //prefetch : 가져올 데이터 개수(-1이면 모두), responder : 결과, 상태 Responder
 }


EHCache를 이용한 기본적인 캐시 구현 방법 및 분산 캐시 구현 방법을 살펴본다.

EHCache의 주요 특징 및 기본 사용법

게시판이나 블로그 등 웹 기반의 어플리케이션은 최근에 사용된 데이터가 또 다시 사용되는 경향을 갖고 있다. 80:20 법칙에 따라 20%의 데이터가 전체 조회 건수의 80%를 차지할 경우 캐시를 사용함으로써 성능을 대폭적으로 향상시킬 수 있을 것이다.

본 글에서는 캐시 엔진 중의 하나인 EHCache의 사용방법을 살펴보고, Gaia 시스템에서 EHCache를 어떻게 사용했는 지 살펴보도록 하겠다.

EHCache의 주요 특징

EHCache의 주요 특징은 다음과 같다.

  • 경량의 빠른 캐시 엔진
  • 확장(scable) - 메모리 & 디스크 저장 지원, 멀티 CPU의 동시 접근에 튜닝
  • 분산 지원 - 동기/비동기 복사, 피어(peer) 자동 발견
  • 높은 품질 - Hibernate, Confluence, Spring 등에서 사용되고 있으며, Gaia 컴포넌트에서도 EHCache를 사용하여 캐시를 구현하였다.
기본 사용법

EHCache를 사용하기 위해서는 다음과 같은 작업이 필요하다.

  1. EHCache 설치
  2. 캐시 설정 파일 작성
  3. CacheManager 생성
  4. CacheManager로부터 구한 Cache를 이용한 CRUD 작업 수행
  5. CacheManager의 종료
EHCache 설치

EHCache 배포판은 http://ehcache.sourceforge.net/ 사이트에 다운로드 받을 수 있다. 배포판의 압축을 푼 뒤, ehcache-1.2.x.jar 파일이 생성되는 데, 이 파일을 클래스패스에 추가해준다. 또한, EHCache는 자카르타의 commons-logging API를 사용하므로, commons-logging과 관련된 jar 파일을 클래스패스에 추가해주어야 한다.

ehcache.xml 파일

EHCache는 기본적으로 클래스패스에 존재하는 ehcache.xml 파일로부터 설정 파일을 로딩한다. 가장 간단한 ehcache.xml 파일은 다음과 같이 작성할 수 있다.

<ehcache>
    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
    
    <cache name="simpleBeanCache"
            maxElementsInMemory="10"
            eternal="false"
            overflowToDisk="false"
            timeToIdleSeconds="300"
            timeToLiveSeconds="600"
            memoryStoreEvictionPolicy="LRU" />

</ehcache>

위 코드에서 <defaultCache> 태그는 반드시 존재해야 하는 태그로서, 코드에서 캐시를 직접 생성할 때 사용되는 캐시의 기본 설정값을 저장한다. <cache> 태그는 하나의 캐시를 지정할 때 사용된다. name 속성은 캐시의 이름을 지정하며, 코드에서는 이 캐시의 이름을 사용하여 사용할 Cache 인스턴스를 구한다.

설정 파일에 대한 자세한 내용은 뒤에서 살펴보기로 하자.

CacheManager 생성

ehcache.xml 파일을 작성했다면 그 다음으로 할 작업은 net.sf.ehcache.CacheManager 객체를 생성하는 것이다. CacheManager 객체는 다음의 두 가지 방법 중 한가지 방식을 사용하여 생성할 수 있다.

  • CacheManager.create() : 싱글톤 인스턴스 사용
  • new CacheManager() : 새로운 CacheManager 인스턴스 생성
CacheManager.create() 메소드는 싱글톤 인스턴스를 생성하기 때문에 최초에 한번 호출될 때에만 CacheManager의 초기화 작업이 수행되며, 이후에는 동일한 CacheManager 인스턴스를 리턴하게 된다. 아래는 CacheManager.create() 메소드의 사용 예이다.

CacheManager cacheManager = CacheManager.create();

싱글톤 인스턴스가 아닌 직접 CacheManager 객체를 조작하려면 다음과 같이 new를 사용하여 CacheManager 인스턴스를 생성해주면 된다.

CacheManager cacheManager = new CacheManager();

두 방식 모두 클래스패스에 위치한 ehcache.xml 파일로부터 캐시 설정 정보를 로딩한다.

만약 클래스패스에 위치한 ehcache.xml 파일이 아닌 다른 설정 파일을 사용하고 싶다면 다음과 같이 URL, InputStream, 또는 String(경로) 객체를 사용하여 설정 파일의 위치를 지정할 수 있다.

URL configFile = this.getClass().getResource("/ehcache_config_replicate.xml")
CacheManager cacheManager = new CacheManager(configFile);

Cache에 CRUD 수행

CacheManager 인스턴스를 생성한 다음에는 CacheManager 인스턴스로부터 Cache 인스턴스를 구하고, Cache 인스턴스를 사용하여 객체에 대한 캐시 작업을 수행할 수 있게 된다.

Cache 구하기
net.sf.ehcache.Cache 인스턴스는 CacheManager.getCache() 메소드를 사용하여 구할 수 있다.

CacheManager cacheManager = new CacheManager(configFileURL);
Cache cache = cacheManager.getCache("simpleBeanCache");

CacheManager.getCache() 메소드에 전달되는 파라미터는 ehcache.xml 설정 파일에서 <cache> 태그의 name 속성에 명시한 캐시의 이름을 의미한다. 지정한 이름의 Cache 인스턴스가 존재하지 않을 경우 CacheManager.getCache() 메소드는 null을 리턴한다.

Create/Update 작업 수행
Cache 인스턴스를 구한 다음에는 Cache.put() 메소드를 사용하여 캐시에 객체를 저장할 수 있다. 아래 코드는 Cache.put() 메소드의 사용예이다.

Cache cache = cacheManager.getCache("simpleBeanCache");

SimpleBean newBean = new SimpleBean(id, name);
Element newElement = new Element(newBean.getId(), newBean);
cache.put(newElement);

Cache.put() 메소드는 net.sf.ehcache.Element 객체를 전달받는다. Element 클래스는 캐시에 저장될 원소를 나타내며, 키와 값을 사용하여 원소를 표현한다. Element 객체를 생성할 때 첫번째 파라미터는 원소의 키를 의미하며, 두번째 파라미터는 원소의 값을 의미한다.

EHCache는 캐시에 저장될 각각의 객체들을 키를 사용하여 구분하기 때문에, Element 객체를 생성할 때 (의미상) 서로 다른 객체는 서로 다른 키를 사용해야 한다.

Map과 마찬가지로 EHCache가 제공하는 Cache는 삽입을 하거나 기존의 값을 수정할 때 모두 Cache.put() 메소드를 사용한다. 기존에 캐시에 저장된 객체를 수정하길 원한다면 다음과 같이 동일한 키를 사용하는 Element 객체를 Cache.put() 메소드에 전달해주면 된다.

Element newElement = new Element(id, someBean);
cache.put(newElement);
...
Element updatedElement = new Element(id, updatedBean);
cache.put(updatedElement);

Read 작업 수행
Cache에 보관된 객체를 사용하려면 Cache.get() 메소드를 사용하면 된다. Cache.get() 메소드는 키를 파라미터로 전달받으며, 키에 해당하는 Element 객체를 리턴하며 관련 Element과 존재하지 않을 경우 null을 리턴한다. 아래 코드는 Cache.get() 메소드의 사용예이다.

Element element = cache.get(key);
SimpleBean bean = (SimpleBean) element.getValue();

Element.getValue() 메소드는 캐시에 저장된 객체를 리턴한다. 만약 Serializable 하지 않은 객체를 값으로 저장했다면 다음과 같이 Element.getObejectValue() 메소드를 사용하여 값을 구해야 한다.

Element element = cache.get(key);
NonSerializableBean bean = (NonSerializableBean) element.getObjectValue();

Delete 작업 수행
Cache에 보관된 객체를 삭제하려면 Cache.remove() 메소드를 사용하면 된다. 아래 코드는 Cache.remove() 메소드의 사용예이다.

boolean deleted = cache.remove(key);

Cache.remove() 메소드는 키에 해당하는 객체가 존재하여 삭제한 경우 true를 리턴하고, 존재하지 않은 경우 false를 리턴한다.

CacheManager의 종료

사용이 종료된 CacheManager는 다음과 같이 shutdown() 메소드를 호출하여 CacheManager를 종료해야 한다.

cacheManager.shutdown();

Cache 값 객체 사용시 주의사항

캐시에 저장되는 객체는 레퍼런스가 저장된다. 따라서, 동일한 키에 대해 Cache.put()에 전달한 Element의 값과Cache.get()으로 구한 Element의 값은 동일한 객체를 참조하게 된다.

SimpleBean bean = ...;
Element element = new Element(key, bean);
cache.put(element);

Element elementFromCache = cache.get(key);
SimpleBean beanFromCache = (SimpleBean)elementFromCache.getValue();

(bean == beanFromCache); // true
(element == elementFromCache); // false

위 코드에서 Cache.put()에 전달된 element 객체와 Cache.get()으로 구한 elementFromCache 객체는 서로 다른 객체이다. 하지만, 두 Element 객체가 갖고 있는 값은 동일한 객체를 참조하고 있다. 따라서, 캐시에 값으로 저장된 객체를 변경하게 되면 캐시에 저장된 내용도 변경되므로, 캐시 사용시 이 점에 유의해야 한다.

캐시 설정

캐시 설정 파일에 <cache> 태그를 이용하여 캐시를 설정했었다. 캐시 설정과 관련하여 <cache> 태그는 다양한 속성을 제공하고 있는데, 이들 속성에는 다음과 같은 것들이 존재한다.

name 캐시의 이름 필수
maxElementsInMemory 메모리에 저장될 수 있는 객체의 최대 개수 필수
eternal 이 값이 true이면 timeout 관련 설정은 무시되고, Element가 캐시에서 삭제되지 않는다. 필수
overflowToDisk 메모리에 저장된 객체 개수가 maxElementsInMemory에서 지정한 값에 다다를 경우 디스크에 오버플로우 되는 객체는 저장할 지의 여부를 지정한다. 필수
timeToIdleSeconds Element가 지정한 시간 동안 사용(조회)되지 않으면 캐시에서 제거된다. 이 값이 0인 경우 조회 관련 만료 시간을 지정하지 않는다. 기본값은 0이다. 선택
timeToLiveSeconds Element가 존재하는 시간. 이 시간이 지나면 캐시에서 제거된다. 이 시간이 0이면 만료 시간을 지정하지 않는다. 기본값은 0이다. 선택
diskPersistent VM이 재 가동할 때 디스크 저장소에 캐싱된 객체를 저장할지의 여부를 지정한다. 기본값은 false이다. 선택
diskExpiryThreadIntervalSeconds Disk Expiry 쓰레드의 수행 시간 간격을 초 단위로 지정한다. 기본값은 120 이다. 선택
memoryStoreEvictionPolicy 객체의 개수가 maxElementsInMemory에 도달했을 때,모메리에서 객체를 어떻게 제거할 지에 대한 정책을 지정한다. 기본값은 LRU이다. FIFO와 LFU도 지정할 수 있다. 선택

아래 코드는 몇 가지 설정 예이다.

<!--
sampleCache1 캐시. 최대 10000개의 객체를 저장할 수 있으며, 
5분 이상 사용되지 않거나 또는 10분 이상 캐시에 저장되어 있을 경우 
캐시에서 제거된다. 저장되는 객체가 10000개를 넘길 경우, 
디스크 캐시에 저장한다.
-->
<cache name="sampleCache1"
       maxElementsInMemory="10000"
       maxElementsOnDisk="1000"
       eternal="false"
       overflowToDisk="true"
       timeToIdleSeconds="300"
       timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LFU"
       />

<!--
sampleCache2 캐시. 최대 1000개의 객체를 저장한다. 
오버플로우 된 객체를 디스크에 저장하지 않기 때문에 
캐시에 최대 개수는 1000개이다. eternal이 true 이므로, 
timeToLiveSeconds와 timeToIdleSeconds 값은 무시된다.
-->
<cache name="sampleCache2"
       maxElementsInMemory="1000"
       eternal="true"
       overflowToDisk="false"
       memoryStoreEvictionPolicy="FIFO"
       />

<!--
sampleCache3 캐시. 오버플로우 되는 객체를 디스크에 저장한다.
디스크에 저장된 객체는 VM이 재가동할 때 다시 캐시로 로딩된다.
디스크 유효성 검사 쓰레드는 10분 간격으로 수행된다.
-->
<cache name="sampleCache3"
       maxElementsInMemory="500"
       eternal="false"
       overflowToDisk="true"
       timeToIdleSeconds="300"
       timeToLiveSeconds="600"
       diskPersistent="true"
       diskExpiryThreadIntervalSeconds="600"
       memoryStoreEvictionPolicy="LFU"
       />

분산 캐시

EHCache는 분산 캐시를 지원한다. EHCache는 피어(peer) 자동 발견 및 RMI를 이용한 클러스터간 데이터 전송의 신뢰성 등 분산 캐시를 위한 완전한 기능을 제공하고 있다. 또한, 다양한 옵션을 통해 분산 상황에 맞게 설정할 수 있도록 하고 있다.

참고로, EHCache는 RMI를 이용하여 분산 캐시를 구현하고 있기 때문에, Serializable 한 객체만 분산 캐시에서 사용 가능하다. 키 역시 Serializable 해야 한다.

분산 캐시 구현 방식

EHCache는 한 노드의 캐시에 변화가 생기면 나머지 노드에 그 변경 내용을 전달하는 방식을 사용한다. 즉, 클러스터에 있는 캐시 인스턴스가 n개인 경우, 한번의 변경에 대해 n-1개의 변경 통지가 발생한다.

각 노드의 캐시간 데이터 전송은 RMI를 통해서 이루어진다. EHCache가 데이터 전송 기술로서 RMI를 사용하는 이유는 다음과 같다.

  • 자바에서 기본적으로 제공하는 원격 메커니즘
  • 안정화된 기술
  • TCP 소켓 옵션을 튜닝할 수 있음
  • Serializable 한 객체를 지원하기 때문에, 데이터 전송을 위해 XML과 같은 별도의 포맷으로 변경할 필요가 없음
노드 발견

EHCache는 클러스터에 새로운 노드가 추가돌 경우 해당 노드를 자동적으로 발견하는 방식과, 지정된 노드 목록에 대해서만 클러스터의 노드로 사용하는 방식을 지원하고 있다.

멀티캐스트 방식

멀티캐스트 모드를 사용한 경우, 지정한 멀티캐스트 IP(224.0.0.1~239.255.255.255)와 포트에 참여하는 노드를 자동으로 발견하게 된다. 지정한 IP와 포트에 참여한 노드는 자기 자신을 다른 노드에 통지한다. 이 방식을 사용하면 클러스터에 동적으로 노드를 추가하거나 제거할 수 있다.

노드 목록 지정 방식

클러스터에 포함되는 노드 목록을 지정한다. 동적으로 새로운 노드를 추가하거나 기존 노드를 제거할 수 없다.

분산 캐시 설정

분산 캐시를 사용하기 위해서는 다음과 같은 세 개의 정보를 지정해주어야 한다.

  • CacheManagerPeerProvider - 피어 발견 관련 설정
  • CacheManagerPeerListener - 메시지 수신 관련 설정
  • 캐시별 CacheReplicator - 메시지 생성 규칙 설정
CacheManagerPeerProvider 설정

CacheManagerPeerProvider는 새롭게 추가된 노드를 발견하는 방식을 지정한다.

노드를 자동으로 발견하는 멀티캐스트 방식을 사용하려면 다음과 같이 설정한다.

<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=automatic, 
                    multicastGroupAddress=230.0.0.100, multicastGroupPort=1234" />

위 코드에서 properties 속성의 값에 사용된 프로퍼티는 다음과 같다.

peerDiscovery automatic으로 지정하면 멀티캐스트 방식을 사용한다.
multicaseGroupAddress 멀티캐스트 IP
multicaseGroupPort 포트 번호

하나의 클러스터에 포함될 노드들은 동일한 멀티캐스트 IP와 포트 번호를 사용해야 한다.

클러스터에 참여할 노드 목록을 지정하는 IP 방식을 사용하려면 다음과 같이 설정한다.

<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual, 
                    rmiUrls=//server2:12345/cache1|//server2:12345/cache2" />

위 코드에서 properties 속성의 값에 사용된 프로퍼티는 다음과 같다.

peerDiscovery manual로 지정한 IP 지정 방식이다.
rmiUrls 분산 노드에 참여할 서버 및 캐시 목록을 지정한다. 현재 노드의 정보는 포함시켜서는 안 된다.

이 경우, rmiUrls에 명시된 포트 번호는 뒤에 살펴볼 CacheManagerPeerListener가 사용할 포트 번호를 지정해주어야 한다.

CacheManagerPeerListener 설정

노드를 발견하는 방식을 지정했다면, 다음으로 할 작업은 클러스터에 있는 다른 노드에서 발생한 변경 정보를 수신할 때 사용할 포트 번호를 지정하는 것이다. 다음과 같은 코드를 이용하여 수신과 관련된 포트 번호를 설정할 수 있다.

<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="port=12345, socketTimeoutMillis=120000" />

위 코드에서 properties 속성의 값에 사용된 프로퍼티는 다음과 같다.

port 메시지를 수신할 때 사용되는 포트
socketTimeoutMillis 이 노드에 메시지를 보냈을 때 메시지 전송을 기다리는 시간. 기본값은 2000ms.

캐시별 CacheReplicator 설정

분산 환경에 적용되어야 하는 캐시는 캐시의 내용이 변경되었을 때 다른 노드에 있는 캐시에 변경 내역을 알려주어야 한다. <cacheEventListenerFactory> 태그를 사용하면, 언제 어떻게 캐시의 변경 내역을 통지할지의 여부를 지정할 수 있다. 아래 코드는 설정의 예이다.

<cache name="simpleBean"
      maxElementsInMemory="100"
      eternal="false"
      overflowToDisk="false"
      timeToIdleSeconds="300"
      timeToLiveSeconds="600"
      memoryStoreEvictionPolicy="LRU">
       <cacheEventListenerFactory 
           class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" 
           properties="replicateUpdatesViaCopy=true,replicateUpdates=true" />
</cache>

위 코드와 같이 <cacheEventListenerFactory>의 구현 클래스로 RMICacheReplicatorFactory를 지정하면 캐시에 변경이 생길 때 마다 해당 변경 내역을 클러스터에 참여하고 있는 노드의 캐시에 통지하게 된다. properties 속성에 프로퍼티를 지정하면, 캐시 요소의 추가, 변경, 삭제 등에 대해 통지 방식을 적용할 수 있다. 설정할 수 있는 프로퍼티는 다음과 같다.

replicatePuts 캐시에 새로운 요소가 추가됐을 때 다른 노드에 복사할지의 여부
replicateUpdates 캐시 요소의 값이 변경되었을 때 다른 노드에 값을 복사할지의 여부
replicateRemovals 캐시 요소가 삭제되었을 때 다른 노드에 반영할지의 여부
replicateAsynchronously 비동기로 값을 복사할지의 여부
replicateUpdatesViaCopy 새로운 요소를 다른 노드에 복사할 지 아니면 삭제 메시지를 보낼지의 여부
asynchronousReplicationIntervalMillis 비동기 방식을 사용할 때 변경 내역을 다른 노드에 통지하는 주기. 기본값은 1000.

위 속성의 기본값은 모두 true이다. 따라서, 기본 설정값을 사용하려면 다음과 같이 properties 속성을 사용하지 않아도 된다.

<cache name="simpleBean" ...
      memoryStoreEvictionPolicy="LRU">
       <cacheEventListenerFactory 
           class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>

어플리케이션 구동시 캐시 데이터 로딩하기

CacheManager가 초기화 될 때, 클러스터에 있는 다른 캐시로부터 데이터를 로딩할 수 있다. 이는 초기 구동이 완료된 후 곧 바로 서비스를 제공할 수 있음을 의미한다. 초기 구동시 다른 노드로부터 캐시 데이터를 로딩하려면 다음과 같이 <bootstrapCacheLoaderFactory> 태그의 구현 클래스를 RMIBootstrapCacheLoaderFactory로 지정해주면 된다.

<cache name="simpleBean" ...
      memoryStoreEvictionPolicy="LRU">
       <bootstrapCacheLoaderFactory
           class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
           properties="bootstrapAsynchronously=true,
                       maximumChunkSizeBytes=5000000" />

       <cacheEventListenerFactory 
           class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
</cache>

RMIBootstrapCacheLoaderFactory에 전달 가능한 프로퍼티 목록은 다음과 같다.

bootstrapAsynchronously 비동기적으로 수행할지의 여부를 지정
maximumChunkSizeBytes 클러스터의 다른 노드로부터 로딩 가능한 데이터의 최대 크기

RMIBoostrapCacheLoaderFactory를 설정하면 캐시를 초기화 할 때, 원격지 노드의 캐시에 저장된 데이터를 로딩하여 로컬 캐시에 저장한다.

분산 캐시 고려사항

분산 캐시를 사용할 때에는 다음과 같은 내용을 고려해야 한다.

  • 노드 증가에 따라 네트워크 트래픽 증가:
    많은 양의 네트워크 트래픽이 발생할 수 있다. 특히 동기 모드인 경우 성능에 영향을 받을 수 있다. 비동기 모드인 경우 버퍼에 변경 내역을 저장하였다가 일정한 주기로 버퍼에 쌓인 내역을 다른 노드에 통지하기 때문에 이 문제를 다소 완하시킬 수 있다.
  • 데이터 불일치 발생 가능성:
    두 노드에서 동시에 동일한 캐시의 동일한 데이터에 대한 변경을 수행할 경우, 두 노드 사이에 데이터 불일치가 발생할 수 있다. 캐시 데이터의 불일치가 매우 심각한 문제가 될 경우, 동기 모드(replicateAsynchronously=false)와 복사 메시지 대신 삭제 메시지를 전송(replicateUpdatesViaCopy=false)함으로써 이 문제를 해결할 수 있다.
관련링크:

참조 : http://javacan.tistory.com/123


annotation으로 javaBean의 중북되고 반복되는 코드를 한결 편리하게 사용할 수 있는 유틸이 있네요.
getter, setter, toString, hasCode등과 같이 bean을 만들때 매번 불편하고 가독성 없이 추가만 해주었는데
이 유틸리티를 사용하면 이런 불편함이 많이 줄어들것으로 생각이 됩니다.
딱히 javaBean이 아니라 다른곳에서도 유용하게 사용하실 수 있습니다.
사용법및 설치법은 다른 여러가지 방법으로도 사용을 할 수 있다고 하나 이클립스에서 설정하는 법을 설명하겠습니다.

다운로드 : http://projectlombok.org/
설치방법 : 해당 사이트에서 lombok.jar 파일을 다운받은 후 console에서 다운로드 경로로 이동한 다음 
java -jar lombok.jar 명령을 입력하게 되면 GUI 창이 노출이 됩니다. 해당 창이 노출이 되면 eclipse 파일의 경로를 지정하고
install/update 버튼을 선택하기면 하면 설치가 끝납니다.

사용방법 : http://www.ibm.com/developerworks/kr/library/os-lombok/index.html

# 버전별 MySQL user , db , database 생성하기
mysql 버전에 따라서 레코드 숫자가 틀려서 생성 할 때 마다 귀찮은 점이 있다.
적어 두고 생성시 복사해서 사용하는게 편리 하다.
반드시 ID , NAME , DATABASE 이름을 변경하여 사용하시기 바랍니다. 

MySQL 3

create database 데이타베이스명;
insert into user values ('localhost','아이디',password('비밀번호'),'N','N','N','N','N','N','N','N','N','Y','N','N','N','N');
insert into db values ('localhost','아이디','디비이름','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
flush privileges;


MySQL 4

create database 데이타베이스명;
insert into user values ('localhost','아이디',password('비밀번호'),'N','N','N','N','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','N','N','','blob','blob','blob','0','0','0');
insert into db values ('localhost','아이디','디비이름','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
flush privileges;


MySQL 5

create database 데이타베이스명;
insert into user values ('localhost','아이디',password('비밀번호'),'N','N','N','N','N','N','N','N','N','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','','blob','blob','blob','0','0','0','0');
insert into db values ('localhost','아이디','디비이름','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
flush privileges;

 


커스텀 설정은 다음과 같은 명령어로 필드 값을 본뒤에 수정 하여 사용할 수 있습니다.
desc user;
desc db;
모든 작업 후 반드시 flush privileges; 로 적용합니다. (모든 작업은 가상으로 작업 된 뒤 적용 시점에 작동 됩니다.)
 

MySQL 데이타 베이스, 삭제하기
      내용 delete from user where user='해당유저이름';
delete from db where db='해당디비이름';
flush privileges; (적용)


사용자 추가

MYSQL에서 유저를 추가하는 방법은 두가지가 있습니다.
일반적으로는 유저를 위한 전용 데이터베이스를 하나 생성해 주고, 해당 데이터베이스에 접속할 권한을 주게 됩니다.
이 때 권한은 local에서만 접속할 권한을 주거나, JDBC등을 이용한다면 외부에서도 접속할 권한을 주어야 합니다.

0.. CREATE DATABASE 명령을 이용한  데이터베이스 신규 생성
1. CREATE USER와 GRANT 명령어 사용 (또는)
2. INSERT, UPDATE, DELETE를 사용해서 직접 관리 테이블을 수정하기를 통한 추가

기존 글을 찾아보면 2번의 내용이 많지만 전문가가 아니라면 개인적으로는 쉬운 1번을 추천합니다. 



먼저 root 유저로 로그인합니다. 암호가 없을 경우 
c:\mysql\bin> mysql -u root mysql

암호가 존재할 경우
c:\mysql\bin> mysql -u root  mysql -p

mysql에 접속한 후에 유저가 사용할 데이터 베이스를 만듭니다. 데이터베이스 명은 ps3_psn 으로 합니다.
mysql> create database ps3_psn; 

먼저 ryu라는 유저를 생성합니다. 암호는 ssf4로 하겠습니다.
mysql> create user 'ryu'@'localhost'  identified by 'ssf4';

ryu 유저에게 ps3_psn 데이터베이스를 로컬에서만 접속할 수 있게 권한을 줍니다.
mysql> GRANT ALL PRIVILEGES ON ps3psn.* TO 'ryu'@'localhost'
    ->     WITH GRANT OPTION;

ryu 유저에게 모든 데이터베이스를 로컬에서 접속할 권합을 준다면
mysql> GRANT ALL PRIVILEGES ON *.* TO 'ryu'@'localhost'

ryu 유저에게 ps3_psn  데이터베이스에 원격에서도 접속할 권한을 줍니다. JDBC 등에서 사용하려면 이런 식으로 합니다.
mysql> GRANT ALL PRIVILEGES ON ps3_psn.* TO 'ryu'@'%'    ->
    WITH GRANT OPTION;

접속권한 보기
mysql> SHOW GRANTS FOR 'ryu'@'localhost';



유저 생성하고 권한 부여하기


1. test 유저를 생성하고 testdb라는 데이터베이스에 모든 권한 부여하기(단, 이 유저는 localhost 에서만 접근 가능하며 접근을 위해서 패스워드 필요)

mysql> grant all privileges on testdb.* to test@localhost identified by '패스워드';



2. test 유저는 모든 호스트에서 testdb에 접근 할 수 있지만 select, insert 권한만 가진다.

mysql> grant select, insert on testdb.* to test@'%' identified by '패스워드';


 3. test 유저는 192.168.0으로 시작하는 모든 컴퓨터에서 접근 가능하며 모든 DB에 모든 권한을 가진다.

mysql> grant all privileges on *.* to test@'192.168.0.%' identified by '패스워드';



 

[출처] http://blog.naver.com/forspeed4?Redirect=Log&logNo=130037742496
[출처] http://k502000.blog.me/30097017893
[출처] http://blog.omyworld.co.kr/entry/Mysql-user-생성-및-권한-부여

타입1.

$.ajax({
  type: "GET",
  url: "test.js",
  dataType: "script"
});

기본형을 보시면 ajax() 라는 메서드안에 속성 3개를 가진 객체를 생성한후 인자로 때려넣고 있군요.
동적으로 js파일을 로드해서 실행시키는 기능을합니다. 기능이 재밌어 보이긴하는데, 실제로 별로 안쓸것같네요 -_-;


타입2.

 $.ajax({
   type: "POST",
   url: "some.php",
   data: "name=John&location=Boston",
   success: function(msg){
     alert( "Data Saved: " + msg );
   }
});
some.php 에 POST 타입으로 name 과 location 을 parameter 로 넘기고있네요. success 프라퍼티는 서버에서 http response 를 받은후에 수행될 콜백함수를 지정합니다. "데이타가 저장되었어염" 라고 알려주네요.
갠적으로 이 타입을 가장많이 사용하고있습니다. 실무에서도 가장많이 사용되죠.

타입3.
$.ajax({
  url: "test.html",
  cache: false,
  success: function(html){
    $("#results").append(html);
  }
});
cache 라는 프라퍼티가 추가되었군요. test.html 을 가장 최근에 수정된 페이지로 받겠다는거죠.
"캐쉬를 사용하지 않겠다" 이겁니다. html 을 받은후에 results라는 아이디를 가진 엘리먼트의 자식노드로써 추가하고있네요. 쌩 dom api 로 쓰면 이렇겠죠. document.getElementById("results").innerHTML = html;
음 근데 이거랑은 좀 차이점이있어요. append 는 "result 엘리먼트의 자식이 존재할경우, 가장 마지막 자식으로 붙인다" 라는 규칙을 가지고있거든요. 반면에 innerHTML 으로넣으면 자식이 존재하든안하든 덮어써버리는거죠. 기존의 html 엘리먼트는 사라지고 새로운 엘리먼트로 교체되는 개념입니다.

타입4.
 var html = $.ajax({
  url: "some.php",
  async: false
}).responseText;
async(비동기) 라는 프라퍼티가 추가되었군요. false를 때려넣었으니까 "동기"로 요청한다는말이네요.
뭔말이냐면, some.php로 request를 날린후에 response가 오기전까지는 브라우저를 블락킹 시켜버립니다.
유저의 어떠한 인터렉션도 허용되지않죠. 보시면 콜백함수를 때려넣는 success라는 프라퍼티도없네요
그럼 어떻게 응답데이타를 받나염? 바로 저렇게요. var html = $.ajax().responseText;
어차피 서버로부터 response 가 오기전까지는 스크립트수행이 블락되어있으니까 저 코드가 가능한겁니다.
웹플밍을 하다보면 이 타입을 "써야만" 할때가 종종있더군요.

타입 5.
 var xmlDocument = [create xml document];
$.ajax({
   url: "page.php",
   processData: false,
   data: xmlDocument,
   success: handleResponse
});


[출처] http://boast.tistory.com


  • HTML에 JavaScript 삽입
    <script language="javascript">
    JavaScript Statements
    </script>

  • HTML에 JavaScript 코드 파일 삽입
    <script language="javascipt" src="src.js">
    </script>

  • 변수의 대소문자 구분
  • 변수에 포함된 데이터의 형을 지정하지 않고, JavaScript 인터프리터가 변수에 포함된 데이터 형을 추적하고 변환.
  • JavaScript 데이터 형
    • 숫 자 형 : 정수와 부동 소수
    • BOOLEAN : true, false
    • STRING : 작은 따옴표나 큰 따옴표에 들어가 있는 값으로, 특수문자 포맷 사용시에는 '\'와 함께 사용.
    • null : 아무런 값도 없는 것으로, 변수를 초기화 시키거나 어떤 값이나 이벤트를 지울 때 사용됨
    • undefined : 변수만 만들고, 값을 할당하지 않은 상태

  • 유형간의 변환
    • 스트링 피연산자가 비스트링 연산자와 사용된 경우 다른 연산자를 모두 스트링으로 변환
    • BOOLEAN값은 1과 0으로 변환되어 수치 연산을 지원
    • null값은 스트링 연산에 대해서는 "null", 논리 연산에서는 false, 그리고 수치 연산에서는 0으로 각각 변환
    • 변환 함수
      • eval() : 스트링 표현식을 수치값으로 변환하고, 파라미터가 수치형태가 아닌 스트링 값이면 에러 발생
      • parseInt() : 스트링에 포함된 첫번째 정수를 리턴하고, 스트링이 정수로 시작되지 않으면 0을 리턴
      • parseFloat() : 스트링에 포함된 첫번째 부동 소수를 리턴하거나 스트링이 적절한 부동 소수로 시작되지 않으면 0을 리턴
  • 배열 : 값의 시퀀스를 정렬할 수 있는 객체로, JavaScript의 특수형으로 배열 사용 전엔 반드시 선언해야 한다.
    • 배열 선언 예
      arrayName = new Array(arrayLength)
      arrayName = new Array()
      arrayName = new Array(value0,value1, ..., valuen)
  • JavaScript만의 특수 연산자
    • comma(,) 연산자 : 두 표현식을 계산하고, 두 번째 표현식의 값 리턴
    • delete 연산자 : 객체의 프로퍼티나 배열 인덱스의 요소 삭제하고, 항상 undefined 값 리턴
    • new 연산자 : 객체 형의 인스턴스를 만들기 위해 사용
    • typeof 연산자 : 연산자의 형을 식별하는 스트링 값을 리턴
    • void 연산자 : 값을 리턴하지 않는다
  • 지역 변수와 전역 변수 : 함수 안에서만 사용되는 것을 지역 변수라 하고, 프로그램 내에서 사용되는 변수를 전역 변수라 하는 데, 지역 변수 사용시 반드시 var 키워드와 함께 선언해야 함

     

    이벤트 처리!!


  • 이벤트 정의와 사용
    • 이벤트 : 사용자가 웹페이지나 기타 다른 브라우저에 수행한 작업으로 인한 결과
    • 이벤트 처리 : 이벤트로 인해 수행되는 프로세스
    • 이벤트 핸들러 : 프로세스를 수행하는 코드
    • 사용 예 : 사용자가 링크 위로 마우스를 갖다 대면 다이얼로그 박스를 표시한다거나, 폼에 입력한 데이터를 검증한다거나, 버튼을 클릭할 때 애니메이션을 나타내거나, Java 애플릿과 브라우저 플러그인이 상호작용을 하도록 한다.
    HTML 태그 JavaScript 이벤트 설명
    다양 mouseMove 마우스 이동
    <A>..</A> Click 마우스로 링크를 클릭
    dbClick 마우스를 링크위에서 더블클릭
    mouseDown 마우스 버튼을 누름
    mouseUp 마우스 버튼을 놓음
    mouseOver 마우스를 링크위로 이동
    mouseOut 링크 위에 있던 마우스를 링크 밖으로 이동
    keyDown 사용자가 키를 누름
    keyUp 사용자가 키를 놓음
    keyPress 사용자가 키를 눌렀다가 놓음
    <IMG> abort 사용자 액션으로 인해 이미지 로딩 작업을 중단함
    error 이미지 로딩하는 동안 에러 발생
    load 이미지가 로드되고 화면에 나타남
    keyDown 사용자가 키를 누름
    keyUp 사용자가 키를 놓음
    keyPress 사용자가 키를 눌렀다가 놓음
    <AREA> mouseOver 마우스가 클라이언트측 이미지맵의 한 영역으로 이동함
    mouseOut 마우스가 이미지맵 영역 밖으로 이동
    dbClick 사용자가 이미지맵의 한 영역을 더블클릭함
    <BODY>..</BODY> Click 사용자가 문서의 본문을 클릭
    dbClick 문서의 본문을 더블 클릭함
    keyDown 키를 누름
    keyUp 키를 놓음
    keyPress 키를 눌렀다가 놓음
    mouseDown 마우스 버튼을 누름
    mouseUp 마우스 버튼을 놓음
    <BODY>..</BODY>
    <FRAMESET>..</FRAMESET>
    <FRAME>..</FRAME>
    blur 윈도우에서 현재 입력 포커스가 사라짐
    error 윈도우가 로드되는 동안 에러 발생
    focus 입력 포커스가 현재 윈도우로 이동
    load 윈도우 로딩이 완료됨
    unload 윈도우를 종료함
    move 윈도우가 이동됨
    resize 윈도우의 크기가 바뀜
    dragDrop 윈도우에 객체를 드롭
    <FORM>..</FORM> submit 사용자가 폼을 제출
    reset 사용자가 폼을 재설정
    <INPUT TYPE="text"> blur 현재 입력 포커스가 텍스트 필드에서 사라짐
    focus 현재 입력 포커스가 텍스트 필드로 이동
    change 텍스트 필드가 변경되어 현재 입력 포커스가 사라짐
    select 텍스트 필드에 있는 텍스트가 선택됨
    <INPUT TYPE="password"> blur 패스워드 필드에서 입력 포커스가 사라짐
    focus 패스워드 필드에 입력 포커스 생김
    <TEXTAREA>..</TEXTAREA> blur 텍스트 영역이 현재 입력 포커스가 사람짐
    focus 텍스트 영역에 입력 포커스 생김
    change 텍스트 영역이 변경되어 입력 포커스가 사라짐
    select 텍스트 영역에서 텍스트가 선택됨
    keyDown 키를 누름
    keyUp 키를 놓음
    keyPress 키를 눌렀다 놓음
    <INPUT TYPE="button"> Click 버튼이 클릭됨
    blur 입력할 수 없도록 버튼이 흐려짐
    focus 입력할 수 있도록 포커스 생김
    mouseDown 버튼 위에서 왼쪽 마우스 버튼 누름
    mouseUp 버튼 위에서 왼쪽 마우스 버튼 놓음
    <INPUT TYPE="submit"> Click 제출 버튼이 클릭됨
    blur 제출 버튼에서 입력 포커스가 사라짐
    focus 제출 버튼에 입력 포커스 생김
    <INPUT TYPE="reset"> Click 리셋 버튼이 클릭됨
    blur 리셋 버튼에서 포커스가 사라짐
    focus 리셋 버튼에서 포터스가 놓임
    <INPUT TYPE="radio"> Click 라디오 버튼이 클릭
    blur 라디오 버튼에서 입력 포커스가 사라짐
    focus 라디오 버튼에 입력 포커스 생김
    <INPUT TYPE="checkbox"> Click 체크 박스가 클릭
    blur 체크 박스에서 입력 포커스가 사라짐
    focus 체크 박스에 입력 포커스 놓임
    <INPUT TYPE="file"> blur 파일 업로드 폼 요소에서 입력 포커스 사라짐
    change 사용자가 업로드될 파일을 선택
    focus 파일 업로드 폼 요소에 입력 포커스 놓임
    <SELECT>..</SELECT> blur 선택 요소가 현재 입력 포커스 잃음
    change 선택 요소가 변경되어 입력 포커스가 사라짐
    focus 선택 요소에 현재 입력 포커스가 놓임

  • 이벤트 처리 속성

    이벤트핸들링속성 실행되는 상황
    onAbort 이미지를 로딩하는 작업이 사용자의 한 행동으로 인해 취소되었음
    onBlur 문서나 윈도우, 프레임세트, 폼 요소에서 현재 입력 포커스가 사라짐
    onChange 텍스트 필드나 텍스트 영역, 파일 업로드 필드, 선택 항목이 변경되어 현재 입력 포커스가 사라짐
    onClick 링크나 클라이언트측 이미지맵 영역, 폼 요소가 클릭됨
    onDbClick 링크나 클라이언트측 이미지맵 영역, 문서가 더블 클릭됨
    onDragDrop 드래그된 객체가 윈도우나 프레임에 드롭됨
    onError 이미지나 윈도우, 프레임을 로딩하는 동안 에러가 발생함
    onFocus 문서나 윈도우, 프레임 세트, 폼 요소에 입력 포커스 놓임
    onKeyDown 키를 누름
    onKeyPress 키를 눌렀다 놓음
    onKeyUp 키를 놓음
    onLoad 이미지나 문서, 프레임이 로드됨
    onMouseDown 마우스 버튼 누름
    onMouseMove 마우스를 이동함
    onMouseOut 링크나 클라이언트측 이미지맵에서 마우스를 옮김
    onMouseOver 마우스를 링크나 클라이언트측 이미지맵으로 옮김
    onMouseUp 마우스 버튼을 놓음
    onMove 사용자가 윈도우나 프레임을 이동함
    onReset 폼의 리셋 버튼을 클릭하여 폼을 리셋시킴
    onResize 사용자가 윈도우나 프레임의 크기를 조절
    onSelect 텍스트는 텍스트 필드나 영역에서 선택됨
    onSubmit 폼이 제출됨
    onUnload 사용자가 문서나 프레임 세트를 종료함


                                                       객체 정의하기

     

    • 객체 유형 정의
      • 프로퍼티 : 객체에 들어 있는 데이터 값에 액세스할 때 사용.
      • 메소드 : 객체에 어떤 작업을 할 때 사용하는 함수.
    • 객체 유형 만들기
      사용자가 직접 객체 유형을 정의하고 특정 객체 인스턴스를 만들 수 있 는데 이렇게 만들려면 객체 유형의 특정 인스턴스를 만들 때 사용되는 함수를 정의하기만 하면 된다. 본래 이러한 생성자 함수는 다음과 같은 일을 한다.
      • 객체 유형의 프로퍼티에 값을 할당한다.
      • 객체 유형의 메소드로 사용할 수 있는 다른 함수를 지정한다.
    • 객체 사용 예
      1. table 객체의 정의 (table.js)
        function table_getValue(row,col){
          return this.data[row* this.columns+col ];
        }
        function table_setValue(row,col,value){
          this.data[row* this.columns+col ]=value;
        }
        function table_set(contents){
          var n=contents.length;
          for(var j=0;jthis.data[j]=contents[j];
        }
        function table_isHeader(row,col){
          return this.header[row* this.columns+col ];
        }
        function table_makeHeader(row,col){   this.header[row* this.columns+col ]=true;
        }
        function table_makeNormal(row,col){   this.header[row* this.columns+col ]=false;
        }
        function table_makeHeaderRow(row){   for(var j=0;j< this.columns+j)
            this.header[row* this.columns+col ]=true;
        }
        function table_makeHeaderColumn(col){   for(var i=0;i< this.rows;++i)
            this.header[i* this.columns+col ]=true;
        }
        function table_write(doc){
          doc.write("<TABLE BORDER="+ this.border+">");
          for(var i=0;i< this.rows;++i) {
            doc.write("<TR>");
            for(var j=0;j< this.columns;++j) {
              if( this.header[i* this.columns+j ]) {
                doc.write("<TH>");
                doc.write( this.data[i* this.columns+j ]);
                doc.write("</TH>");
              }
              else {
                doc.write("<TD>");
                doc.write( this.data[i* this.columns+j ]);
                doc.write("</TD>");
              }
            }
            doc.writeln("</TR>");
          }
          doc.writeln("</TABLE>");
        }
        funtion table(rows,columns) {
          this.rows=rows
          this.columns=columns
          this.border=0
          this.data=new Array(rows*columns)
          this.header=new Array(rows*columns)
          this.getValue=table_getValue
          this.setValue=table_setValue
          this.set=table_set
          this.isHeader=table_isHeader
          this.makeHeader=table_makeHeader
          this.makeNormal=table_makeNormal
          this.makeHeaderRow=table_makeHeaderRow
          this.makeHeaderColumn=table_makeHeaderColumn
          this.write=table_write
          
        }
      2. table 객체 사용하기
        <HTML>
        <HEAD>
        <TITLE>Defining Object Types</TITLE
        <SCRIPT LANGUAGE="JavaScript" SRC="table.js"><!-
        //-></SCRIPT>
        </HEAD>
        <BODY>
        <H1>Defining Object Types</H1>
        <SCRIPT LANGUAGE="JavaScript"><!-
        t=new table(3,4)
        contents=new
        Array("This","is","a","test","of","the","table","object.","Let's","see","it","work")
        t.set(contents)
        t.border=4
        t.makeHeaderColumn(0)
        t.write(document)
        //-></SCRIPT>
        </BODY>
        </HTML>
      3. 객체 유형에 프로퍼티와 메소드 추가
        : prototype 프로퍼티를 통해서 인스턴스화할 수 있는 미리 정의된 객체 유형에 프로퍼티와 메소드 추가
        사용 예
        <HTML>
        <HEAD>
        <TITLE>Updating Object Types </TITLE>
        <SCRIPT LANGUAGE="JavaScript" SRC="table.js"><!-
        //-></SCRIPT>
        </HEAD>
        <BODY>
        <H1>Updating Object Types</H1>
        <SCRIPT LANGUAGE="JavaScript"><!-
        function table_colorWrite(doc){
          ........
          함수 정의
          ........
          ........
        }
        t=new table(3,4)
        table.prototype.bgColor="Cyan"
        table.prototype.colorWrite=table_colorWrite
        .............
        .............
        t.colorWrite(document)
        //-></SCRIPT>
        </BODY>
        </HTML>
      4. 프로퍼티와 메소드 삭제
        delete objectName.propertyName
        delete objectName.methodName

                                                            브라우저 객체

     

    객 체 용 도
    window 객체 브라우저 윈도우나 윈도우 안에 있는 프레임에 액세스할 때 사용한다. 프로퍼티와 메소드를 참조할 때, window 객체가 존재하는 경우에는 "window."접두사를 붙일 필요가 없다
    document 객체 현재 윈도우에 로드되어 있는 문서에 액세스할 때 사용한다. document 객체는 컨텐트를 제공하는 HTML 문서, 즉 HEAD와 BODY 태그가 있는 문서를 의미한다.
    location 객체 URL을 나타낼 때 사용한다. 이 객체는 URL객체를 만들거나 URL의 일부분에 액세스하거나 기존의 URL을 수정할 때 사용할 수 있다.
    history 객체 한 윈도우 안에서 액세스된 URL의 히스토리를 유지할 때 사용
    frame 객체, frames 배열 HTML 프레임에 액세스할 때 사용
    frames 배열은 윈도우안에 있는 모든 프레임에 액세스할 때 사용
    link 객체, links 배열 하이퍼텍스트 링크의 텍스트 기반이나 이미지 기반 소스 앵커(anchor)에 액세스할 때 사용
    links배열은 문서 안에 있는 모든 link 객체에 액세스할 때 사용한다. I.E.는 link 객체의 anchor객체를 결합한다.
    anchor 객체, anchors 배열 하이퍼텍스트 링크의 타켓에 액세스할 때 사용
    anchors 배열은 문서 안에 있는 모든 anchor 객체에 액세스할 때 사용
    image객체, images 배열 HTML 문서에 삽입되어 있는 이미지에 액세스할 때 사용
    images 배열은 문서 안에 있는 모든 image 객체에 액세스할 때 사용
    area 객체 클라이언트측 이미지맵 안에 있는 영역에 액세스할 때 사용
    applet 객체, applets 배열 Java 애플릿에 액세스할 때 사용
    애플릿 배열은 문서 안에 있는 모든 애플릿에 액세스할 때 사용
    event 객체, Event 객체 이벤트 발생에 대한 정보에 액세스할 때 사용
    event 객체는 특정 이벤트에 대한 정보 제공
    Event 객체는 이벤트를 식별하는 데 사용하는 상수 제공
    form 객체, forms 배열 HTML 폼에 액세스시 사용
    forms 배열은 문서 안에 있는 모든 폼에 액세스시 사용
    element 객체 폼 안에 들어있는 모든 폼 요소에 액세스시 사용
    text 객체 폼의 텍스트 필드에 액세스시 사용
    textarea 객체 폼의 텍스트 영역 필드에 액세스시 사용
    radio 객체 폼의 라디오 버튼 세트에 액세스하거나 세트 안에 있는 각각의 버튼에 액세스할 때 사용
    checkbox 객체 폼의 체크 박스에 액세스할 때 사용
    button 객체 Submit나 Reset 버튼이 아닌 폼 버튼에 액세스시 사용
    reset 객체 폼의 Reset 버튼에 액세스시 사용
    selet 객체 폼의 선택 리스트에 액세스시 사용
    option 객체 option 객체는 선택 리스트의 요소에 액세스시 사용
    password 객체 폼의 패스워드 필드에 액세스시 사용
    hidden 객체 폼의 숨겨진 필드에 액세스시 사용
    FileUpload 객체 폼의 파일 업로드 요소에 액세스시 사용
    navigator 객체 스크립트를 실행하고 있는 브라우저에 대한 정보에 액세스시 사용
    screen 객체 사용자의 화면의 색상 깊이와 크기에 대한 정보에 액세스시 사용
    embed 객체, embeds 배열 삽입된 객체에 액세스시 사용
    embeds 배열은 문서 안에 삽입된 모든 객체에 대한 액세스 제공
    mimeType 객체, mimeTypes 배열 브라우저가 제공하는 특징 MIME 유형에 대한 정보에 액세스시 사용
    mimeTypes 배열은 제공하는 모든 mimeType 객체의 배열
    I.E.는 빈 배열을 리턴하면서 mimeTypes에 대해서 임시적으로 지원
    plugin 객체, plugins 배열 특정 브라우저 플러그인에 대한 정보에 액세스시 사용
    plugins 배열은 브라우저가 지원하는 모든 플러그인의 배열
    I.E.는 빈 배열을 리턴하면서 plugins에 대해서 임시적으로 지원

                                                                    

                                                               window 객체

    • 모든 브라우저 스크립트의 기본적인 것으로, 브라우저가 자동으로 정의하는 최상위 레벨의 객체이다. 현재 열려 있는 각 윈도우에 대해 별도의 window 객체가 정의된다.

    window 객체의 프로퍼티

     

    프로퍼티 설 명
    closed 윈도우가 닫혀 있는지 식별
    defaultStatus 브라우저 윈도우의 하단의 상태바에 나타나는 디폴트 상대 메시지를 지정
    document 윈도우에 표시되어 있는 현재 문서를 지정하는 객체
    frames 윈도우 객체에 들어 있는 모든 프레임 객체로 구성된 배열
    history 마지막으로 윈도우로 로드된 URL의 리스트를 포함하는 윈도우의 히스토리 객체
    length window에 들어 있는 프레임의 수 식별
    location window 객체와 관련된 URL을 지정하는 객체
    name 윈도우의 이름 지정
    offscreenBuffering 윈도우 정보의 오프스크린 버퍼링이 사용될 것인지를 지정하는 부울값
    오프스크린 버퍼링은 윈도우를 나타내기 전에 윈도우의 모든 요소를 로드할 때 사용
    opener 윈도우를 만들거나 열 수 있도록 해주는 window 객체 지정
    parent 특정 윈도우를 포함하는 윈도우를 지정하는 시너님
    self 참조될 현재 윈도우를 지정하는 시너님
    status 브라우저 윈도의 하단의 상태 표시줄에 나타날 임시 메시지를 지정
    top 중첩된 일련의 윈도우에서 맨 위에 있는 브라우저 윈도우를 의미하는 시너님
    window 참조될 현재 윈도우를 식별하는 시너님

    window 객체의 메소드
    메 소 드 설 명
    alert(text) 경고 다이얼로그 박스를 표시
    blur() 포커스를 윈도우에서 옮긴다
    setInterval(expression,milliseconds) 지정된 타임아웃 인터벌이 지난 이후에 표현식을 반복해서 평가하거나 함수를 불러온다.
    clearInterval(interval) 이전에 설정된 인터벌 타이머를 클리어
    setTimeout(expression,milliseconds) 타임아웃 기간이 지난 이후에 표현식을 평가하거나 함수를 호출한다.
    clearTimeout(timer) 이전에 설정된 타임아웃을 클리어
    close() 지정된 윈도우를 닫는다.
    confirm(text) 확인 다이얼로그 박스를 나타낸다.
    focus() 윈도우로 포커스를 가져간다.
    open(url,name,[options]) 새로운 윈도우를 열고 새로운 window 객체를 만듬
    prompt(text,defaultInput) 프롬프트 다이얼로그 박스를 나타낸다.
    scroll(x,y) 윈도우를 특정 위치까지 스크롤한다.

    open() 메소드의 옵션
    옵 션 설 명
    toolbar yes no 윈도우에 툴바 제공
    location yes no 윈도우에 위치 필드 제공
    directories yes no 디렉토리 버튼 제공
    status yes no 상태 표시줄 제공
    menubar yes no 메뉴바 제공
    scrollbars yes no 스크롤 바 제공
    resizable yes no 윈도우 크기 조절 가능
    width 정수 윈도우의 폭(픽셀)
    height 정수 윈도우의 높이(픽셀)

                                                               frame 객체

    • 프레임은 윈도우를 독립된 표시 영역들로 분할한 후, 이 영역들에 표시되는 정보들을 강력하게 컨트롤 할 수 있게 해준다.
    • 프레임 객체의 프로퍼티와 메소드는 window 객체와 같지만, close() 메소드는 지원하지 않는다.

    document 객체

    • JavaScript 에서 아주 중요한 객체로, 이 객체를 사용하면 로드될 문서를 업데이트하고 로드된 문서 안에 있는 HTML 요소에 액세스할 수 있다.

    프로퍼티 설 명
    alinkColor <BODY> 태그의 alink 속성의 값 지정
    anchor 문서에 들어 있는 배열을 참조하는 객체
    anchors 문서에 들어 있는 모든 앵커의 배열
    applet 문서에 들어 있는 애플릿을 참조하는 객체
    applets 문서에 들어 있는 모든 애플릿의 배열
    area 문서 안의 이미지맵 영역을 참조하는 객체
    bgColor <BODY> 태그의 bgColor 속성의 값 식별
    cookie 쿠키의 값 식별
    domain 문서가 로드되는 서버의 도메인 이름 식별
    embeds 문서안의 모든 플러그인의 배열
    fgColor <BODY> 태그의 text 속성값 지정
    form 문서 안의 폼을 참조하는 객체
    Forms[] 문서 안의 모든 폼의 배열
    image 문서 안의 이미지를 참조하는 객체
    Images[] 문서 안의 모든 이미지의 배열
    lastModified 문서가 마지막으로 수정된 날짜
    link 문서 안의 링크를 참조하는 객체
    links 문서 안의 모든 링크의 배열
    linkColor <BODY> 태그의 link 속성의 값 식별
    plugin 문서 안의 플러그인을 참조하는 객체
    plugins[] 브라우저가 지원하는 플러그인을 나타내는 객체의 배열
    referrer 문서에 대한 링크를 제공하는 문서의 URL
    title 문서의 타이틀
    URL 문서의 URL
    vlinkColor <BODY> 태그의 vlink 속성의 값 식별

    메 소 드 설 명
    close() 문서의 객체를 만드는 데 사용된 스트림
    open([mimeType][,"replace"]) 선택적인 MIME 유형으로 문서 객체를 만들 때 사용되는 흐름을 개시한다. "replace" 파라미터는 text/html MIME 유형과 함께 사용되어 히스토리 리스트에 있는 현재 문서를 대체
    write(expr1[,expr2...,exprN]) 문서에 표현식의 값을 기록
    write(expr1[,expr2...,exprN]) 개행 문자가 다음에 따라오는 문서에 표현식의 값 기록

    navigator 객체

    • navigator 객체는 window 객체와 마찬가지로 브라우저 객체 모델에서 최상위 레벨의 객체이며, 스크립트를 실행할 때 사용되는 브라우저의 종류와 버전에 대한 정보 제공한다.

    프로퍼티 브라우저 지원 설 명
    appCodeName N2, I.E3 브라우저 색상 이름
    AppMinorVersion I.E4 브라우저 버전 번호
    appName N2, I.E3 브라우저 이름
    appVersion N2, I.E3 브라우저의 버전
    browserLanguage I.E4 브라우저에 설정되어 있는 언어
    connectionSpeed I.E4 브라우저가 네트워크에 연결되는 속도
    cookieEnabled I.E4 브라우저가 쿠키를 허용하도록 설정되어 있는지의 여부
    cpuClass I.E4 브라우저 실행시 사용되는 마이크로프로세서의 유형
    onLine I.E4 브라우저가 현재 온라인 연결을 가지고 있는지 여부
    Language N4, I.E4 브라우저에 설정되어 있는 언어
    mimeTypes N3, I.E4 현재 브라우저가 지원하는 모든 MIME 유형의 배열
    platform N4, I.E4 브라우저가 실행되는 운영체제 플랫폼
    plugins N3, I.E4 현재 브라우저에 설치된 모든 플러그인의 배열
    systemLanguage I.E4 운영체제의 디폴트 언어
    userAgent N2, I.E3 브라우저에서 서버로 전송된 HTTP 프로토콜의 사용자 에이전트 헤더
    userLanguage I.E4 사용자가 사용하는 언어
    userProfile I.E4 사용자 프로파일 정보에 대한 액세스를 제공하는 객체

    navigator 객체의 메소드
    메 소 드 설 명
    javaEnabled() 사용자가 브라우저의 Java 기능을 켜두었는지의 여부를 나타내는 부울값 리턴
    taintEnabled() 사용자가 data tainting(보안 메커니즘)을 활성화했는지 여부를 나타내는 부울값 리턴
    preference 서명이 되지 않은 스크립트가 보안 관련 프로퍼티를 얻고 설정할 때 사용

    event 객체

    event 객체의 프로퍼티
    프로퍼티 브라우저 설 명
    data N DragDrop 이벤트로 인해 드롭된 객체의 URL이 들어있는 스트링 배열
    height, width N 윈도우나 프레인의 길이와 너비(픽셀표시)
    pageX, pageY N 픽셀로 나타낸 커서의 수평/수직 위치(페이지에서의 상대적위치)
    screenX, screenY N, I.E 픽셀로 나타낸 커서의 수평/수직 위치(화면에서의 상대적 위치)
    layerX, layerY N 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 레이어에 대한 상대적 위치. Resize 이벤트와 함께 사용하면 layerX와 layerY가 이벤트가 타겟으로 하는 객체의 길이와 너비 지정
    clientX와 clientY I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 웹페이지에서의 상대적 위치
    offsetX, offsetY I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 컨테이너에 대한 상대적 위치
    X, Y I.E 픽셀로 나타낸 커서의 수평/수직 위치, 이벤트가 발생한 문서에 대한 상대적 위치
    target N 이벤트가 전송된 원래 객체
    srcElement I.E 이벤트가 전송된 원래 객체
    type N, I.E 발생한 이벤트 유형
    which N 눌려진 마우스 버튼(왼:1, 가:2, 오:3)이나 눌려진 키의 ASCII값
    keyCode I.E 키 누름과 연관된 Unicode 키 코드를 식별
    button I.E 이벤트가 발생했을 때 눌려진 마우스 버튼 식별(0:눌려진버튼없음, 1:왼, 2:오, 4:가)
    modifiers N 마우스나 키 이벤트와 연관된 수정자 키(ALT_MASK,CONTROL_MASK,SHIFT_MASK,META_MASK)를 식별
    altkey,ctrlkey,shiftkey I.E true나 false로 설정하여 이벤트가 발생했을 때 Alt키와 Control키, Shift 키 중에 어떤 것이 눌려졌는지 알려준다.
    cancelBubble I.E true나 false로 설정하여 이벤트 버블링을 취소하거나 활성화한다.
    fromElement, toElement I.E 이동 중인 HTML 요소 지정
    reason I.E 데이터 소스 객체에 대한 데이터 전송 상태를 나타내는데 사용
    returnValue I.E true나 false로 설정하여 이벤트 핸들러의 리턴값을 나타낸다. 이벤트 핸들러에서 true나 false를 리턴하는 것과 같다.
    srcFilter I.E onfilterchange 이벤트를 시작하는 filter객체 지정

     

    screen 객체

  • screen 객체의 프로퍼티
    • height : 사용자의 화면의 현재 높이(픽셀)
    • width : 사용자의 화면의 현재 너비(픽셀)
    • colorDepth : 사용자의 화면/비디오 카드에서 현재 지원하는 색상당 바이트 수

    form 객체

    • document 객체의 프로퍼티로 액세스되고, form 객체는 문서 안의 폼에 액세스할 수 있도록 해주고, 폼 관련 이벤트에 응답을 할 수 있도록 해주기 때문에 중요하다.

    form 객체의 프로퍼티
    프로퍼티 설 명
    action <FORM> 태그의 HTML action 속성에 대한 액세스 제공
    button GUI 컨트롤 버튼을 나타내는 객체
    checkbox 체크 박스 필드를 나타내는 객체
    elements 폼 안에 포함되어 있는 모든 필드와 GUI 컨트롤을 포함하는 배열
    encoding <FORM> 태그의 HTML enctype 속성에 대한 액세스 제공
    FileUpload 파일 업로드 폼 필드를 나타내는 객체
    hidden 숨겨진 폼 필드를 나타내는 객체
    length elements 배열의 길이에 대한 액세스 제공
    method <FORM> 태그의 HTML method 속성에 대한 액세스 제공
    name 폼의 이름 식별
    password 패스워드 필드를 나타내는 객체
    radio 라디오 버튼 필드를 나타내는 객체
    reset reset 버튼을 나타내는 객체
    select 선택 항목 리스트를 나타내는 객체
    submit submit 버튼을 나타내는 객체
    target <FORM> 태그의 HTML target 속성에 대한 액세스 제공
    text 텍스트 필드를 나타내는 객체
    textarea 텍스트 영역 필드를 나타내는 객체

    form 객체의 메소드
    메 소 드 설 명
    handleEvent() 지정된 이벤트에 대한 폼의 이벤트 핸들러를 호출할 때 사용
    submit() 폼을 제출시 사용
    reset 폼의 엔트리를 디폴트 값으로 재설정시 사용

    form 요소 객체의 프로퍼티
    객 체 프로퍼티 설 명
    button name 버튼의 name 속성에 대한 액세스 제공
    type 객체의 유형 지정
    value 객체의 값 지정
    checkbox checked 체크박스가 현재 체크되어 있는지를 식별
    defaultChecked 체크박스가 디폴트로 체크되어 있는지 식별
    name 체크박스의 HTML name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    FileUpload name 객체의 name 속성에 대한 액세스 제공
    type 객체의 type 속성에 대한 액세스 제공
    value 객체의 값 식별
    hidden name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    password defaultChecked 객체의 디폴트 값 식별
    name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    radio checked 라디오 버튼이 체크되어 있는지 식별
    defaultChecked 라디오 버튼이 디폴트로 체크되어 있는지 식별
    name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    reset name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    select length 선택 리스트의 길이 식별
    name 객체의 name 속성에 대한 액세스 제공
    option 선택 리스트가 제공하는 옵션 식별하는 배열
    selectedIndex 선택 리스트 안에서 처음 선택된 옵션 식별
    type 객체의 유형 식별
    submit name 객체의 name 속서에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    text defaultValue 텍스트 필드에 나타나는 디폴트 텍스트를 식별
    name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별
    textarea defaultValue 텍스트 영역 필드에 나타나게 되는 디폴트 텍스트 식별
    name 객체의 name 속성에 대한 액세스 제공
    type 객체의 유형 식별
    value 객체의 값 식별

    form 요소 객체의 메소드
    객 체 메 소 드 설 명
    button Click() 클릭된 버튼 시뮬레이트
    blur() 포커스 잃음
    focus() 포커스 맞춤
    checkbox Click() 클릭된 체크 박스 시뮬레이트
    blur() 포커스 잃음
    focus() 포커스 맞춤
    FileUpload blur() 포커스 잃음
    focus() 포커스 맞춤
    select() 입력 영역을 선택
    hidden 없음
    password blur() 포커스 잃음
    focus() 포커스 맞춤
    select() 패스워드 필드에 나타나는 텍스트를 하이라이트
    radio Click() 라디오 버튼 클릭 시뮬레이트
    blur() 포커스 잃음
    focus() 포커스 맞춤
    reset Click() 리셋 버튼 클릭 시뮬레이트
    blur() 포커스 잃음
    focus() 포커스 맞춤
    select blur() 포커스 잃음
    focus() 포커스 맞춤
    submit Click() 제출 버튼 클릭 시뮬레이트
    blur() 포커스 잃음
    focus() 포커스 맞춤
    text blur() 포커스 잃음
    focus() 포커스 맞춤
    select() 텍스트 필드에 있는 텍스트 하이라이트
    textarea blur() 포커스 잃음
    focus() 포커스 맞춤
    select() 텍스트 영역에 있는 텍스트 하이라이트

    location 객체

    • 윈도우에 로드되어 있는 현재 문서의 URL에 액세스하거나 새로운 문서를 로드할 때 사용


    location 객체의 프로퍼티
    프로퍼티 설 명
    hash URL의 앵커 부분(존재하는 경우)
    host URL의 hostname:port 부분
    hostname URL의 host부분
    href 전체 URL
    pathname URL의 경로명 부분
    port URL의 포트 부분
    protocol URL의 프로토콜 부분
    search URL의 쿼리 스트링 부분

     

    location 객체의 메소드
    • reload() : 윈도우의 현재 문서를 브라우저의 Reload 버튼에서 사용하는 정책에 따라 다시 로드
      • Every time : 문서는 매번 서버에서 다시 로드
      • Once per session : 서버의 문서의 날짜가 캐시에 저장되어 있는 문서보다 더 최신 날짜라는 것을 나타내면 문서는 세션당 한 번씩 서버에서 다시 로드된다. 문서가 캐시에 없는 경우에는 서버에서 로드
      • Never : 문서는 가능하면 캐시에서 다시 로드, 그렇지 않으면 서버에서 로드
    • replace() : URL을 파라미터로 취하여, 현재 문서 히스토리 목록에 있는 현재 문서위로 그 URL의 문서를 로드, 그러면 브라우저의 Back버튼을 클릭하여 이전 문서로 돌아갈 수 없음

    link 객체

    • link 객체는 document 객체의 프로퍼티로, 문서에 들어있는 텍스트나 이미지 링크를 캡슐화
    • links 배열은 문서에 들어있는 모든 링크의 배열
    • link 객체의 메소드
      handleEvent() : event 객체를 인자로 취하며 그 이벤트에 대해 적당한 이벤트 핸들러 호출

    link 객체의 프로퍼티
    프로퍼티 설 명
    hash URL의 앵커 부분(존재하는 경우)
    host URL의 hostname:port 부분
    hostname URL의 host부분
    href 전체 URL
    pathname URL의 경로명 부분
    port URL의 포트 부분
    protocol URL의 프로토콜 부분
    search URL의 쿼리 스트링 부분
    target 링크의 HTML, target 속성

     

    anchor 객체

    • HTML 문서 안에서 이름이 지정된 오프셋으로 사용되는 앵커 의미
    • anchors 배열에는 문서의 모든 앵커가 들어있음
    • 프로퍼티나 메소드 또는 이벤트를 전혀 가지고 있지 않음
    • HTML 문서와 관련하여 정의된 이름이 지정된 오프셋을 추적할 때 사용
    • anchor 객체는 HREF 속성을 포함하는 경우에 link 객체가 된다.

    history 객체

    • history 객체의 프로퍼티
      • current : 윈도우에 나타나는 현재 문서의 URL
      • length : History 리스트의 길이
      • next : History 리스트에서의 다음 URL
      • previous : History 리스트에서의 이전 URL
    • history 객체의 메소드
      • back() : History 리스트에 이전 문서를 로드. 브라우저의 Back 버튼을 클릭하는 것과 같은 효과
      • forward() : History 리스트에 다음 문서를 로드. 브라우저의 Forward 버튼을 클릭하는 것과 같은 효과
      • go() : History 리스트에 있는 특정 문서로 감
        • go(n) : n>0인 경우, 이 메소드는 History 리스트에서 n개의 엔트리가 앞에 있는 문서를 로드, n=0인 경우에는 현재 문서가 다시 로드되고, n<0인 경우엔 History 리스트에서 n개의 엔트리 뒤에 있는 문서를 로드
        • go(string) : go()는 이 스트링을 서브스트링으로 갖고 있는 URL의 History 리스트에서 가장 가까운 문서를 로드

    image 객체

    • document 객체의 프로퍼티
    • 문서와 함께 로드된 이미지에 대한 액세스 제공
    • images 배열은 문서 안에 지정되어 있는 각각의 <IMG>태그에 대한 엔트리가 들어있음
    • image 객체 유형을 사용하면 키워드와 생성자로 새로운 image 객체를 명시적으로 만들 수 있다. Image() 생성자는 웹페이지의 일부로서 처음에 나타나지 않는 이미지를 만들고 미리 로드할 때 사용한다. 이러한 image 객체는 브라우저의 캐시에 저장되면 이미 나타난 이미지를 대체할 때 사용
      * Image() 생성자를 사용하여 캐시된 이미지 만드는 예 cachedImage=new Image()
      cachedImage.src="myImage.gif"
      = > 첫번째 문장은 새로운 image 객체를 만들고 그것을 cachedImage 변수에 대입하고, 두번째 문장은 image 객체의 src프로퍼티를 myImage.gif 이미지 파일로 설정한다. 이 경우 myImage.gif는 브라우저 캐시로 로드된다. 그러면 로드된 이미지는 cachedImage 변수를 사용하여 참조 가능하다.

      image 객체의 프로퍼티
      프로퍼티 설 명
      border <:IMG> 태그의 BORDER 속성의 값
      complete 이미지가 완전히 로드되었는지 식별
      height <:IMG> 태그의 HEIGHT 속성의 값
      hspace <IMG> 태그의 HSPACE 속성의 값
      lowsrc <IMG> 태그의 LOWSRC 속성의 값
      name <IMG> 태그의 NAME 속성의 값
      prototype image 객체에 사용자 지정 프로퍼티를 추가할 때 사용
      src <IMG> 태그의 SRC 속성의 값
      vspace <IMG> 태그의 VSPACE 속성의 값
      width <IMG> 태그의 WIDTH 속성의 값

    area 객체

    • 이미지맵은 여러 가지 다른 영역으로 나누어져 있는 이미지로서 각각의 영역은 자체 URL과 관련되어 있다. 그리고 이러한 영역과 관련된 사용자 처리 방식으로 area 객체를 제공

    area 객체의 프로퍼티
    프로퍼티 설 명
    hash area 객체의 HREF 속성의 파일 오프셋 부분
    host area 객체의 HREF 속성의 호스트 이름 부분
    hostname area 객체의 HREF 속성의 host:port 부분
    href area 객체의 완전한 HREF 속성
    pathname area 객체의 HREF 속성의 경로명 부분
    port area 객체의 HREF 속성의 포트 부분
    protocol area 객체의 HREF 속성의 프로토콜 부분
    search area 객체의 HREF 속성의 쿼리 스트링 부분
    target area 객체의 TARGET 속성

     

    Array 객체

    • Array 객체를 사용하면 배열을 객체처럼 액세스 가능
    • Array 객체의 프로퍼티
      • length : 배열의 길이 식별
      • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
    • Array 객체의 메소드
      • toString() : 배열의 스트링 버전 리턴, 배열 요소는 컴마로 구분
      • join(separator) : 배열의 스트링 버전 리턴, 배열 요소는 seperator 스트링으로 구분, 분리자가 없으면 컴마로 구분
      • reverse() : 배열의 요소를 역순으로 바꿈
      • sort(comparisionFunction) : 비교 연산에 따라 배열의 요소 정렬. 비교 함수가 지정되면, 배열 요소는 사전순서로 정렬. 비교 연산이 지정되면 두개의 파라미터 p1,p2를 취하고, p1이 p2보다 작은 경우에는 음의 정수를 리턴하고, 같으면 0을 리턴하고, p1이 p2보다 크면 양의 정수 리턴

    Boolean 객체

    • Boolean 객체를 사용하면 부울값은 객체로서 액세스 가능
    • Boolean 객체는 생성자에 대한 인자로서 값을 식별하여 만들어짐 myBoolean=new Boolean(false)
      yourBoolean=new Boolean(true)
    • Boolean 객체의 프로퍼티
      • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
    • Boolean 객체의 메소드
      • toString() : 부울값에 해당하는 스트링 리턴
      • valueOf() : 객체의 값에 따라 true나 false로 리턴

    Date 객체의 메소드
    메 소 드 설 명
    getDate()
    getUTCDate()
    setDate()
    setUTCDate()
    Date 객체의 날짜를 설정하거나 리턴
    getDay()
    getUTCDay()
    Date 객체의 한 주의 날짜를 설정하거나 리턴
    getHours()
    getUTCHours()
    setHours()
    setUTCHours()
    Date 객체의 시간를 설정하거나 리턴
    getMilliseconds()
    getUTCMilliseconds()
    setMilliseconds()
    setUTCMilliseconds()
    Date 객체의 밀리초 값을 설정하거나 리턴
    getMinutes()
    getUTCMinutes()
    setMinutes()
    setUTCMinutes()
    Date 객체의 분을 설정하거나 리턴
    getMonth()
    getUTCMonth()
    setMonth()
    setUTCMonth()
    Date 객체의 달을 설정하거나 리턴
    getSeconds()
    getUTCSeconds()
    setSeconds()
    setUTCSeconds()
    Date 객체의 초를 설정하거나 리턴
    getTime()
    getUTCTime()
    Date 객체의 시간을 설정하거나 리턴
    getTimeZoneOffset() Date 객체의 시간대 오프셋(분)을 리턴
    getYear()
    getFullYear()
    getUTCFullYear()
    setYear()
    setFullYear()
    setUTCFullYear()
    Date 객체의 연도를 리턴하거나 설정한다. 완전한 연도를 나타내는 방법으로 4자리 연도 값을 사용한다.
    toGMTString() 날짜를 Internet GMT(Greenwich Mean Time) 포맷의 스트링으로 변환
    toLocaleString() 날짜를 로케일(locale)포맷의 스트링으로 변환. 로케일 포맷이란 사용자가 위치해 있는 지형적 위치에서 일반적으로 사용하는 포맷 의미
    toString() Date 객체의 스트링 값을 리턴
    valueOf() 1970년 1월 1일 자정 이후의 밀리초 값 리턴
    toUTCString() UTC에서 시간을 나타내는 스트링 값을 리턴

    Date 생성자
    생 성 자 설 명
    Date() 현재 날짜와 시간으로 Date 인스턴스 만듬
    Date(dateString) dateString 파라미터에 지정되어 있는 날짜로, Date 인스턴스를 만든다. dateString의 포맷은 "월,일,연도,시:분:초"
    Date(milliseconds) 1970년 1월 1일 자정 이후 지정된 밀리초 값으로 Date 인스턴스를 만든다.
    Date(year,month,
    day,hours,minutes,
    seconds,milliseconds)
    년,월,일,시,분,초,밀리초 정수에 따라 지정된 날짜로 Date 인스턴스를 만든다. 연도와 월 파라미터는 제공되어야 하고 다른 나머지 파라미터가 포함되면 앞에 오는 모든 파라미터가 제공되어야

    Function 객체

    • 함수를 객체처럼 액세스 가능하고, 이 객체는 스크립트를 실행하는 동안에 함수를 동적으로 만들고 호출할 때 사용
    • Function 객체는 함수의 파라미터와 본문을 Function() 생성자에 제공하면 된다.
      variable=new Function("p1","p2", ... ,"pn","body")
    • Function 객체 프로퍼티
      • length : 함수에 대해 정의된 파라미터의 숫자 식별
      • prototype : 모든 객체 유형이 지원하는 프로퍼티로 객체 유형에 대해 추가적인 프로퍼티 및 메소드 정의 가능
      • arguments : 호출시 함수에 전달되는 인자를 가리키는 배열
      • caller : 특정 함수를 호출한 함수를 가리킴
    • Function 객체의 메소드
      • toString() : 함수의 스트링 형태 리턴
      • valueOf() : 함수 자체 리턴

    Global 객체

    • new Global() 을 통해서 명시적으로 만들거나, 참조할 수 없다. 대신 해당 프로퍼티와 메소드가 전역 변수와 함수로 직접 참조됨
    • Global 객체의 프로퍼티
      • Nan : 숫자가 아니라는 의미
      • Infinity : 양수 무한대 값 의미
    • Global 객체의 메소드
      • escape(string) : string을 새로운 스트링으로 변환
      • eval(x) : 표현식 x의 값을 계산하고 리턴
      • inFinite(number) : number가 유한하면 true를 리턴하고, 무한하면 false를 리턴
      • inNaN(number) : number가 숫자가 아니면 true를 리턴하고, 숫자이면 false를 리턴
      • parseFloat(string) : string을 부동 소수 값으로 파싱
      • parseInt(string,radix) : string을 밑이 radix인 정수로 파싱
      • unescape(string) : escape()에 들어 있는 스트링을 원래의 값으로 되돌린다.

    Math 객체

    • 수학적 상수와 함수의 표준 라이브러리 제공
    • Math의 특수 인스턴스는 Math가 내장 객체이고 객체 유형이 아니기 때문에 만들어지지 않는다.


    Math 프로퍼티
    프로퍼티 설 명
    E Euler의 상수. 이것은 계산을 하는 어디에서나 발견할 수 있으며 자연대수의 기초
    LN2 2의 자연대수. 이것은 자연대수와 밑이 2인 대수 사이의 전환에 사용되는 간단한 상수
    LN10 10의 자연대수. LN2와 마찬가지로 대수 변환에 사용
    LOG2E 밑이 2인 E의 대수. 이것은 밑이 10인 대수를 밑이 E인 대수로 변환시 사용
    PI 원의 원주 대 지름의 비율
    SQRT1_2 1/2의 제곱근은 많은 삼각법 계산에서 사용
    SQRT2 2의 제곱근은 대수식에서 흔히 사용

    Math 메소드
    메 소 드 설 명
    abs(x) x의 절대값 리턴
    acos(x) x의 아크 코사인값 라디안으로 리턴
    asin(x) x의 아크 사인값 라디안으로 리턴
    atan(x) x의 아크 탄젠트 값을 라디안으로 리턴
    atan2(x,y) (x,y)에 해당하는 극좌표의 각도를 리턴
    ceil(x) x보다 크거나 작은 최소 정수값 리턴
    cos(x) x의 코사인 값 리턴
    exp(x) eX를 리턴
    floor(x) x보다 작거나 같은 최대 정수값 리턴
    log(x) x의 자연대수 리턴
    max(x,y) x, y 중 큰 값 리턴
    min(x,y) x, y 중 작은 값 리턴
    pow(x,y) xy를 리턴
    random() 0과 1사이의 임의의 숫자 리턴
    round(x) x의 가장 가까운 정수로 반올림되는 값 리턴
    sin(x) x의 사인값 리턴
    sqrt(x) x의 제곱근 리턴
    tan(x) x의 탄젠트 값 리턴

    Number 객체

    • Number 객체 유형을 사용하면 숫자를 객체로 다룰 수 있다.
    • Number 객체의 프로퍼티
      • MAX_VALUE : 숫자는 가능한 최대 수치값
      • MIN_VALUE : 숫자는 가능한 최소 수치값
      • NaN : 숫자가 아니다
      • NEGATIVE_INFINITY : 숫자가 음수 무한대 값
      • POSITIVE_INFINITY : 숫자가 양수 무한대 값
      • prototype : 모든 객체 유형이 지원
    • Number 객체의 메소드
      • toString(radix) : 밑이 radix인 숫자를 나타내는 스트링 리턴
      • valueOf() : Number 객체의 수치값 리턴

    Object 객체

    • Object 객체는 다른 모든 객체들이 파생되어 나가는 기반 객체로 이것의 프로퍼티와 메소드는 다른 객체 유형들에서 사용 가능
    • Object 객체의 프로퍼티
      • prototype : 모든 객체 유형이 지원
      • constructor : 객체 생성자의 이름 식별
    • Object 객체의 메소드
      • toString() : 객체를 스트링 표현으로 바꾸는 역할
      • valueOf() : 객체와 관련된 경우의 원시값(숫자,스트링,부울값)을 리턴하고, 그렇지 않은 경우에는 객체 자체를 리턴

    String 객체

    • 스트링을 객체로 액세스 가능
    • String 객체의 프로퍼티
      • length : 문자에서 스트링의 길이 알아내는 역할
      • prototype : 모든 객체 유형이 지원

    String 메소드
    메 소 드 설 명
    charAt(index) 메소드가 적용되는 스트링의 지정된 인덱스에 있는 문자로 구성된 스트링을 리턴
    charCodeAt(index) 지정된 인덱스의 문자의 Unicode 인코딩 리턴
    fromCharCode(codes) 문자 코드의 컴마로 구분된 시퀀스에서 스트링 만듬
    indexOf(pattern) 스트링안에 들어있는 pattern 파라미터가 지정한 첫 번째 스트링의 인덱스 리턴, 패턴이 스트링 안에 들어있지 않으면 -1 리턴
    indexOf(pattern,startIndex) startIndex가 지정한 위치에서 검색을 시작하는 것을 제외하면 indexOf(pattern) 메소드와 같다.
    lastIndexOf(pattern) 스트링에 들어 있는 pattern 파라미터가 지정한 마지막 스트링의 인덱스 리턴, 패턴이 스트링 안에 들어있지 않으면 -1 리턴
    lastIndexOf(pattern,startIndex) startIndex가 지정한 위치에서 검색을 시작하는 것을 제외하면 lastIndexOf(pattern)과 같다.
    splitSeparator() 하나의 스트링을 분리자를 기반으로 하여 서브스트링의 배열로 분리
    substring(startIndex) startIndex에서 시작하는 스트링의 서브스트링을 리턴
    substring(startIndex,endIndex) startIndex에서 시작하고, endIndex에서 끝나는 스트링의 서브스트링을 리턴
    toLowerCase() 소문자로 변환된 스트링의 복사본 리턴
    toString() 객체의 스트링 값을 리턴
    toUpperCase() 대문자로 변환된 스트링의 복사본 리턴

  • 내용출처 : [기타] 블로그 집필 - 뎅구르르까껑의 블로그

    java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V 

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

    1. Removed Hibernate's asm.jar,cglib-2.1.3.jar and asm-attrs.jar from classpath.

    2. Placed cglib-nodep-2.1_3.jar in classpath (downloaded from

    http://repo1.maven.org/maven2/cglib/cglib-nodep/2.1_3/).

    3. Included asm3.0.jar from CXF2.0.1 from distribution into the classpath.

    http://forge.objectweb.org/projects/asm/




    D:\dev\eclipse\eclipse.exe -data "워크스페이스경로" -showlocation

    '개발 > IDE' 카테고리의 다른 글

    eclipse copy & Paste 느린 현상  (0) 2015.04.02
    eclipse.ini 설정  (0) 2014.04.22
    Eclipse 유용한 PLUG-IN  (0) 2009.10.24
    [eclipse] 자주쓰는 이클립스 단축키  (0) 2008.12.24
    Eclipse plug-in  (0) 2008.12.06