2011. 7. 14. 08:24 IT
// 예전에 쓴 자료 (2004) // 기록을 위해 남깁니다. 

클라이언트의 정보를 얻는 방법은

http request에서 제공되는 정보, client 스크립트(자바스크립트,VB스크립트)에서 제공해주는 정보, Form에서 전송되는 고객이 선택한 정보. 이 세가지가 일반적이고 그 이상의 정보를 얻기 위해서는 applet, activeX 등을 직접 제작해야  합니다.

 

1. 먼저 다국어와 로케일시간을 처리하는 방법을 보자면

단순한 쿠키세팅값을 읽어와 출력해주는 것입니다.

-----------
timeNameObj = new Array("사모아", "하와이",
 "알래스카", "태평양 표준시",
 "애리조나", "미국(중부)",
 "미국(동부)", "상파울로",
 "브라질리아", "중부-대서양",
 "아조레스", "런던",
 "로마", "아테네",
 "모스크바", "두바이",
 "이슬라마바드", "아스타나",
 "자카르타", "북경",
 "서울", "시드니",
 "마가단", "오클랜드");
timeObj = new Array("GMT-11","GMT-10","GMT-9","GMT-8","GMT-7","GMT-6","GMT-5","GMT-4","GMT-3","GMT-2","GMT-1","GMT","GMT+1",
 "GMT+2","GMT+3","GMT+4","GMT+5","GMT+6","GMT+7","GMT+8","GMT+9","GMT+10","GMT+11","GMT+12");

// body on Load시 호출
f unction init(){
  saveTimezone = getCookie("saveTimezone");
  for (i=0;i<24;i++) {
    if (saveTimezone==timeObj[i]) {
      xform.TIMEZONE2.value = timeNameObj[i] + " (" + timeObj[i] + ")";
    }
    else
      xform.TIMEZONE2.value = timeNameObj[20] + " (" + timeObj[20] + ")";
  }
}
----------------------

위의 내용을 설명하자면 자바스크립트 배열로 GMT시간을 저장해놓고

saveTimezone 이란 이름의 쿠키에 값이 있는경우 해당 값을 화면에 출력해주는 것입니다.

쿠키에 값이 없는 경우엔 디폴트로 20번 배열(한국)을 보여줍니다.

 

다국어 처리도 마찬가지군요

<select name="LANG">
  <OPTION value="en_US.EUC-KR" >영어</OPTION>
  <OPTION value="ko_KR.EUC-KR" selected>한국어</OPTION>
  <OPTION value="ja_JP.SJIS" >일본어</OPTION>
  <OPTION value="zh_CN.GB2312" >중국어</OPTION>
</select>

기본값을 영어로 하고 쿠키에 셋팅되어있는 값을 읽어 언어 로케일을 설정한뒤
이 값을 가지고 이후에 resource bundle에 적용하게 됩니다.

 

2. resource bundle을 사용하는 방법
 먼저 언어별 properties file을 생성. (test.properties, test_fr.properties, test_de.properties )
 
 java application에서 bundle 사용 코드 작성
 ---------------------
 ResourceBundle labels = null;
 
 String localeString = "fr"; // 프랑스어로 설정
 
 Locale currentLocale = new Locale(localeString);
 
 labels = ResourceBundle.getBundle("test",currentLocale);

 String value  = labels.getString("xxx");
 
 localeString = "de"; // 독일어로 변경
 
 labels = ResourceBundle.getBundle("test",currentLocale);

 보다 자세한 내용은 .. http://java.sun.com/jdc/TechTips/1998/tt0521.html#tip2

 

3. 그러나 실제로 web application의 경우 ResourceBundle 클래스를 바로 쓰지 않고
 struts 의 경우와 같이 MessageResources 클래스를 이용합니다.
 (struts site를 참조하세요 ) http://jakarta.apache-korea.org/struts/doc-1.0.2/userGuide/building_view.html

 

posted by smplnote
2011. 7. 8. 14:07 IT
Cross Platform을 위해 기존 파일 업로드 모듈을 변경하게 되었다. 

기존 ActiveX 모듈이 제공하는 기능은 다음과 같다.
- Drag & Drop 
- 첨부갯수, 용량제한 지원
- 이미지 업로드 연계 (게시판에서 전달한 인자를 이용하여 추가 업로드 수행)
- 첨부제외 파일 확장자 리스트 지원
- 업로드시 프로그레스 바 제공
- 다운로드시 일괄 파일저장 기능 제공 

우선 웹표준을 적용할때 제공할 수 없는 것을 정리해보면
- Drag & Drop ( 로컬 파일에 대해서는 보안위배사항)
- 용량제한 확인 불가 (역시 로컬 접근이 안되므로 서버 측에서 검사해야함)
- 이미지 업로드 연계 불가 ( file type 의 input 은 value 값이 readOnly 다. 역시 보안상의 이유)
- 프로그레스바 미제공 (이건 좀 찾아보면 나올지도... )
- 일괄파일 저장 기능 미지원 ( 이것도 좀 트릭을 쓰면 될지도... )

하여튼 이런저런 시간 낭비를 거쳐 마침내 대충 정리했다. 

적용 솔루션은 다음과 같다.
1. UI : jquery , multiple-file-upload plugin 
http://www.jquery.com 
http://www.fyneworks.com/jquery/multiple-file-upload
 
2. Server : com.oreilly.servlet
http://www.servlets.com/cos/

- 준비물 
jquery.js , jquery.MultiFile.js , WEB-INF/lib/cos.jar

- 등록 페이지
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.MultiFile.js"></script>
<script>
function upload(){
        var fileTags = document.body.getElementsByTagName('input');
var arr = new Array();
var cnt = 0;
for (var tg = 0; tg< fileTags.length; tg++) {
   var tag = fileTags[tg];
   if (tag.name =='Filename') {
    tag.name = tag.id;   // tag.name이 모두 Filename 으로 된 것을 바꾸도록 처리함 (MultiFile.js 의 버그? )
    }
}
        document.getElementById("
frmFile").submit(); 
}
function  onUploadDone(msg){
   alert(msg);
</script>
<!-- 업로드용 폼 --> 
<form name="frmFile" action="your_server_page" 
    id="frmFile" method="post" 
    target="upload_target" encoding="multipart/form-data" enctype="multipart/form-data">
    <!-- 업로드용 file input -->
    <input class="multi"  type="file"  id="Filename" name="Filename"
              accept="jpg|png|gif|tif|xls|doc|hwp|int|zip" style="width:400">
    <!-- 업로드 타겟용 frame --> 
    <iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;">
    <input  type="button" value="upload" onclick="upload();"/>
</iframe>

- 서버측
<%@ page language="java" contentType="text/html; charset=utf-8" import="com.oreilly.servlet.*" %>
<%
String fileDir = "/upload";
String encoding = "euc-kr";

int attachSize = 1; // Megabyte
String retVal = "":
if(request.getContentLength()>attachSize* 1024 * 1024){
        retVal = "upload file size is over";
}else{
        MultipartRequest mr = new MultipartRequest(request, fileDir, request.getContentLength(),
encoding,new DefaultFileRenamePolicy());
        Enumeration fileNames = mr.getFileNames();
        List fileInputNames = new ArrayList();
        while(fileNames.hasMoreElements()) {  
         String str = fileNames.nextElement().toString();
                fileInputNames.add(str);
        }
        for(int i=0;i<fileInputNames.size();i++){
                String inputName = (String)fileInputNames.get(i);
                String fileNm = mr.getFilesystemName(inputName);
                File file = mr.getFile(inputName);
                String orgFileName = mr.getOriginalFileName(inputName);
                retVal += fileName +" ";
        }
}
out.print("<script>parent.onUploadDone('" + retVal + "');</script>"); 
%>



[기타 기록사항]
- ajax form 비정상 작동 : ajax form 을 이용하려고 했으나 어떤 이유인지 모르지만 정상적으로 파일을 전달하지 못했다. 별수없이 iframe을 직접 작성했다. 
- multifile.js 의 name 동일성 문제 : id는 XXX1, XXX2 처럼 늘어나는데 name은 XXX, XXX 로 되는 버그가 있다. 
- file type의 input은 보안상의 이유로 value 값을 readonly로만 지원한다. 따라서 외부 게시판을 이용한 이미지 업로드 와 같은 기능은 적용할 수 없다.
- cos.jar 대신에 apache common-fileupload 를 이용하는 경우도 많은데, 내 경우에는 이미 기존에 cos.jar 를 잘 사용하고 있었고, 중복 파일에 대한 처리기능을 별도로 구현하기 귀찮고... 추가로 필요한 기능은 없어서 기존 코드를 그대로 재사용 했다.
 

 
posted by smplnote
2011. 6. 20. 16:46 IT

web.xml 에서 명시적으로 log4j 설정파일 경로를 명시하여 작업하는 경우
junit만 실행할때는 web.xml 을 참조하지 않고 실행되므로
다음과 같은 에러 메세지가 콘솔에 찍힌다. (당연히 눈에 거슬린다.)

log4j:WARN No appenders could be found for logger(...

해결책으로는 
test 소스 폴더의 디폴트 패키지 위치에 log4j.properties 를 두면 끝.

출처 : http://blog.naver.com/goethe1004/80034130033
posted by smplnote
2011. 5. 28. 11:06 IT

java.util.Hashtable은 map객체 안의 null값을 저장하지 못함
따라서 hashtableVariable.putAll(map)은 예외를 던질수 있다.

방법1. map에 널값이 저장되지 않게 한다 ex) IsNull(xx,"")  또는 ORMapping때는 공백치환처리 (QueryService의 NullChecks 와 같은 방식)

방법2. map을 hashtable에 옮길때 putAll 대신 루프를 돌리면서 널값체크해서 처리를 한다.

cf) 가능하면 Hashtable 을 사용하는 방식 자체를 지양해라. 구습 아닌가!!!
 


cf) Anyframe QueryService를 사용하면 VARCHAR, CHAR type에 대해서는 NullChecks를 이용하여 Null을 빈문자열로 자동 치환해주는데, 숫자타입이나 LOB 타입을 null로 반환된다.
(왜 구현을 안한걸까?)
 
posted by smplnote
2011. 5. 25. 18:48 IT
jenkins 
이전까지 hudson으로 알려져 있던 build server
반복적인 작업들의 실행을 모니터링 해준다.  ( from https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins )

site : http://jenkins-ci.org/ 
version : 1.413

cf) window service 등록을 금지하는 경우 윈도우용 installer를 사용해선 안됨
jdk : 1.6 이상 1.5에서는 오류 메시지 발생

주요 argument ( from http://winstone.sourceforge.net/#commandLine )
JENKINS_HOME : war가 풀릴 공간. default는 ${user.home}/.jenkins
--httpPort : default 8080
--ajp13Port : default 8009 , no use -1
--logfile : 콘솔 로그를 redirect 하여 저장할 파일 

실행스크립트 샘플 (윈도우용 => 서비스 등록하는게 더 편하지만 여건상 안되서.. )
set JENKINS_HOME=c:\my
set JAVA_HOME=c:\my\jdk1.6.0_25
set PATH=%JAVA_HOME%\bin
set HTTP_PORT=6666
set AJp13PORT=9999
set WEBROOT=c:\my\mywebroot
set LOGFILE=c:\my\log.log
start "jenkins" /B /d c:\my -jar c:\jenkins.war --httpPort=%HTTP_PORT --ajp13Port=%AJP13PORT% --webroot=%WEBROOT% --logfile=%LOGFILE%


 
posted by smplnote
2011. 5. 24. 18:43 IT
spring log level 변경

개발용으로 spring context를 매번 로딩하게 했더니 디버그성 로그 지나가는게 눈에 거슬렸다.

log4j.properties 파일에 다음과 같이 추가하여 레벨을 조정해주자
log4j.logger.org.springframework=WARN



posted by smplnote