2018년 9월 17일 월요일

리눅스 파일 또는 폴더만 선택해서 권한 속성 변경하기


리눅스 사용시 권한 속성을 변경 하는 경우 파일과 폴더의 속성을 다르게 설정해야 하는 경우가 생깁니다.

이런 경우 사용 find 명령을 통해서 검색 결과에 명령을 실행하도록 해주면 됩니다.

파일만 권한 속성 변경 하기
find ./ -type f -exec chmod 640 {} \;

폴더만 권한 속성 변경 하기
find ./ -type d -exec chmod 750 {} \;

2018년 9월 11일 화요일

Spring 어플리케이션을 톰캣에 배포 하였을때 schedule 이 중복 실행 되는 현상

톰캣에 Spring 어플리케이션을 배포해서 서비스 하는 경우 schedule 이 중복되어 실행 되는 현상이 발생하는 경우가 있습니다.

이런 경우는 보통 어플리케이션이 이중으로 로딩되어 발생하는 현상입니다.

tomcat 의  server.xml 설정시에 Host 설정에 appBase 속성을  설정하고 배포한 어플리케이션을  appBase 폴더 아래에 위치 시켜서 Context 설정을 하게 되면 Tomcat 이 어플리케이션을 이중으로 로딩하게 됩니다.

아래와 같이 server.xml 을 설정 하게 되면  배포한 appTest 어플리케이션이
Host의 appbase 설정에 따라서 /appTest 로 배포 하고
또 context  설정에 따라서 /로 배포 하게 되어 이중으로 로딩하는 문제가 발생 하게 됩니다.

    <Host name="localhost"  appBase="/home/user/tomcat/webapps" unpackWARs="true" autoDeploy="false" >
        <Context path="/appTest" docBase=“app1" reloadable="true" />
    </Host>

이런 경우 소스를 appbase 아래가 아닌 다른곳에 설치 하거나 host 속성에 기동시에 appbase 아래의 어플리케이션을 배포 하지 않도록 아래 처럼 deployOnStartup 을 false로 설정을 해주면 됩니다.

    <Host name="localhost"  appBase="/home/user/tomcat/webapps" unpackWARs="true" autoDeploy="false" deployOnStartup="false">
        <Context path="/appTest" docBase=“app1" reloadable="true" />
    </Host>

2017년 2월 1일 수요일

[spring] @Scheduled 로 이번달의 마지막 일자에 실행하기가 안될때

Spring 에서 @Scheduled 어노테이션 사용시 해당월의 마지막에 실행하려고
'L' 문자를 사용하려고 하면 에러가 발생한다.

그래서 매일 실행 하면서 java에서 마지막 날을 확인해서 실행 하는 방식으로 처리 하였다.

@Scheduled(cron="1 0 0 * * *")
private void SchedulerEndDayOfMonth() {
  
    Calendar cal = Calendar.getInstance();
    // 오늘이 월의 마지막 일인지 확인
    boolean isLastDay = cal.get(Calendar.DATE) == cal.getActualMaximum(Calendar.DATE);
 
    if(isLastDay) {
        // 실행 내용 
    }
}

2017년 1월 20일 금요일

[jsRender] jsRender 사용 되는 기본 표현식 및 기본 개념 정리

스크립트와 html 코드를 분리할 방법을 찾다가  jsRender를 사용하게 되었습니다.
단순한 작업은 그냥 봐도 사용하는데 문제가 없는데 점점 케이스가 다양해지면서 역시 기본이 개념에 대한 이해가 필요해 지더군요.
그래서 jsRender를 사용하다 기본적으로 참고할 만한 사항을 정리 하였습니다.

1. 탬플릿 태그

1) {{: ...}}
 데이터의 경로나 표현식을 넣으면 데이터나 표현식의 결과를 출력한다.

[data]
var person = {
    name : "joe",
    age : 30,
    tag : "very good man"
}

[example]
{{: name}} => joe
{{:"Hi! " +name}} => Hi! joe
{{:age + 10}} => 40
{{:: name == 'peter'}} => false

2) {{> ...}}
    {{: ...}} 와 동일하나 HTML-encoded 형태로 출력한다. (HTML 태그를 그대로 출력한다.)

[example]
{{:tag}} => very good man
{{>tag}} => very <b>good</b> man

2. view 와 data

view는 일종의 jsRender에서 사용하는 블럭 단위라고 생각하면 됩니다. 
각 view에는 data라는 property 가 있어서 전달받은 객체가 data에 담기게 됩니다. 
만약 사용자가 person객체를 넘기면 하나의 view가 생기면서 data = person 이 됩니다. 
이 view가 블럭 태그(에를 들면 for 같은, 단 if는 제외)를 만나면 하위 view 생기고 하위 view에 data 생성 됩니다.

루프 블럭을 예로 들자면 처리중 for 구문을 만나게 되면 arrayView가 생성되고 해당 data = array 가 됩니다. 그리고 루프를 돌게 되면 해당 array의 각 하나의 요소를 가진 itemView가 생기게 됩니다. 
이렇게 되면 array[index]가 itemView의 data가 되게 됩니다.

패스를 사용할때 현재 view의 data는 생략해도 됩니다 하지만 상위 view의 데이터를 접근할때는 꼭 써줘야만 접근이 가능합니다.


3. 패스(Path)
    객체에 접근하는 방식으로 객체의 타입에 따라서 접근하는 방식에 차이가 있습니다.

1) Data paths - {{ ... }} 
    일반적으로 사용하는 데이터에 접근 하는 표현 방식입니다. 별도로 붙이는게 없이 그냥 사용하면 됩니다.
    현재 view에 있는 data 요소에 접근하는 방식으로 data를 생략하고 사용하면 됩니다.
    예를 들면 person 이라는 객체를 받은 경우 data.name 또는 name 으로 접근 하면 됩니다.
    dataProperty.bb.cc

3) View Paths - {{ #...}}
    view의 요소에 접근 하는 표현 방식 입니다. # 을 붙여서 사용 합니다.
    #view 는 현재의 view 블럭을 가르키고  #view.data 는 #data 로 표현이 가능합니다.
    #viewProperty.bb.cc

    view에는 다른 view에 접근 하거나 기본적용 요소들이 있습니다.
    이 표현으로 유용한 요소는  상위 view를 표현하는 #parent 나 loop 블록에서 사용되는 #index  요소가 있습니다.
    상위  view 에 있는 team 이라는 객체에 접근하고 싶은 경우 다음과 같이 표현하면 됩니다.
    #parent.data.team

4) Helper paths - {{~...}}
    helper 패스는 사용자가 생성해서 설정한 함수, 객체 등을 사용할때 사용하는 표현 방식으로 jsRender에 함수 같은것을 넘겨서 사용할때 사용하게 됩니다.
    그리고 contextual 파라메터를 접근할때도 사용하게 됩니다. (~root)
    ~myHealper.bb.cc


* 참조
  - https://www.jsviews.com/#paths
  - https://www.jsviews.com/#helpers
  - https://www.jsviews.com/#contextualparams
  - https://www.jsviews.com/#views
  - https://www.jsviews.com/#views@datacontext

2017년 1월 12일 목요일

[git] gitlab 설치 하기

gitlab 설치 방법

git 서버 구축을 위해서  gitlab을 설치 하는 방법 입니다.

설치 OS : CentOS 7

1.  기본 환경 설정 및 의존도 있는 어플리케이션 설치
- 필요 프로그램 사전 설치
sudo yum install curl policycoreutils openssh-server openssh-clients

- sshD 기동
sudo systemctl enable sshd
sudo systemctl start sshd

- 메일 서버 설치 및 기동
sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix

- 방화벽 설정 및 재시작
sudo firewall-cmd --permanent --add-service=http
sudo systemctl reload firewalld

* 이미 설치되어 있는경우 설치 하지 않아도 됩니다.

2. gitlab 패키지 설치
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo yum install gitlab-ce

3. gitlab 설정 및 기동
sudo gitlab-ctl reconfigure

4. 접속(웹브라우저)
http://[gitserverIP]

* 관리자 계정은 root 이고 기본 패스워드는  5iveL!fe 으로 되어 있지만 초기 접속하면 바로 패스워드 변경 화면으로 이동하게 됩니다.

5. 기동 / 중지 / 재시작
sudo gitlab-ctl start
sudo gitlab-ctl stop
sudo gitlab-ctl restart

6. 기타 정보
 - 설치는 /opt/gitlab 에 됩니다. 
 - 설정 변경시 /etc/gitlab/gitlab.rb 를 수정해 주고 
   sudo gitlab-ctl reconfigure 해 주시면 됩니다.


** 주의 사항
계정을 만들어 실행 시키는 경우 sudo 가 실행이 안되고 아래 에러가 나는 경우가 있습니다.
[user] is not in the sudoers file.  This incident will be reported.

root 계정으로 sudouser 에 추가해 줍니다.
visudo -f /etc/sudoers

root ALL=(ALL) ALL
아래에 계정을 추가해 줍니다.

[아이디] ALL=(ALL) ALL

** 주의 사항
- 설치 시에  git 이라는 유저가 이미 있으면 설정 및 실행시 실패 합니다.(있으면 지워야 합니다.)

* 참고 사항 : https://about.gitlab.com/ 의  download  항목에서 OS를 선택하면 친절 하게 설치 절차를 보여 줍니다.

[git] git 설치 하기

git 설치 단계를 정리 하였습니다.


1. git 컴파일  설치

1) 설치된 git 확인
yum list git

2) 기존 git 삭제
yum -y remove git

3) git 버젼 확인
https://www.kernel.org/pub/software/scm/git

4) git 가져 오기
cd /usr/src
wget https://www.kernel.org/pub/software/scm/git/git-2.11.0.tar.gz

5) 필요 어플리케이션 설치
yum -y install gettext-devel openssl-devel perl-CPAN perl-devel zlib-devel
yum -y install gcc

6) git 설치
tar xvf git-2.11.0.tar.gz
cd git-2.11.0
make configure
./configure --prefix=/usr/local
make install

** 주의 사항
- autoconf 관련 에러가 발생하면 설치 하면 됩니다.
yum -y install autoconf


2. git yum  설치

1) git 설치 확인
yum list git

2) git 설치
yum install git

3) git version 확인
git version

4) 설치한 경로 확인
rpm -ql git


3. git 설정

1) git 사용자 설정
git config --global user.name "[Name]"
git config --global user.email "[e-mail]"

2) git 설정 확인
git config -l

3) git 스토리지로 설정
mkdir gittest
cd gittest
git init


** 주의 사항
  - 서버로 사용하기위해서는 gitlab 같은 패키지를 설치 해야합니다.

2016년 12월 16일 금요일

[uml] 관계도 정리

UML 사용시 가끔 혼동되는 경우가 있어서 정리 하였습니다.


2016년 12월 14일 수요일

[JNI] Java JNI 연동 방법

Java에서 C쪽 레거시 연동을 위해서 JNI를 사용할 때가 있습니다.
이때 연동하는 절차에 대해서 간단하게 정리해 봤습니다.

1. java 에서 호출 하기

public class Hello {
    native void helloFromC(int iValue, String sValue);
    static {
        System.loadLibrary("chello");
    }
    static public void main(String argv[]) {

        int i = 1;
        String s = "testval";
        Hello helloWorld = new Hello();
        helloWorld.helloFromC(i, s);
    }
}

native 로 C쪽에서 사용할 메소드를 선언합니다.
그리고  System.loadLibrary  로 C 소스를 로딩합니다.
마지막으로  호출해서 사용합니다.

2. java 소스 컴파일 및 C에서 사용할 소스의 헤더 생성하기

일단 javac 로 자바 파일을 컴파일 한 후에 javah 로 c에서 사용할 헤더파일을 생성합니다.

$ javac Hello.java
$ javah Hello

3. c 코드 작성하기 

#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_helloFromC
  (JNIEnv * env, jobject jobj, jint ival, jstring sval)
{
 const char *name = (*env)->GetStringUTFChars(env, sval, NULL);
     printf("Hello from C!\n");
     printf("%d ____ %s \n",ival,name);
     
     printf("Hello from C exit\n");     
}

4. c 코드 컴파일 하기

$ gcc -o libchello.so -shared chello.c -lc -fPIC

* 참조하는 라이브러리가 있는경우 아래와 같이 참조를 해서 컴파일 한다.
$ gcc -o libchello.so -shared -I/home/temp/Stat_Test -I/home/FRAMEWORK/include chello.c -lc -fPIC -L/home/FRAMEWORK/lib/ -lstctl


5. 실행한다. 

$ java Hello

실행시 다음과 같은 에러가 나는 경우가 있습니다.
이런 경우는 64bit 로 컴파일하고 32bit JDK 버젼에서 실행한 경우이다. 

$ /usr/local/j2sdk1.4.2_19/bin/java Hello
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/temp/TT/libchello.so: /home/temp/TT/libchello.so: wrong ELF class: ELFCLASS64 at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511) at java.lang.Runtime.loadLibrary0(Runtime.java:788) at java.lang.System.loadLibrary(System.java:834) at Hello.(Hello.java:4)

* 주의 사항 : 테스트는 패스를 숨기기위해서 일부 경로 정보를 조작한게 있습니다.
(무조건 복붙해서 돌리면 에러가 날 수도 있다는 뜻입니다.)
* 주의 사항 : 테스트는 같은 폴더에 있어서 패스 설정하는 부분이 빠져 있습니다.
* 주의 사항 : 실제 Web 서버에서 사용할때는 라이브러리가 LD_LIBRARY 패스에 들어가 있어야 합니다.

2016년 12월 12일 월요일

[Java] Logger 라이브러리 구조 및 유의 사항

 Log4J를 사용하다가 오래된 로그 지우는 기능을 사용하기 위하여 기존 Log4J를 걷어 내고 Logback으로 Logger를 변경하게 되었다.
이때 Logging 라이브러리 관련해서 이해한 내용을 정리 하였다.

로그 프레임 워크를 보면 아래와 같은 순서로 진행되게 된다. 

    1. 어플리케이션에서 사용하는 로거를 브릿지를 통해서  SLF4J 형식으로 변환한다. 
    2. SLF4J로 변환된 로그를 원하는 로깅 라이브러리로 바인딩하여 사용한다. 

이를 통해서 다양한 형식으로 로깅 방식을  SLF4J 로 통합하고 자신에게 맞는 로깅 라이브러리로 쉽게 바인딩 하여 사용 할 수 있도록  되어 있다. 

구성요소는 아래와 같이 4가지로 되어 있다. 

Application -> Bridge -> Interface -> Binding -> Logger

이 때 주의 할 점은  Bridge 에서 변환되는 로그와 Binding 에서 연동하는 로그의 타입이 같으면 안된다.
만약 같게 되는 경우 Binding -> Bridge 방향으로 다시 로그가 흘러가 무한 루프에 빠지게 된다.

예를 들면 log4j-over-slf4j 브릿지를 쓰고 slf4j-log4j 바인더를 사용하게 되는 경우
    Application -> Bridge -> Interface -> Binding ->[ Bridge -> Interface ->Binding ->] .... 
이런식으로 무한 루프에 빠져 오류가 발생하게 된다.

2016년 11월 9일 수요일

[Mysql] Mysql 에서 연산시 이상한 소수점이 생기는 현상

mysql 에서 연산을 하면 이상하게 소수점이 발생하는 경우가 있습니다 .

이런 경우 필드의 타입이 double, float 형 즉, 부동소수점 형태의 자료형을 연산(sum 등) 하는 경우에 발생하는 현상이 입니다.

이런 경우 필드 타입을 decimal 로 해야 해당 문제가 발생하지 않습니다.

데이터가 저장용이 아닌 연산을 위한 필드를 정의 시엔 decimal로 선언해서 사용하는 것이 정확한 값을 얻는데 도움이 됩니다.

2016년 8월 3일 수요일

[MySql] Mysql Safe mode On/Off

MySql Safe Mode 로 인해서 데이터 베이스 업데이트나 삭제가 안되는 경우가 발생한다.

이 경우에 명령어로 On/Off 하는 방법이다.

[Safe Mode ON]
$>set sql_safe_updates = 1;

[Safe Mode OFF]
$>set sql_safe_updates = 0;

2016년 8월 2일 화요일

[Java] Java Web application Login 설계

Java web 어플리케이션에 로그인 설계 with spring framework

1. 기능 정의

- 로그인
    - 사용자에게 아이디 패스워드를 받아서 로그인 한다.
    - 로그인 이후 사용자를 메인 페이지로 이동시킨다.
- 로그아웃
    - 사용자를 로그아웃 처리한다.
- 로그인 확인
    - 로그인이 안되어 있는경우 로그인 페이지로 이동한다.
    - 로그인이 되어 있는경우 접속을 허가 한다.
- 중복 로그인 방지
    - 동일한 아이디로 로그인이 되어 있는 경우 기존 사용자의 접속을 종료 하고 로그인 한다.
- 로그인/로그아웃 이력 저장
    - 로그인 이력 기록
    - 로그아웃 이력 기록
    - 동일 아이디 접속에 의한 로그아웃 이력 기록
    - 세션 타임아웃에 의한 로그아웃 이력 기록 (옵션)
    - 관리자에 의한 로그아웃 이력을 기록(옵션)
- 관리자 로그인/로그아웃 관리 기능 (옵션)
    - 현재 로그인된 사용자 목록을 조회 한다.
    - 로그인된 사용자를 로그아웃 시킨다.

2. 주요 기술 및 기능 구성

- Spring framework 기반으로 개발 한다.
- 브라우져와 서버와의 연동은 rest 방식을 사용한다.
- 로그인 확인 체크는 interceptor를 통해서 처리한다.
- 로그인한 사용자의 관리는 Manager 관리 객체를 만들고 Thread safe 하게 ConcurrentHashmap을  이용하여 처리 한다.
- 세션이 끝나는경우 로그아웃 처리를 위해서는 HttpSessionListener 를 구현해서 처리 한다.
- 자발적인 로그아웃이 아닌경우 로그아웃된 이유는 해당 세션에 넣어 준다.

3. 로그인/로그아웃 Case

- 로그인
    - 사용자의 아이디/패스워드를 입력 후 로그인
- 로그 아웃
    - 로그 아웃 기능을 통해 정상 로그아웃
    - 로그인 된 상태에서 다른곳에서 동일한 아이디로 로그인
    - 관리자 관리 기능으로 강제 로그 아웃
    - 서버 장애/셧다운 (처리 불가)

4. 추가 기능

- 지정된 횟수만큼 로그인 실패시 로그인 잠금 기능(초기화 필요/일정시간동안 잠금)
- 자동입력 방지 기능
- 초기 비밀 번호 변경 기능
- 아이디 찾기
- 비밀번호 찾기

5. 보안 고려 사항

- 아이디는 6자 이상으로 한다.
- 패스워드는 대/소/숫자/특수 에서 3가지 이상의 조합으로 등록 하도록 한다.
- 로그인 실패 시 출력 멘트는 보안 이슈로 인해서 모호하게 출력해야 한다.
    - ex> 아이디/패스워드가 잘못되었습니다.

6. 추가 사항

- 세션 타임 아웃에 의한 로그아웃 시키고 이력을 저장하는 부분은 리스너로 등록된 객체에서 스프링 bean 에 접근해야 하기 때문에 보류(가능은 하나 별의미가 없어서 보류 처리)

2015년 8월 2일 일요일

awk 로 프로세스 상태를 확인하는 스크립트 만들기

linux 에서 시스템의 프로세스를 모니터링하는 스크립트를 awk 를 이용하여 작성 하였습니다. 

shell 에서 prop 파일을 읽어서 awk 스크립트를 이용해서 처리하는 구조 입니다.

총 3개의 파일로 구성되어 있고 추가적인 기능이 필요 한경우 awk  스크립트에 구현을 하면 됩니다 .


1. shell 파일 (disp.sh)


#!/bin/bash

set SCRIPT_PATH = '/home/user/util/'
awk -f ${SCRIPT_PATH}disp.awk ${SCRIPT_PATH}proc.prop
    


* script_path : 스크립트 패스가 있는 폴더를 설정하면 됩니다. 

2. prop 파일(proc.prop) 


# Title processKey 
tomcat tomcat

apache httpd

* 첫번째 필드는 표시될 이름 입니다. 
* 두번째 필드는 ps -ef 명령 실행시 찾을 문구 입니다.  

3.  awk 파일 ( disp.awk)


#!/bin/awk
#
# This Program is display WEB status

BEGIN {
    # width 66
    pFormat = "%12s|%12s|%14s|%10s|%12s|\n";
    pStar = "*****************************************************************"
    pBar  = "-----------------------------------------------------------------";

    print "";
    print pStar;
    print "*              Display WEB Applicatin Status                    *";
    print pStar; 
    printf(pFormat ,"PROCESS", "PID", "START TIME", "COUNT", "STATUS");
    print pBar;
}

# ROUTINE 
{
    #if ( $1 == "#" ) {
    if ( $1 ~ /^#/ || $1 == "") { 
        # print "Skip....";
    } else {
        cmd = "ps -e -o pid,start,command |grep " $2 " | grep -v grep" ;
        #system(cmd) | getline psResult;
        
        count = 0;
        while (cmd | getline line) {
            # print line;
            split (line , res, " ");
            if (count == 0 ) {
                pid = res[1];
                sTime = res[2];
            }    
            count++;
        }
        close(cmd)

        status= "     \033[1;31mUNKNOWN\033[0m";
        if( count > 0 ) {
            status = "ALIVE";
        }

        printf(pFormat , $1, pid, sTime, count, status); 
    }

}

END {
    print pBar;
    print pStar;
    print "";
}


* 프로세스에서 지정된 키워드를 가진 프로세스의 숫자를 세서 보여 줍니다.


실행을 하면 다음과 같은 결과를 출력하게 됩니다.
*************************************************************
*            Display WEB Applicatin Status                  *
*************************************************************
     PROCESS|        PID|   START TIME|    COUNT|     STATUS|
-------------------------------------------------------------
      tomcat|           |             |        0|    UNKNOWN|
      apache|         37|       5:39PM|      113|      ALIVE|
-------------------------------------------------------------

*************************************************************

프로세스의 상태와 개수및 시작 시간 그리고 하나도 발견이 안되는 경우  붉은 글씨로  UNKNOWN 으로 표시 하게 됩니다. 











2015년 7월 30일 목요일

Tomcat 서버 로그 롤링 하기 (쉘 스크립트 + cron)

기본 적으로 Tomcat의 catalina.out 로그는 롤링이 되지 않기 때문에 별도의 방법을 사용해야 합니다.

쉬운 방법은  shell 을 만들어  cron 에 등록하면 됩니다.

1.  catalina.out 을 오늘 날자로 백업 하고 현재 catalina.out  초기화 하기
2.  30일 이상되는 오래된 파일 삭제



#!/bin/bash

LOG_DIR="/usr/local/tomcat/logs"
EXPIREDAY="+30"

DATE=`date +%Y-%m-%d`
cp  $LOG_DIR/catalina.out $LOG_DIR/catalina.$DATE.out
cat /dev/null > $LOG_DIR/catalina.out

find "$LOG_DIR" -ctime $EXPIREDAY -exec rm -f {} \;



**
- 로그 폴더에 여러 파일이 섞어 있는 경우 삭제시 find 명령어에  -name 옵션을 사용하면 필터링이 가능합니다.

- 삭제 대신 이동을 하려면 find  명령어 마지막 부분을 변경하면 됩니다.

2014년 10월 21일 화요일

[ Tip] Mac에서 FileZilla 클라이언트가 화면 영역 밖으로 벗어난 경우 초기화 방법

이번에 파일질라가 클라이언트가 업데이트 문제인지 맥에서 화면 여역 밖으로 벗어 나는 경우가 발생하는 경우가 있다. (윈도우도 현상이 동한지 확인은 못했다.) 

이때 화면 중앙으로 초기화 하는 방법은 다음과 같다. 아래의 파일을 삭제해 주면 화면 중앙으로 초기화 하게 된다.

 /Users/[User]/.filezilla/filezilla.xml

또는 위의 파일을 열어서 아래의 부분을 수정해 주면 된다. 

<Setting name="Window position and size">0 18 24 944 665 </Setting>

 2번째 변수가 x,  3번째가 y 좌표 이므로 해당 값을 변경해 주면 된다. 

2014년 9월 16일 화요일

[css] input 필드의 입력 모드(한/영)를 제어 하는 ime-mode 속성 정리

input 필드의 입력 모드를 제어 하는 ime-mode  속성


input 필드에서 한/영 입력을 제어 하고 싶을때
css/style로 ime-mode 값을 설정 함으로써 제어가 가능하다.

속성은 다음과 같다.

auto (default) : 현재 모드 값을 사용한다.  한/영 변환 가능
inactive : 영문 모드로 자동 전환, 한/영 변화 가능
disabled : 영문 모드로 자동 전환 ,한/영 변환 불가
active : 한글 모드로 자동 전환, 한/영 변환 가능
deactivated: 한글기본, 한/영 전환 가능

ex> 영문/숫자만 입력하고 싶은 경우
<input type="text" name="name" value="" style="ime-mode:disabled;">


참조 : https://developer.mozilla.org/en-US/docs/Web/CSS/ime-mode

* 이 스타일 속성은 표준이 아니고 몇몇 브라우져에서는 정상 동작하지 않는 경우가 있으니 사용을 지양하는게 좋을것 같다. (크롬에서는 잘 동작하고 사파리에서는 정상 동작하지 않았다.)
* 가끔 가다가 특이한 케이스로 허용되지 않은 입력이 되는 경우가 있기 때문에 반드시 서버단에서 다시 확인을 해야 한다.

2014년 9월 11일 목요일

[javascript] jQuery에서 XML 파싱 하는 방법

jQuery 에서 xml 파싱하는 방법

<script>
function doSomething ( xmlData) {

    this.itemList = new Array();

    var xmlDoc = $.parseXML(xmlData);
    var $xml = $(xmlDoc);

    $xml.find('item').each(function (idx) {
        var item = new item(idx, $(this));
        this.itemList.push(item);
    });

    // 여기에서 파싱해서 만든 객체로 원하는 처리를 하면 됩니다.
}


var Item = function($xmlData) {
    var myItem = this;
    this.id = $xmlData.attr('id');
    this.type = $xmlData.attr('type');

    return myItem;
};

var xmlData = "<?xml version='1.0' encoding='UTF-8'?> " +
     "<Item id=‘id1’ type=‘triangle’>" +
     "</Item>" +
     "<Item id=‘id2’ type=‘square’>" +
     "</Item>" +
     "<Item id=‘id3’ type=‘circle’>" +
     "</Item>";
</script>

일반적으로 위와 같이 find 로 해서 each 로 사용하면 됩니다.
하지만 아래와 같이 item 엘리멘트가 상위와 하위에 중첩이 되어 있는 경우는
위 와 같은 방법은 문제가 생기게 됩니다.
find로 찾으면 상위에 있는것과 하위에 있는것을 모두 찾아 주기 때문에 다음과 같은 방법을 이용 하면 됩니다.

<script>
function doSomething ( xmlData) {

    this.itemList = new Array();
    this.groupList = new Array();

    var xmlDoc = $.parseXML(xmlData);
    var $xml = $(xmlDoc);

    $xmlData.children().each(function(idx1) {
        var eName = $(this)[0].tagName;

        if (eName == "Item) {
            var item = new Item($(this));
            this.itemList.push(item);
        } else if (eName == "Group") {
            var group = new Group($(this));
            this.groupList.push(group);
        }
    });


    // 여기에서 파싱해서 만든 객체로 원하는 처리를 하면 됩니다.
}


var Item = function($xmlData) {
    var myItem = this;

    this.itemList = new Array();
    this.groupList = new Array();

    this.id = $xmlData.attr('id');
    this.type = $xmlData.attr('type');


    $xmlData.children().each(function(idx1) {
     var eName = $(this)[0].tagName;

     if (eName == "Item) {
     var item = new Item($(this));
     this.itemList.push(item);
     } else if (eName == "Group") {
     var group = new Group($(this));
     this.groupList.push(group);
    }
  });

    return myItem;
};

var Group = function($xmlData) {
    var myGroup = this;
   
    this.itemList = new Array();
    this.groupList = new Array();

    $xmlData.children().each(function(idx1) {
        var eName = $(this)[0].tagName;
    
        if (eName == "Item) {
            var item = new Item($(this));
            myGroup.itemList.push(item);
        } else if (eName == "Group") {
            var group = new Group($(this));
            myGroup.groupList.push(group);
        }
    });

    return myGroup;
};

var xmlData = "<?xml version='1.0' encoding='UTF-8'?> " +
  "<Item id='id1' type='triangle'>" +
  "    <Group>" +
  "        <Item id='id1_sub1' type='triangle_sub'>" +
  "        </Item>" +
  "        <Item id='id1_sub2' type='triangle_sub'>" +
  "        </Item>" +
  "    </Group>" +
  "</Item>" +
  "<Item id='id2' type='square'>" +
  "</Item>" +
  "<Item id='id3' type='circle'>" +
  "</Item>";
</script>


** 더 좋은 방법이 있으면 조언 부탁드립니다. 

2014년 8월 6일 수요일

Tomcat 설치 후 보안 조치 기본 사항

Tomcat 설치 후 보안 조치 기본 사항


1.  log file 권한 설정 
로그 파일및 폴더 의 권한을 750 이하로 유지 한다.
이 값은  umask 값과 관련 있기 때문에 톰캣을 실행 하는 계정의 umask 값을 027 으로 설정한다.

설정은 계정의 shell 에 설정해도 되고 보통 tomcat 의 기동 스크립트에 아래의 명령을 넣어 준다.
umask 027

* 계정 공통 : /etc/profile  에 설정이 가능한다.


2. 불필요한 파일 제거

$tomcat/webapps 아래에 불 필요한 폴더를 제거 한다.

 - examples
 - docs


3. 관리자 폴더 권한 변경 

$tomcat/webapps  아래 관리자용 폴더들의 권한을 제한 한다.

host-manager, manager 폴더의 권한에서 other s 의 권한을 제거 한다.
아래 명령어를 통해서 others 의 권한을 제거 한다.

chmod -Rf o-rwx host-manager
chmod -Rf o-rwx manager

* 옵션 설명
    -Rf : 하위 폴더를 강제로 모두 적용
    o-rwx : others 의 rex 권한을 제거 한다.
* 보통 chmod 750 ./* 같은 명령어를 사용하는 경우 권한이 추가될수 있기 때문에 사용을 지양한다.

4. 로그 포맷 설정

log 파일의 포맷 pattern 설정을 combined로 설정

$tomcat/conf/server.xml 파일 설정 



2014년 6월 30일 월요일

[SVG] SVG element의 class 값을 jquery 이용해서 변경하기


SVG 의 element 의 class 변경 하기

이러한 경우  jQuery 에서 제공하는 removeClass/addClass  메소드가 동작하지 않는다.

변경하는 방법은 다음과 같다.

$('#elementId').attr('class', 'changeClass');

여러개를 적용 하려면 다음과 같이 여러개의 클래스명을 사용하면 된다.

$('#elementId').attr('class', 'changeClass1 changeClass2');


** 기존의 class 를 통째로 교체 하기 때문에 필요한 클래스를 모두 써줘야 한다.

2014년 6월 16일 월요일

[JavaScript] this 의 용법

this 키워드는 JavaScript 코드를 가지고 있는 객체를 지칭한다. 
function에서 사용 되는 경우 그 function 을 가지고 있는 객체를 지칭하고 객체에서 사용하면 객체 자체를 가르킨다. 

<script>
function Person (name, age) {
    this.name = name;
    this.age = age;

    this.sayHello = function () {
          var name = "Person";
          return this.name +  " : Hello " + name + ".";
    }
}

var smith = new Person("smith", 37);
console.log (smith.sayHello ()); // smith : Hello Person.
</script>

위의 예제에서 출력 결과는 "smith : Hello Person.”이다.


Person 바로 아래에 있는 this 는 현재 코드를 소유한 객체(smith)를 지칭하게 되고 sayHello 아래에서 this 는 function 소유한 객체를 가키게 된다. 즉, smith 이다.
따라서 sayHello 함수에서의 this는 함수 자신이 아닌 smith이다. 그래서 this.name은 “smith” 가 되고 name은 함수 내부의 변수 “Person”을 가르키게 된다. 

이와 비슷한 형태로 혼동하기 쉬운 상황이 있다. 

<script>
function civil() {
    var name = "Neo";

    function sayMyName() {
         console.log ("name : " + name); // name : Neo
         console.log ("this.name : " +  this.name); // this.name : 
    }
    sayMyName();
}
    
civil();
</script>

이와 같은 경우는 function 에서 사용되는 경우이다. 
현재 civil() 을 실행 시키는 주체 window 이므로 코드를 소유한 객체는 window 가 된다 따라서 this 키워드는 window 객체를 가르 키게 된다. 
따라서 이 경우 this.name 은 내용이 없어서 안찍게 된다. 
실제로  civil(); 을 window.civil(); 로 해도 동일하게 동작하게 된다.