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

  1. 2011.07.26 오라클 숫자를 한글로 표시 (금액단위) 1
  2. 2011.07.15 [XSS 취약점 보완] Cross Site Scripting 방지 기법 - Commons Lang
  3. 2011.07.11 jsp, java 한글 깨짐현상
  4. 2011.07.11 리눅스 시간 않맞을때 설정방법
  5. 2011.07.05 Open User Interface Framework
  6. 2011.07.04 erwin 사용법 동영상
  7. 2011.06.12 ie fe div 가운데 영역 보이기
  8. 2011.06.11 ie9 에서 smarteditor 영역이 보이지 않을경우...
  9. 2011.06.11 [tomcat 4.x -> 5.x 올리기 -2-] Attribute value java.net.URLEncoder.encode("한글") is quoted h " which must be escaped when used within the value
  10. 2011.06.11 톰캣 6.0 에서 웹사이트 여러개 운영하기 (2)
  11. 2011.06.03 우리은행 웹접근성 가이드라인
  12. 2011.05.09 Apache HTTP Server Version 2.3 문서
  13. 2011.03.15 Spring MVC
  14. 2011.03.15 spring 동영상 강좌 정리노트
  15. 2011.03.08 Spring MVC Annotation
  16. 2011.02.22 숫자를 한글로 반환
  17. 2011.02.14 spring 3.0 mvc 설정 간편화
  18. 2011.02.12 request 값 변경 1
  19. 2011.02.10 linux java 수동설치, Java Runtime Environment(JRE)에 대한 Linux x64 RPM 다운로드 및 설치 지침
  20. 2011.02.08 virtualbox ubuntu10 해상도 설정
  21. 2011.02.07 Developing a Spring Framework MVC application step-by-step
  22. 2011.02.07 [유틸리티] Google에서 만든 Javascript 최적화 및 압축도구 Closure Compiler
  23. 2011.01.18 웹접근성 웹개발시 쓰고 파이어폭스 플러그인 1
  24. 2011.01.18 XHTML Strict에서 target="_blank" 속성 사용법
  25. 2011.01.18 웹 표준, 추천도서
  26. 2011.01.05 IE inerText -> EE innerHTML
  27. 2011.01.04 웹 접근성 도구 모음
  28. 2010.12.30 자바스크립트 사용 예
  29. 2010.12.21 w3c img tag 에 onclick="javascript:self.close();" 문제점
  30. 2010.12.21 Tidy: character ";" not allowed in attribute specification list
02.Oracle2011. 7. 26. 14:55
반응형


CREATE OR REPLACE FUNCTION FN_NUM2HAN(n_number NUMBER)
RETURN VARCHAR2 AS
    n_unit   NUMBER;
    n_length NUMBER;
    v_prev   VARCHAR2(8);
    v_digit  VARCHAR2(8);
    v_number VARCHAR2(150);
    v_return VARCHAR2(150);
BEGIN
    -- [ Usage ]
    -- SELECT FN_NUM2HAN(125670000           ) FROM DUAL; -- 일억이천오백육십칠만
    -- SELECT FN_NUM2HAN(100000000           ) FROM DUAL; -- 1억
    -- SELECT FN_NUM2HAN(1000000000000       ) FROM DUAL; -- 1조
    -- SELECT FN_NUM2HAN(1000000000000000    ) FROM DUAL; -- 1000조
    -- SELECT FN_NUM2HAN(10000000000000000000) FROM DUAL; -- 1000경
    IF n_number = 0 AND n_number < 0 THEN
        RETURN '영';
    END IF;
    n_unit   := 0;
    v_number := LTRIM(TO_CHAR(n_number,'99999999999999999999'));  -- 천경
    n_length := LENGTH(v_number);
    v_digit  := NULL;
    FOR i IN 1 .. n_length LOOP
        v_prev  := v_digit;
        v_digit := SUBSTR(v_number, n_length-i+1, 1);
        IF v_digit = '1' THEN v_digit := '일'; END IF;
        IF v_digit = '2' THEN v_digit := '이'; END IF;
        IF v_digit = '3' THEN v_digit := '삼'; END IF;
        IF v_digit = '4' THEN v_digit := '사'; END IF;
        IF v_digit = '5' THEN v_digit := '오'; END IF;
        IF v_digit = '6' THEN v_digit := '육'; END IF;
        IF v_digit = '7' THEN v_digit := '칠'; END IF;
        IF v_digit = '8' THEN v_digit := '팔'; END IF;
        IF v_digit = '9' THEN v_digit := '구'; END IF;
        IF v_digit = '1' THEN v_digit := '일'; END IF;
        IF v_digit = '0' THEN v_digit := NULL; END IF;
        -- DBMS_OUTPUT.PUT_LINE(' DIGIT : [' || v_digit || ']');
        -- DBMS_OUTPUT.PUT_LINE(' DEBUG : [' || i || '/' || i || ']');
        IF v_digit IS NOT NULL THEN
            IF MOD(i, 4) = 2 THEN
                v_digit := v_digit || '십';
            END IF;
            IF MOD(i, 4) = 3 THEN
                v_digit := v_digit || '백';
            END IF;
            IF MOD(i, 4) = 0 THEN
                v_digit := v_digit || '천';
            END IF;
        END IF;
        IF (v_digit IS NOT NULL AND i = 5) OR  --
           (v_digit IS NOT NULL AND v_prev IS NULL AND i > 5 AND i<9) THEN
            v_digit := v_digit || '만';
        END IF;
        IF (v_digit IS NOT NULL AND i = 9) OR
           (v_digit IS NOT NULL AND v_prev IS NULL AND i > 9 AND i<13) THEN
            v_digit := v_digit || '억';
        END IF;
        IF (v_digit IS NOT NULL AND i =13) OR
           (v_digit IS NOT NULL AND v_prev IS NULL AND i >13 AND i<17) THEN
            v_digit := v_digit || '조';
        END IF;
        IF (v_digit IS NOT NULL AND i =17) OR
           (v_digit IS NOT NULL AND v_prev IS NULL AND i >17 AND i<21) THEN
            v_digit := v_digit || '경';
        END IF;
        IF v_digit IS NOT NULL THEN
            v_return := v_digit || v_return;
        END IF;
        IF MOD(i,4) = 4 THEN
            n_unit := n_unit + 1;
        END IF;
    END LOOP;

    --DBMS_OUTPUT.PUT_LINE('[' || v_return || ']');
    RETURN v_return;
EXCEPTION
    WHEN OTHERS THEN v_return := SQLCODE;
    RETURN v_return;
END;
/

 SELECT FN_NUM2HAN(125670000           ) FROM DUAL;

Posted by 1010
01.JAVA/Java2011. 7. 15. 21:21
반응형

Apache Commons를 활용한 예
http://blog.naver.com/phrack?Redirect=Log&logNo=80086347596

Struts Taglib을 활용한 예
http://blog.naver.com/phrack?Redirect=Log&logNo=80053722854

Struts Response Utils를 활용 한 예
http://blog.naver.com/phrack?Redirect=Log&logNo=80053722954

JSTL을 활용한 예
http://blog.naver.com/phrack?Redirect=Log&logNo=80053722757

---------------------------------------------------------------------------­----------------------

Posted by 1010
01.JAVA/Java2011. 7. 11. 15:43
반응형

System.out.println("===========================================================================");
   String param = request.getParameter("viewComment");    // 테스트해보고 싶은 파라미터를 지정하세요.
   System.out.println("[TEST] 변환전: " + param);
   String charset[] = {"8859_1", "ascii", "UTF-8", "KSC5601", "EUC-KR", "MS949"};
   for(int i=0; i<charset.length ; i++){
       for(int j=0 ; j<charset.length ; j++){
           if(i==j){
               continue;
           } else{
            System.out.println("[TEST] "  + charset[i]+" : "+charset[j]+" :" +new String (param.getBytes(charset[i]),charset[j]));
           }
       } // inner for
   } // outer for
   System.out.println("===========================================================================");
Posted by 1010
61.Linux2011. 7. 11. 15:01
반응형
date

rdate -s time.bora.net
Posted by 1010
반응형


Browser Compatibility

  • Internet Explorer 6~8
  • Firefox Latest Version
  • Safari Latest Version
  • Chrome Latest Version
  • Opera Latest Version

OUIF SVN Checkout

OUIF Map

  1. Default Set
    1. HTML 4.01 Transitional
    2. XHTML 1.0 Transitional
    3. HTML5 | HTML5 enable script
    4. CSS
    5. jQuery
  2. CSS Selector Rules
    1. Naming Guide
    2. Logical Usage
  3. CSS Framework For Layout
    1. XE CSS Framework For Layout | Manual
  4. CSS3 References
  5. Icon Library
    1. Fugue (Preview) - 2,627 icons 16x16, 24x24 (Creative Commons Attribution 3.0 License)
    2. FAMFAMFAM (Preview)- 700 icons 16x16 (Creative Commons Attribution 3.0 License)
    3. Icon Finder - Free Icons
    4. Find Icons - Free Icons
    5. Icon Pedia - Free Icons
  6. User Interface Object
    1. Box
      1. Regular - quirks | html | xhtml | html5
    2. Button
      1. Button Area - quirks | html | xhtml | html5
      2. Single - quirks | html | xhtml | html5
      3. Package - quirks | html | xhtml | html5
    3. Calendar
      1. jQuery Datepicker - quiks | html | xhtml | html5
    4. Editor
      1. SmartEditor Basic - Demo | Skin | Download
    5. Form
      1. Form Table - quirks | html | xhtml | html5
      2. Log-in
        1. Modal Windowed Login - quirks | html | xhtml | html5
      3. Registration - quirks | html | xhtml | html5
      4. Search
        1. Regular - quirks | html | xhtml | html5
    6. Graph & Progress & Loading
      1. Horizontal - quirks | html | xhtml | html5
      2. Inline - quirks | html | xhtml | html5
      3. Vertical - quirks | html | xhtml | html5
      4. Loading Icon - quirks | html | xhtml | html5
      5. Modal Windowed Loading - quirks | html | xhtml | html5
      6. Modal Windowed Progress - quirks | html | xhtml | html5
    7. Layer
      1. Modal Windowed Layer - quirks | html | xhtml | html5
    8. List
      1. Text
        1. UL(Unordered List) - quirks | html | xhtml | html5
        2. OL(Ordered List) - quirks | html | xhtml | html5
      2. Image
        1. Fixed Image Col - quirks | html | xhtml | html5
        2. Flexible Image Col - quirks | html | xhtml | html5
        3. Fixed Image Row - quirks | html | xhtml | html5
        4. Flexible Image Row - quirks | html | xhtml | html5
      3. FAQ - quirks | html | xhtml | html5
    9. Navigation
      1. Skip Navigation - quirks | html | xhtml | html5
      2. Horizontal
        1. Bar - quirks | html | xhtml | html5
        2. Lined Tab - quirks | html | xhtml | html5
        3. Faced Tab - quirks | html | xhtml | html5
        4. List Tab - quirks | html | xhtml | html5
      3. Pagination
        1. Regular - quirks | html | xhtml | html5
        2. Simple - quirks | html | xhtml | html5
        3. Complex - quirks | html | xhtml | html5
      4. Vertical
        1. Bar - quirks | html | xhtml | html5
        2. Tree - quirks | html | xhtml | html5
    10. Select - quirks | html | xhtml | html5
    11. Star Rating
      1. Regular - quirks | html | xhtml | html5
    12. Table
      1. Multiple Header - quirks | html | xhtml | html5
    13. Tag Cloud - quirks | html | xhtml | html5

Posted by 1010
90.개발관련문서2011. 7. 4. 13:58
반응형
Posted by 1010
03.HTML 4.X, HTML5, XML...2011. 6. 12. 16:25
반응형


<script type="text/javascript">
  function loginLayerOn(id){
   if (document.getElementById(id).style.display == "inline"){ 
    document.getElementById(id).style.display = "none";   
   }else{
    var cfmOllehLayerPopUp340 = document.getElementById(id);
    var tmpTop = 0;
     if(browser() == "Chrome" || browser() =="MSIE 5.5"){
      tmpTop = document.body.scrollTop;
     }else if(browser() =="Safari"){
      tmpTop = window.pageYOffset ;
     }else{
      tmpTop = document.documentElement.scrollTop;
     }
     cfmOllehLayerPopUp340.style.position = "absolute";
     cfmOllehLayerPopUp340.style.display = "inline";
     cfmOllehLayerPopUp340.style.left = document.body.clientWidth/2 - cfmOllehLayerPopUp340.offsetWidth/2 + "px";
     cfmOllehLayerPopUp340.style.top = document.body.clientHeight/2 - cfmOllehLayerPopUp340.offsetHeight/2 + tmpTop + "px";
   }
  }

 function browser() {
   var appAgent = navigator.userAgent;
   var returnStr ;
   if (appAgent.indexOf('MSIE 8.0')>0)  returnStr  =  "MSIE 8.0";
   if (appAgent.indexOf('MSIE 7.0')>0)  returnStr  =  "MSIE 7.0";
   if (appAgent.indexOf('MSIE 6.0')>0)  returnStr  =  "MSIE 6.0";
   if (appAgent.indexOf('MSIE 5.5')>0)  returnStr  =  "MSIE 5.5";
   if (appAgent.indexOf('MSIE 5.0')>0)  returnStr  =  "MSIE 5.0";
   if (appAgent.indexOf('Chrome')>0)  returnStr  =  "Chrome";
   if (appAgent.indexOf('Firefox')>0)  returnStr  =  "Firefox";
   if (appAgent.indexOf('Chrome')<0 && appAgent.indexOf('Safari')>0) returnStr  =  "Safari";
   return returnStr;
 }
 </script>


<Div id="pop" style="position:absolute;left:10px; top:12px; width:100px; height:70px;z-index:1;display:none;BACKGROUND: red">
내용 들어가는 부분
</Div>

<a href="#" onclick="loginLayerOn('pop');"><img src="/images/egovframework/sosang/topmenu/main_menu01_off.gif" width="80" height="30" border="0" alt="정책정보" /></a>

Posted by 1010
03.HTML 4.X, HTML5, XML...2011. 6. 11. 19:49
반응형

//if(this.bIE){button=document.createElement("<BUTTON type='button'>");}
if(navigator.appVersion.indexOf("MSIE 9") > -1){ button=document.createElement("BUTTON");button.type="button"; } else if(this.bIE){button=document.createElement("<BUTTON type='button'>");}


ie9에서는 문법이 맞지 않아서 생긴다.
Posted by 1010
03.HTML 4.X, HTML5, XML...2011. 6. 11. 18:07
반응형

Attribute value java.net.URLEncoder.encode("한글") is quoted h " which must be escaped when used within the value

위와 같은 로그가 쌓이면서 태그 라이브러리 형태의 jsp 코드에서 에러가 발생할 경우...

tomcat/conf/catalina.properties 의 맨 마지막 줄에 다음의 한 줄을 추가!

org.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false


Posted by 1010
52.Apache Project &...2011. 6. 11. 17:18
반응형
톰캣 6.0 에서 웹사이트 여러개 운영하기 (2)


톰캣에서 하나의 IP로 여러개의 웹사이트를 운영하는 방법은 2가지가 있다.


# 가상 호스트(Virtual Host)를 이용하는 방법
# IP Address의 port를 여러개 사용하는 방법


여기서는 가상 호스트를 이용하여 톰캣에서 여러개의 웹사이트를 운영하는 방법에 대해서 설명하고자 한다.
설치 환경은 다음과 같다.


* O/S : Windows XP (Windows Server 동일)
* Tomcat 6.0.10


설명의 편의를 위해 톰캣의 설치 디렉토리는 'TOMCAT_HOME' 으로 표기할 것이다. 참고로 내 경우는 C:\Server\Tomcat6.0 이다.

설정하는 방법은 /TOMCAT_HOME/conf/에 있는 server.xml 파일만 수정하면 된다. server.xml의 쓸데없는 주석부분을 다 없애고 관련 부분만 남겨놓으면 아래와 같다.

<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>

</Engine>
</Service>


위의 내용에서 핵심 부분은 <Host></Host> 영역이다.

1. 우선 <Connector port="8080" protocol="HTTP/1.1" 부분의 port를 80으로 수정한다.
도메인명이 기본으로 80포트를 사용하기 때문이다.

2. <Host>... </Host> 에 해당하는 부분을 복사하여 2개를 만든다. 그리고 이렇게 수정하자.



<Host name="www.myweb1.com" appBase="d:/webapps/myweb1"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>

<Host name="www.myweb2.com" appBase="d:/webapps/myweb2"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>


appBase="webapps" 는 톰캣의 기본 웹루트인 TOMCAT_HOME/webapps 디렉토리를 가르킨다. 웹사이트를 원하는 디렉토리에 두고 싶다면 d:/webapps/myweb1 처럼 자기가 지정하고 싶은 곳으로 수정하면 된다.

3. 마지막으로 웹사이트들의 ROOT 디렉토리를 지정해주자. 아래의 폴더를 생성한다.

d:/webapps/myweb1/ROOT/
d:/webapps/myweb1/ROOT/WEB-INF/

d:/webapps/myweb2/ROOT/
d:/webapps/myweb2/ROOT/WEB-INF/

그리고 WEB-INF 폴더 밑에 각각 web.xml 파일을 추가한다. 그냥 /TOMCAT_HOME/webapps/ROOT/WEB-INF/에 있는 web.xml 을 복사하면 된다.

4. 테스트하기 위해 ROOT/index.html 또는 index.jsp를 만든다.

이제 톰캣을 재시작하고 웹브라우저로 접속해 보자.
http://www.myweb1.com
http://www.myweb2.com

정말 간단하지 않은가?
톰캣 6.0에서 웹사이트 여러개 운영하기 (1)
아파치와 연동없이 톰캣만으로도 하나의 IP로 다수의 웹사이트를 운영하는 것이 가능하다.
(아파치와 톰캣을 연동하는 방법에 대해서는 차후에 자세히 올리도록 하겠다)

특히 개발자의 경우 여러개의 프로젝트를 개발하거나 테스트하고자 할 때 웹사이트를 여러개 운영해야한다. 다수의 웹 사이트를 세팅하는 방법은 크게 2가지가 있다.


* 가상호스트를 이용하는 방법
* IP Address의 port를 여러개 사용하는 방법


가상호스트를 이용하는 방법은 도메인을 이용하여 실제로 서비스를 운영하는 경우가 아니면 개발자에겐 별 의미가 없다. 여기서는 두번째 방법인 IP 어드레스의 포트를 이용하는 방법에 대해서 설명하겠다. (바로가기 : 톰캣에서 가상 호스트를 이용하는 방법)
우선 설치 환경은 다음과 같다.


* O/S : Windows XP (난 아직 리눅스를 잘 모른다. 비슷하겠지만 테스트해보지 않았다)
* Tomcat 6.0 (정확히는 6.0.10) : 다운로드


설명의 편의를 위해 톰캣의 설치 디렉토리는 'TOMCAT_HOME' 으로 표기할 것이다. 참고로 내 경우는 C:\Server\Tomcat6.0 이다.

설정하는 방법은 간단하다. /TOMCAT_HOME/conf/에 있는 server.xml 파일만 수정하면 끝이다. server.xml의 쓸데없는 주석부분을 다 없애고 핵심부분만 남겨놓으면 아래와 같다.


<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>

</Engine>
</Service>



우선 빨간색으로 표시한 부분만 이해하고 넘어가도 상관없다.
Connector port="8080"은 HTTP로 넘어오는 포트를 지정하는 것이다. 톰캣의 기본 포트가 8080인 이유가 여기에 있다. 따라서 8080 대신 기본 80포트를 사용하고 싶다면? 바로 이 부분을 port="80"으로 바꾸어주면 된다.

다음, Host 지시어의 appBase="webapps" 는 웹어플리케이션(웹사이트)의 위치를 나타낸다. appBase="./webapps"와 같은 의미다. 실제 위치는 TOMCAT_HOME/webapps이다. 물론 "d:/weapps/myweb1" 과 같이 절대경로로 지정하는 것도 가능하다.

그럼 웹사이트를 하다 더 추가하고 싶다면? 위의 <Service>...</Service>를 하나 더 만들어 버리면 된다. 위의 코드를 복사한 다음 server.xml 에 추가한다. 그리고 빨간색으로 표시한 부분만 수정하자.


<Service name="Catalina2">
<Connector port="9090" protocol="HTTP/1.1"
maxThreads="150" connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

<Engine name="Catalina2" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>

<Host name="localhost" appBase="d:/webapps/myweb2"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
</Host>
</Engine>
</Service>


다른 웹어플리케이션을 돌리기 위해 서비스를 하나 더 추가한 것이다.
port="9090" 은 새로 추가하고 싶은 포트이다.
appBase="d:/webapps/myweb2"는 9090 포트에서 돌아갈 웹사이트 위치이다.

이제 server.xml 설정은 끝난 것이다.
마지막으로 웹사이트의 ROOT 디렉토리를 지정해주자. 아래의 폴더를 생성한다.

d:/webapps/myweb2/ROOT/ (
d:/webapps/myweb2/ROOT/WEB-INF/
(WEB-INF 폴더를 만들고 web.xml 파일을 추가한다. 그냥 /TOMCAT_HOME/webapps/ROOT/WEB-INF/에 있는 web.xml 을 복사하면 된다.

무지 간단하다. 하지만 난 이 간단한 것을 위해서 하루종일 삽질해야만 했다. 검색해 보아도 문서는 많은데 실제 도움이 될만한 것이 별로 없었다.

테스트하기 위해 ROOT/index.html 또는 index.jsp를 만든다.
이제 톰캣을 재시작하고 웹브라우저로 접속해 보자.
http://localhost:8080
http://localhost:9090

출처 : http://dbdb.tistory.com/rss

+++++
ROOT 디렉토리의 이름을 바꾸고 싶다면
<Host name="localhost" appBase="d:/dev/myweb">
<Context path="" docBase="d:/dev/myweb"/> <!-- 추가-->
</Host>


Posted by 1010
반응형
Posted by 1010
반응형
Posted by 1010
반응형

 http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_Architecturing

http://forum.springsource.org/showthread.php?t=21639

 

Mapping 설정

HandlerMapping

.setOrder

SimpleUrlHandlerMapping

<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="...do">contentConroller</prop>
   </props>
  </property>
</bean>


BeanNameUrlHandlerMapping

.setMappings

PropertiesFactoryBean을 이용하면 별도의 파일에서 설정 가능

@RequestMapping

import  org.springframework.web.bind.annotation.RequestMapping


View

ViewResolver

InternalResourceViewResolver

.setViewClass, .setCache, .setPrefix, .setSuffix


Conroller

MultiActionController

.setMethodNameResolver

AbstractCommandController

.setCommandClass

SimpleFormConroller

.setCommandName, .setCommandClass, .formBackingObject, .onSubmit , .showForm,. initBinder, .referenceData

@Controller

import org.springframework.stereotype.Controller


MethodNameResolver

PropertiesMethodNameResolver

.setMappings

ParameterMethodNameResolver

.setParamName, .setDefaultMethodName


Common configuration

ServletRequestUtils

WebUtils 사용하기

Developing a Spring Framework MVC application step-by-step

Spring MVC에서 클라이언트 요청의 처리 과정

Spring MVC에서 사용하는 ApplicationContext와 WebApplicationContext

Critical security issues found in the Spring Framework

 

Model

@ModelAttriutes


Binder

@InitBinder

WebDataBinder

ServletRequestDataBinder

MultipartResolver

ComonsMultipartResolver

.setMaxUploadSize, .setUploadTempDir

파일첨부 처리 방법

  1. Request를 MultipartHttpServletRequest로 casting
  2. PropertyEditorSupport를 상삭, setValue에서 value instaceof MultipartFile 이면 FileUploadUtil.uploadFormFile사용.


커스텀 태그

spring:bind

스프링 MVC form 태그 써 보셨어요?

PropertyEditor 활용 예제

 

HandlerInterceptor



2.5

 http://www.infoq.com/articles/spring-2.5-ii-spring-mvc

스프링 2.5 애노테이션 기반 MVC 예제

http://springtutorial.googlecode.com/svn/trunk/moimApp/src/spring/tutorial/web/MoimController.java

Spring 2.5 Annotation기반 Controller 끄적거림

Annotated Spring MVC Controller !!

Annotation-based controller configuration

Spring Framework 2.5의 Annotation based Controller의 메서드 파라미터에서 주의점

http://dev.anyframejava.org/anyframe/doc/web/3.2.0/webfw/springmvc/basic/annotation_controller.html

 

 

3.0

REST in Spring 3: @MVC

스프링 REST 지원 사용하여 애플리케이션에 Atom 뷰 추가하기

REST in Spring 3: RestTemplate

초간단 CURD, 검색, 페이징, 정렬 구현 완료

Spring3.0 M2 RESTful Client 구현 예제

스프링 3.0의 MVC 간편화

Spring 3.0.1 mvc:annotation-driven 이 몰래 하는 짓

http://toby.epril.com/?p=982 :

Spring 3.0 @MVC 메소드에서 자동으로 리턴 모델에 추가되는 것들

DispatcherServlet의 디폴트 대체(fallback) 전략

InsideSpring (3) 스프링 밖에서 WebApplicationContext에 접근하기

CRUD

http://blog.springsource.com/2010/07/22/spring-mvc-3-showcase/

Spring, Junit 에서 session, request scope bean 을 사용하기

 

Spring Faces

Simplifying JSF Development with Spring Faces

 

보안

Spring framework 보안 취약성 보고와 해결 방안.

 

Json

스프링 JSON view와 jQuery 이용하여 자동완성 기능 만들기 1

스프링 JSON view와 jQuery 이용하여 자동완성 기능 만들기 2

스프링 JSON view와 jQuery 이용하여 자동완성 기능 만들기 3

스프링 JSON view와 jQuery 이용하여 자동완성 기능 만들기 4

 [테스트] 스프링의 MappingJacksonJsonView 초간단 학습 테스트

[봄싹 버그]] JSON 뷰와 하이버가 가져온 Proxy 객체

 

View

Spring MVC에서 jexcel 모듈을 활용한 엑셀 파일 다운로드 기능 구현하기

 

Validation

 http://blog.inflinx.com/2010/03/10/jsr-303-bean-validation-using-spring-3/

 http://blog.openframework.or.kr/141

 

Test

어노테이션 기반 스프링 컨트롤러 단위테스트

Spring, Junit 에서 session, request scope bean 을 사용하기

[스프링 테스트] 웹 테스트용 WebApplicationContext에 request, session 스코프 빈 등록하기

 

Formatter

http://chanwook.tistory.com/867

 

Converter

http://chanwook.tistory.com/866

Spring 3 MVC HttpMessageConverter 기능으로 RESTful 웹 서비스 빌드

Posted by 1010
반응형
Spring EJB  기반으로 개발을 하지 않고, POJO(Plain old java Object)기반으로 개발을 하더라도 가볍고,
제어가 간으한 상호 관련이 적은, AOP을 지원하고, 컴테이너를 통해 라이프 사이클을 관리하고,
XML기반으로 컴포넌트를 개발할수 있도록 지언해주는 Framework이다.

AOP, DI -- Spring 의 특징  : J2EE 를 대체하는 프레임워크로 자리 잡고 있다.
서버측 개발에만 국한되지 않는 모든 Java Applicaiton개발에 활용할수 있다.
단순성, 테스트 용이성, 느슨한 결합성(DI)을 보장받을수 있다.

객체의 라이프 사이클을 관리하기 위햐여 DI를 사용하는 경량 컨테이너
자바 객체의 생성, 소멸과 같은 라이플 사이클을 관리한다.

DI(Dependency Injection) 패턴을 지원한다.
(스프링은 설정 파일을 통해서 객체간이 의존 관계를 설정할수 있도록 하고있다. 따라서 객체는 직접
의존하고 있는 객체를 생서하거나 검색할 필요가 없다.

스프링은 AOP(Aspect oriented Programming)를 지원한다.
(스프링은 자체적으로 AOP를 지원하고 있기 때문에, 트랜잭션이나, 로깅, 보안과 같이 여러 모듈에서
공통으로 필요로 하지만 실제 모듈이 핵심은 아닌 기능들을 분리해서 각 모듈에 적용할 수 있다.

스프링은 POJO(Plain Old Java Object)를 지원한다.
(간단한 자바객체를 가지고도, 구현할수 있다. 특정한 인터페이스를 구현하거나, 상속받을 필요가 없다.)

트랙젝션 처리를 위한 일관된 방법을 제공한다.

JDBC를 사용하든, JTA 를 이용하든 컨테이너가 제공하는 트랜잭션을 사용하든,
설정파일을 통해 트랜잭션 관련정보를 입력하기 때문에 트랜잭션 구현에 상관없이
동일한 코드를 여러 환경에서 사용할수 있다.

영속성과 관련된 다양한 API를 지원한다.
스프링은 JDBC를 비록한 i-BATS, 하이버네이트, JPA, JDO등 데이터베이스 처리와
관련하여 널리 사용되는 라이브러리와의 연동을 지원하고 있다.

다양한 API 에 대한 연동을 지원한다.





Spring의 구조

Core : DI기능을 제공
Context: 컨텍스트라는 정보를 제공하는 설정을 관리한다.  JNDI, EJB, 국제화, 스케줄링이 여기에 포마
DAO: DB와 관련된 JDBC 코딩부분을 처리해 주기 위한 JDBC추상화 레이어 제공.
ORM :JDO, Hibernates, iBATS등 O-R Mapping API를 위한 레이어 제공
AOP : 관점 지향 프로그래밍을 제공.
Web : 웹 기반의 여러가지 기능을 제공
Web MVC: Model과 View(Web form) 사이의 구분을 제공하기 위한 관련된 기능을 제공








필요한 준비물들


Eclipse
http://www.eclipse.org

Oracle10g

Tomcat
http://www.apache.org

jdk1.5이상

Spring Framework

http://www.springsource.org
spring-framework-2.5.5-with-dependencies.zip다운로드
spring-framework-2.5.5-with-docs.zip다운로드






웹서버를 실행하기위한 이클립스 세팅


이클립스 적당한 위치에다가 실행
Spring2.5에 압축을 품.(절대로 한글폴더에 풀지 말것)
워크 스페이스를 Spring2.5폴더에 Webapp 폴더에 푼다.

web- dynamic Web Project

jsp에서 실행하면..  apache하고 버젼 선택하고, 실제 톰캣의 경로를 선택해주고

<script type="text/javascript">
location.href="Hello.jsp";
</script>



spring 압축을 풀고, dist/spring.jar, modules /spring-webmvc.jar, ./lib/jakarata-commns/commons-logging.jar 를 워크스페스에 lib폴더에 넣는다.

web.xml을 통해서, spring에서 기본적인 클래스 core를 가져다 써야 한다. 이걸 wiring이라고 한다.(객체와 객체를 연결해야 한다.)
web-inf/web.xml에다가 Spring의 기본 클래스를 적어야 한다.  document열어보면..방법이 나와있다.


docs/mvc-step-by-step가 잇는데, 거기 안에pdf파일이 있따..
web.xml in the..머로 시작하는.. 곳으로 가서..  

그곳에 web.xml 에 잇는 내용을 추가하고,

<servlet> 노드랑
<servlet-mapping> 노드를 추가한다.  *.htm 은 html파일을 열때 스프링을 쓴다는 말  do라는 확장자로 바꿈

index.jsp를
<script type="text/javascript">
location.href="Hello.do";
</script>

java class 를 생성하고,   springweb.web 패키지 안에 HelloController 상속을하고 인터페이스를 구현해야 한다. controller라는 인터페이스를 구현해야 한다.


controller 를 오버라이딩 하면.. 기본적인 오버라이딩이 나온다.(다른 방법은 AbstractController를 상속 받는 방법도 있다.)

servlet api 도 잡아줘야 한다... 그래서 이걸 추가할려면.. 프로젝트에 빌드 패스로 가서,
(servlet라이브러리는 톰캣이 제공해준다. tomcat/lib/servlet-api를 libraries탭에 add external jar를 해가지고 추가한다.)

(모델을 처리해서, 뷰에게 넘긴다.)

handleRequest 를 메서드안에, HttpServletRequest req, HttpServletResponse res 로 파라미터를 바꾸고
req.setAttribute("name","홍길동");  그리고 null값을 리턴하는것이 아니고, new ModelAndView("")//어느페이지로 이동할지


wiring 작업을 하나의 xml을 만드는데 그냥 만드는 것이 아니고,

이름을 내맘데로 만드는것이 아니고, web.xml 에 springapp 이름을 이용해가지고
springapp-servlet.xml로 만들어야 한다.

다큐멘트에서 spring-servlet.xml샘플을 복사한다.   (web.xml에, 똑같은 파일을 넣는다.)

<bean name="/Hello.do" class="springweb.web.HelloController"/>//servlet을 맵핑한다.




ModelAndView mav = new ModelAndview();
mav.setViewName("Hello.jsp"")//어떤 페이지로 이동할것인가..
mav.addObject("name","홍길동"); // 이렇게 해서 request뿐만 아니라, 이렇게 파라미터도 보낼수 있다.

return mav;

hello.jsp에다가 request객체의 내용을 뿌릴려면은  EL 로 해가지고,<br>${requestScope.name} 해가지고 뿌릴수 있다.<%=request.getAttribute("name")%> 으로 해도 된다.



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

db연결

아파치에서 제공하는 DBCP API 를 이용(톰캣에 들어있다 tomcat/lib/tomcat-dbcp.jar파일이있다..)
JNDI를 이용함 (네이밍 서비스, 내가 원하는 서비스를 찾아서 이용 이용)


설정방법

이클립스에 servers에, server.xml 에  (tomcat/webapps/docs/index.html(도움말)에 tomcat standard Resource Factories 에 JDBC Data Source에 Configure tomcat`s Resource Factory 에 내용이 나와있다.)
이걸 복사해가지고, Global JNDI resources 에 주석이 있는데, GlobalNamingResources 노드에 넣는다.

name=jdbc/이름 아무거나
username과, password설정하고,
driverClassName = "oracle.jdbc.driver.OracleDriver"(Orace Doc에 나와있음)
url="jdbc:oracle:thin:@localhost:1521:XE(Orace Doc에 나와있음)
maxActive=최대연결수


포트번호를 확인(programfiles/oraclexe/app/product/10.2.0/server/network/ADMIN/tnsnames.ora)
드라이버는 (programfiles/oraclexe/app/product/10.2.0/server/jdbc/lib/에 모든 jar파일을
톰캣에 설치된 폴더에 lib에 복사를 한다.


test_jndi.jsp를 만들고

<@ page import="javax.naming.InitialContext"%>
<@ page impor="java.sql.Connection" %>
<@ page impor="java.sql.Statement" %>
<@ page impor="java.sql.ResultSet" %>

<%
InitialContext ctx = new InitialContext();//InitialContext 에서 검색 객체를 만든다.
Object obj = ctx.lookup("java:comp/env/jdbc/SpringDB");// SpringDB 는tomcat 에 아까 추가한 name과 같아야 한다.  검색을 한다.
if(obj !=null){
javax.sql.DataSource ds = (javax.sql.DataSource)obj;
Connection Con = ds.getConneciton();
Statement stmt = Con.createStatement();
String sql = " select * from board";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
out.println(rs.getString(1) + "<br/>);
}
stmt.close();
Con.close();
}else{
out.println("검색실패!");
}


%>

index.jsp를 만들고,

게시판 테스트라고 만들고 tomcat재부팅하고,

실행하고, 이클립스에  servers에 server.xml 밑에 보면, <Context docBase라고 새로 생성이 되는데,
<Context doc...>
</Context> 라고 만들고..

 가운데다가  <ResourceLink name="jdbc/SpringDB" global="jdbc/SpringDB" type="java.sql.DataSource"/>라고 등록하고

test_jndi.jsp를 실행한다.




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



게시판 만들기

wei-inf/lib/ commons-loggin.jar, spring-webmvc.jar, spring.jar 를 넣는다.

web.xml 에  
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

을 추가한다.


스프링 MVC의 개요

요청을 처리하기 위해 컨트롤러를 선택하는 방법과 결과를 보여주기 위한 뷰를 선택하는 방ㅎ식간에
낮은 결합도를 유지하고 있다는 점이 무엇보다 중요하다.


스프링 MVV 의 라이프사이클


요청===>dispatcher servlet(web.xml에서 씀 Front Controller담당) ==>  Handler Mapping(어떤 컨트롤러에게 이 요청을 맞길것인가.)
  ==> controller(서비스 모델에서 처리하고.) ==>ModelAndView(모델과 뷰를 통합해서 가지고 다님) 이걸 다시 Dispatcher servlet로 넘겨주고
dispatcher servlet 은 ViewResolve 는 어떤 뷰에 넘길지.. 선택하고.. 이것을 View에 넘긴다.




dispatcher에서 설정한 springapp에다가 -servlet.xml로 환경설정을 할수 있다.

1.. Dispatcher-servlet
보안계층, 웹계층, 서비스 계층, 퍼시스턴스계층으로 xml을 나눌것을 권함
서블릿명-security.xml
서블릿명-servlet.xml
서블릿명- service.xml
서블릿명-data.xml(퍼시스턴스계층..은 디비와 관련된 계층)

여러개의 xml을 모두 읽어들일려면..
web.xml에 컨텍스트 로더를 구성해야 한다

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
를 통해서

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/서블릿명-service.xml.....
</paran-value>
</context-param>




springapp-servlet.xml 을 만든다



메인페이지  index.jsp로 만든다.

<h2>게시판 테스트</h2>
<hr></hr>
<a href="board_list.do">게시판 목록으로 가기</a>



WebContent/board폴더에 게시판을 만든다.
list.jsp 를 만든다.


컨트롤러를 만드는데.. 클래스로..   (컨트롤러 종류에는 많다.) 컨트롤러가..다 처리하는건.. 않좋은 예다..
package.springapp.web
BoardController class로 만든다..

public springapp.web
class BaordController extents AbstractController  {//컨트롤러에 역할을 수행하기 위해api를 보면.. (Spring2.5/docs/api/index.html)  org.springframework.web.servlet.mvc에 controller 인터페이스가 있음 자식들이..컨트롤러의 종류..
 protected abstract ModelAndView handleRequestInternal(HttpServletRequest arg0,    //리턴값은 어떤 컨트롤러든.. 모두 모델앤 뷰이다.
HttpServletResponse arg1) throws Exception {
ModelAndView mav= new ModelAndView();  
mav.setViewName("board/list.jsp");   //ViewResolve를 이용하기 위해서는 여기다가 절대 경로를 넣는것이 아니라, xml설정파일을 통해서 해야 올바른 방법이다.
mav.addObject("board","이것은 게시판 테스트이다.");//모델을 여기다가 넣는다.(즉, 파라미터들..)  Request영역에 저장된다.
return mav;
}
}



위에 것이 완성되면springapp-servlet.xml 에
<bean name="/board_list.do" class="springapp.web.BoardController"/>
가..들어간다.


list.jsp에다가

테스트 : ${requestScope.board}
를 넣는다.



web.xml에..

위에서 배운..
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
를 통해서

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-servlet.xml.....
</paran-value>
</context-param>



를 넣는다.



 컨트롤러에서 모든 일을 하지 않고, 일처리는 서비스라는 곳에서 한다. 모델의 역할을 하는것이 서비스에서 처리한다.

모델에 해당되는 클래스를 만든다.

package: springapp.dao
BoardDao


import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;

import java.sql.DataSource;
public class BoardDao{
private DataSource ds ;
public void setDataSource(DataSource ds){
this.ds = ds;
}
public int count()throws Exception{
int result = -1;
Conneciton con = null;
Statement stmt = null;
try{
con = ds.getConnection();
stmt = con.createStatement();
String sql = "select  count(*) CNT from board";
ResultSet rs = stmt.executeQuery(sql);
rs.next();
result = rs.getInt("CNT");
}catch(){
}finally{
close(conn,stmt);
}
return result;
}
private void close(Conneciton con, Statement stmt){
try{
if(con != null)con.close();
}catch(Exception err){

}

try{
if(stmt != null)stmt.close();
}catch(Exception err){

}
}
}


springapp-servlet.xml에 가가지고 서비스를 등록하기 위해


<bean name="/board_list.do" class="springapp.web.BoardController">
<property name="boardDao" ref="boardDao"></propery>
</bean>


<bean id="boarddao" class="springapp.dao.BoardDao">//객체를 생성해서 로드를 할수 있게.
<property name="dataSource" ref="dataSource"></propery>//boardDao/setDataSource를 쓴다.
</bean>


<bean id="dataSource" class="org.springframeworkd.jndi.JndiObjectFactoryBean">//dbcpapi를 이용하는 객체 가져오기
<property name="jndiName" value="jdbc/SpringDB"></property>  tomcat에 server.xml에 name과 동일 //프로퍼티를 이용해가지고.. 값을 넘길수 있따
<property name="resourceRef" value="true"></property> //톰캣에 등록되어 잇는 애를 가져다 쓰겟다..
</bean>


BoardController.java에다가

import springapp.dao.BoardDao;


//boarddao객체를 넘겨받기 위한
private BoardDao boardDao;

public void setBoardDao(BoardDao dao){
boardDao = dao;
}

 그리고 handleReuqestInternal함수에다가

mav.addObject("boardCount", new Integer(boardDao.count());



list.jsp에서는

글의 총갯수 : ${boardCount}






BoardController.java에서 mav.setViewName에서 url을 직접 지정하는건 올바르지 않다..


viewReolver을 이용할려면 InternalViewResolver을 이용해가지고 할수 있다 (뷰를 벨로시티나, jsf로 사용할수도 있다.. jsp도 그렇고)

mav.setViewName("board/list.jsp");를 환경변수로...

mav.setViewName("list")로 바꾸고..



springapp-servlet.xml에

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResouceViewResolver">
<property name ="prefix">   //간단하게 접두사를 붙일수 있다.
<value>/board/</value>
</propery>
<property name ="suffix">   //간단하게 접두사를 붙일수 있다.
<value>.jsp</value>
</propery>
</bean>



----------------------------------------
JDBC Templete(db쿼리를 간단하게 사용할수있다. 자원관리도.. 다 해준다.)  --  


spring-servlet.xml에다가

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.jdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>



package springapp.dao;

public class jdbcTemplateBoardDao{  //예외 처리나 보완관련.. 모든걸.. 다 해결해준다.
private jdbcTemplate jdbcTemplate;
public void setjdbcTemplate(jdbcTemplate temp){
jdbcTemplate= temp;
}
public int count() throws Exception{
return jdbcTemplate.queryForInt("select count(*) from board");
}
}




springapp-servlet.xml로 가서


<bean id="boarddao" 를 주석하고

<bean id="boarddao" class="springapp.dao.jdbcTemplateBoardDao">
<propery name="jdbcTemplate" ref="jdbcTemplate"></propery> //이러면 setJebcTemplete를 실행한다.
</bean>




그리고 boardController.java를

private BoardDao  boardDao;
public void setVBoardDao(BoardDao){
boardDao = dao;
}
를 주석하고


private jdbcTemplateBoardDao boardDao;
public void setVoardDao (JdbcTemplateBoardDao dao){
 boardDao = dao;
}






springapp-servlet.xml에

<bean name="/board_list.do" class="spring.web.BoardController">
<propery name="boardDao" ref="boarddao"></property>
</bean>

은 주석처리하고

<bean name="/board_list.do" class="springapp.board.BoardListController">
<property name="boardDao" ref= " boardDao"></propery>
</bean>
 
위에 소스 추가하고..
 



//spring 에서 제공하는 컨트롤러의 계층 구조

Controller
AbstractController

MultiActionController
BaseCommandController
AbstractCommandController
AbstractFormController
AbstractWizardFromController
SimpleFormcontroller





package springapp.board.BoardListController

public class BoardListController implements Controller {  
private JdbcTemplateBoardDao  bardDao ;
public void setBoardDao(JdbcTemplateBoardDao boardDao){
this.boardDao = boardDao;
}
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
List boardList = boardDao.list();
return new ModelAndView("list");
}
}




jdbcTempleteBoardDao .java에다가 아래소스 추가

public List list(){
List result = new ArrayList();
String sql = "select * from board order by seq desc";
RowMapper mapper = new RowMapper(){ //레코드 하나를 전달받아서 맵핑해줌
public Object mapRow(ResultSet rs, int rowNum) throws SQLException{
BoardVO vo = new BoardVO();//게시판에 잇는 글들을 저장하고 사용하기 위한 데이터 엔티티클래스
vo.setContent(rs.getString("content"));
vo.setHitcount(rs.getInt("hitcount"));
vo.setPassword(rs.getString("password"));
vo.setRegdate(rs.getString("regdate"));
vo.setSeq(rs.getInt("seq"));
vo.setTitle(rs.getString("title"));
vo.setWriter(rs.getString("writer"));
return vo;
}
};
result = jdbctemplete.query(sql, mapper);//위에 mapper이 들어온다.
return result;
}









package springapp.dao;

public class BoardVO{
private int seq;
private int hitcount;
private String title;
private String content;
private String wirter;
private String gredate;
private String password;

setter함수와 getter함수..만들고
}



BoardListController.java 에

return new ModelAndView("list", "boardList", boardList); //request객체에 담아서 실어보낸다.



톰캣폴더에 webapps에 examples에 web-inf에 lib폴더에 보면.. jstl.jar, standard.jar복사해서,
web-inf에 lib에 넣는다.




list.jsp를
<@ taglib  prefix="c" uri="http://java.sun.com/jsp/jstl/core/"%>//jstl을 사용하기위해서
<jsp:useBean id="boardList" type="java.util.List"  scope="request" />
<table>
<tr>
<th>번호</th><th>제목</th><th>등록자</th><th>등록일</th>
</tr>
<c:forEach var="vo" items="${boardList}">
<tr>
<td>${vo.seq}</td>
<td><a href="board_detail.do?seq=${vo.seq}">${vo.title}</a></td>
<td>${vo.wirter}</td>
<td>${vo.regdate}</td>
</tr>
</c:forEach>
</table>




-------------------------
글의 상세보기 detail.jsp




< jsp:useBean id="boardVO" class="springapp.dao.BoardVO" scope="request"/>
<script type="text/javascript">
function fn_update_from(){
locaion.href="board_update.do?seq=${boardVO.seq}";
}

function fn_list_form(){
locaiton.href="board_list.do";
}
function fn_delete_form(){
locaiton.href="board_delete.do?seq=${boardVO.seq}";
}
</script>
<body>
<p align="center">
게시판 상세보기
</p>
<table border="1">
<tr>
<th>글번호</th><td>${boardVO.seq}</td>
</tr>
<tr>
<th>글제목</th><td>${boardVO.title}</td>
</tr>
<tr>
<th>글내용</th><td>${boardVO.content}</td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="button" value="수정하기"  onclick="fn_update_from()"/>
<input type="button" value="삭제하기" onclick="fn_delete_from()" />
<input type="button" value="목록보기" onclick="fn_list_from()" />
</td>
</tr>
</table>
</body>
</html>




springapp-servlet.xml에..

<bean name="/board_detail.do" class="springapp.board.BoardDetailController">
<property name="boardDao" ref="boardDao"></proerty>
</bean>





package springapp.baord;

public class BoardDetailController implements Controller{

private JdbcTemplateBoardDao boardDao;
public void setBoardDao(JdbcTemplateBoardDao boardDao){
this.boardDao=boardDao;
}
public ModelAndview handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception{
BoardVO vo = null
String seq = arg0.getParameter("seq");
vo = boardDao.findBySeq(seq);//서비스에게 맞긴다.  이클립스에서는 vreate method findBySeq(String) in type  어쩌고 저쩌고 해서.. 자동적으로 만들어준다.
ModelAndView mav = new ModelAndView();
mav.setViewName("detail");
return mav;
}
}


JdbcTemplateBoardDao.java  //자동적으로 생성

public BoardVO findBySeq(String seq){
BoardVO result = null;
String sql = "select * from board where seq=?";
Object[] values = new Object[]{new Integer(seq)}
RowMapper mapper = new RowMaper(){  //RowMapper가져다 주면.. 자동적으로 오버라이딩 할 메서드가 나타난다.
public Object mapRow(ResultSet rs, ing rowNum) throws SQLException{
BoardVO vo = new BoardVO();
vo.setContent(rs.getString("content"));
vo.setHitcount(rs.getInt("hitcount"));
vo.setPassword(rs.getString("password"));
vo.setRegdate(rs.getString("regdate"));
vo.setSeq(rs.getInt("seq"));
vo.setTitle(rs.getString("title"));
vo.setWriter(rs.getString("writer"));
return vo;
}
};
result = (BoardVO)jdbctemplate.queryForObject(sql, values, mapper);
return result;
}
}

----------------------------------------
update.jsp

<jsp:useBean id="boardVO" class="springapp.dao.boardVO" scope="request"/>
 
<script type="text/javascript">
function fn_passCheck(){
var pass=  document.getElementById("password").value;
if(pass != "${boardVO.password)"{
alert("패스워드가 틀립니다.");
docuemnt.getElementById("password").focus();   //id랑 name이랑 같다.
return;
}
 document.forms[0].submit();
}
</script>

<body>
<p align="center">
게시판 수정하기
</p>
<form action="board_updae_action.do" method="post">
<input type="hidden" name="seq" value="${boardVO.seq}"/>
<table border="1">
<tr>
<th>글제목</th><td><input type="text" name="title" value="${boardVO.title}"/></td>
</tr>
<tr>
<th>글쓴이</th><td><input type="text" name="writer" value="${boardVO.writer} "> </td>
</tr>
<tr>
<th>비밀번호</th><td><input type="text" name="password"  /></td>
</tr>
<tr>
<th>글내용</th><td><textarea rows="5" cols="60" name="content" >${boardVO.content}</textarea></td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="button" value="수정하기" onclick="fn_passCheck()"   />
</td>
</tr>
</table>
</form>
</body>
</html>



spring-servlet.xml에다가

<bean name="/board_update.do" class="springapp.board.BoardUpdateController">
<property name="boardDao" ref="boardDao"></property>
</bean>




package springapp.board;

public class BoardUpdaeController implement Controller{
private JdbcTemplateBoardDao boardDao;
public void setBoardDao(JdbcTemplateBoardDao boardDao){
this.boardDao. boardDao;

}

public ModeAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1)throws Exception{
String seq = arg0.getParameter("seq");
BoardVO vo = boardDao.findBySeq(seq);
arg0.setAttribute("boardVO", vo);  //위에껄로 써도 된다.
ModelAndView mav= new ModelAndView();
mav.setViewName("update");
return mav;
}
}






---------------------------
update 처리

spring-servlet.xml

<bean name="/board_update_action.do" class="springapp.board.BoardUpdateActionCommandController">
<property name="boardDao" ref="boardDao"></property>
<property name="commandClass" value="springapp.dao.BoardVO"></property>//넘어가는 데이터타입..
<property name="commandName" value="boardCmd"></property> //value는 그냥.. 아무렇게나 해도 상관없다..
</bean>



package springapp.board;

public class BoardUpdateActionCommandController extends AbstractCommandController{  // 이걸로 하면, 파라미터 처리가 쉽다.
private JdbcTemplateBoardDao boardDao;
public void setBoardDao(JdbcTemplateBoardDao boardDao){
this.boardDao = boardDao;
}
protected ModelAndView handle(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, BindException arg3)  //안에 있는 매개변수가 다르다.파라미터를 용이하게 처리할수 있다.
throws Exception{
BoardVO vo = (BoardVO)arg2; arg2는 모델이 전달된다.
boardDao.update(vo);
//return new ModelAndView(new RedirectView("board_list.do"));//뷰를 바로 이동할수 잇게끔 한다.
return new ModelAndView("redirect:board_list.do"); //이렇게 해도 된다.  둘다..ViewResolver의 영향을 받지 않는다.
}
}




JdbcTemplateBoardDao.java에다가
public void update (BoardVO vo){
String sql = "Update Board set title=?, content=? where seq =?";
Object[] values = new Object[]{vo.getTitle(), vo.getContent(),vo.getSeq()};
jdbctemplate.update(sql,values);
}
}


글을 등록하면 한글이 깨지는 문제는


web.xml에..

<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframeworkd.web.filter.CharacterFilter</filter-class>
<init-param>
<param-name>encodint</param-name>
<param-value>euc-kr</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>




------------------------------------
글등록


list.jsp에 가서

<script type="text/javascript">
function fn_insert(){
locaiton.href="board_insert.do";
}
</script>


밑에다가

<input type="button" value="글쓰기" onclick="fn_insert()"/>
<hr/>
만든다.




insert.jsp를 만든다.



<body>
<p align="center">
게시판 글 등록하기
</p>
<form action="board_insert_action.do" method="post">
<table border="1">
<tr>
<th>글제목</th><td><input type="text" name="title"  /></td>
</tr>
<tr>
<th>글쓴이</th><td><input type="text" name="writer" >   </td>
</tr>
<tr>
<th>비밀번호</th><td><input type="text" name="password"  /></td>
</tr>
<tr>
<th>글내용</th><td><textarea rows="5" cols="60" name="content"  ></textarea></td>
</tr>

<tr>
<td colspan="2" align="center">
<input type="submit" value="등록하기"    />
</td>
</tr>
</table>
</form>
</body>






spring-servlet.xml에다가

<bean name="/board_insert.do" class="springapp.board.BoardInsertController"/>
 




package springapp.board;

public class BoardInsertController implement Controller{

public ModeAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1)throws Exception{
 
return new ModelAndView("insert");
}
}


----------
insert 처리




spring-servlet.xml

<bean name="/board_insert_action.do" class="springapp.board.BoardInsertActionCommandController">
<property name="boardDao" ref="boardDao"></property>
<property name="commandClass" value="springapp.dao.BoardVO"></property>//넘어가는 데이터타입..
<property name="commandName" value="boardCmd"></property> //value는 그냥.. 아무렇게나 해도 상관없다..
</bean>



package springapp.board;

public class BoardInsertActionCommandController extends AbstractCommandController{  // 이걸로 하면, 파라미터 처리가 쉽다.
private JdbcTemplateBoardDao boardDao;
public void setBoardDao(JdbcTemplateBoardDao boardDao){
this.boardDao = boardDao;
}
protected ModelAndView handle(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, BindException arg3)  //안에 있는 매개변수가 다르다.파라미터를 용이하게 처리할수 있다.
throws Exception{
BoardVO vo = (BoardVO)arg2; arg2는 모델이 전달된다.
boardDao.insert(vo);
//return new ModelAndView(new RedirectView("board_list.do"));//뷰를 바로 이동할수 잇게끔 한다.
return new ModelAndView("redirect:board_list.do"); //이렇게 해도 된다.  둘다..ViewResolver의 영향을 받지 않는다.
}
}




JdbcTemplateBoardDao.java에다가
public void insert (BoardVO vo){
String sql = "Insert into Board (seq, title, content, writer ,regdate,password, hitcount) "
+"values (board_seq.nextVal,?,?,?, to_char(sysdate,'yyyy/mm/dd'),?,0 )";
Object[] values = new Object[]{vo.getTitle(), vo.getContent(), vo.getWriter(), vo.getPassword()};
jdbctemplate.update(sql,values);
}
}





-----------------------------------------------------
Dependency Injection 종속객체주입 =IoC(inversion of Control)역제어

의존성은 객체와 객체사이의 관계를 말한다. (낮은 결합도) new라는 생성자를 이용해서, 객체를 생성하지 않는다.


주입 방법


spring설치파일에 docs/reference/pdf/pdf파일 열어보면..
1.생성자를 이용한 주입

public class SimpleMovieLister{
private MovieFinder movieFinder;
public simpleMovieListter(MovieFinder movieFinder){
this.movieFinder = movieFinder;
}
}
어딘가에 만들어진 객체를 위와 같은 소스로 주입한다.

package x,y;

public class Foo{
public Foo(Bar bar, Baz baz){
//..
}
}

어디서 객체가 만들어지나면..

<beans>
<bean name="foo" class="x.y.Foo">
<constructor-arg>
<bean class="x.y.Bar"/>
</constructor-arg>
<constructor-arg>
<bean class="x.y.Baz"/>
</constructor-arg>
</bean>
</beans>



또다른 예 (값도 넘겨줄수 있다.)
package examples;
public class ExampleBean{
private int years;
private String ultimateAnswer;
public ExampleBean(int years, String ultimateAnswer){
this.years=years;
this.ultimateAnswer = ultimateAnswer;
}
}

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="750000"/> //value는 속성으로도 사용할수 잇지만, 자식 엘리먼트로 이용될수도 있다. <value>5200000</value>  
<constructor-arg type="java.lang.String" value="42"/>
</bean>


index라는 속성은 여러개의 객체가 넘어갈때의 순서이다.


-----------------------
어플리케이션 DI실습

commons-loggin.jar, spring.jar만 있으면 된다.
window-preferences- java-Build Path- User Libraries 로 해가지고, 라이브러리를 만든다.

Spring_App_Lib 라이브러리를 만들고,  addJars를 해가지고, 위 두가지 jar파일을 추가한다.




window-cusmotmize Perspective에서 new를 눌렀을때, 나오는 메뉴들을 조절할수 있다.

Java Project해가지고, SpringApp01 로 프로젝트를 만든다.

프로젝트에 BuildPath addLibrary 를 해가지고, userLibrary해가지고, Spring_App_Lib 를 추가한다.


MessageBean.java
package myspring;

public interface MessageBean{
void sayhello(String name);
}
MessageBeanKo.java

package myspring;
public class MessageBeanKo implements MessageBean{
public void sayHello(String name){
System.out.println("안녕하세요....."+name + "님");
}
}

MessageBeanEn.java

package myspring;
public class MessageBeanEn implements MessageBean{
public void sayHello(String name){
System.out.println("Hello.....Mr."+name );
}
}



xml설정파일은 웹이 아니라서, 어떤걸로도 이름을 지어도 상관은 없지만,
applicationContext.xml로 만든다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="msgBean" class="myspring.MessageBeanEn"></bean>
</beans>




활용을 하기 위한 클래스를 만든다.

package.myspring
public class HelloApp{
public static void main(String[] args){
Resource res = new FileSystemResource("applicationContext.xml");//설정파일을 읽어올려면..   스프링 폴더에 docs에 api를 보면.. org.springframework.core.io라는 패키지를 들어가면 ClasspathResource(패키지 안에 같은경로에 있어야 한다.), FileSystemResource(프로젝트 안에 있어야 한다.)두개의 클래스를 사용할수 있다.
BeanFactory factory = new XmlbeanFactory(res); //xml에 설정되어 잇는 빈객체를 생성하는곳  둘다.. 부모 클래스로 받아준다.
MessageBean bean = (MessageBean)factory.getBean("msgBean"); //위에 xml에 있는 id를 이용할수 있다.
bean.sayHello("Tom");
}
}

2.setter를 이용한 주입

MessageBean.java


package myspring.sample1;

public interface MessageBean{
void sayHello(String name);
}



pacakge myspring.sample1;
public class MessageBeanImpl implemens MessageBean{
private String name;  //생성자를 통해서..
private String greeting; //setter를 통해서 초기화 할수 있도록
public MessageBeanImpl(String name){  //source -  Generate Constructor using Fields..
super();
this.name = name;
}

//source- Generate Getter/Setter
public void setGreeting(String greeting){
this.greeting = greeting;
}
public String getGreeting(){
return greeting;
}

public void sayHello(){
System.out.println(greeting + name + "!");
}
}


설정파일을 만든다.

applicationContext1.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="msgBean" class="myspring.sample1.MessageBeanImpl">
<constructor-arg>///전에는 객체만 생성했었는데..여기서 생성자를 통해서..값을 넘겨 줄수 있다.그리고 setter메서드를 이용해가지고..값을 넘길수 잇다.
<value>홍길동</value>
</constructor-arg>
<property name="greeting">
<value>안녕하세요....</value>
</property> //setter을 이용하는 방법
</bean>
</beans>







활용을 하기 위한 클래스를 만든다.

package.myspring.sample1
public class HelloApp{
public static void main(String[] args){
Resource resource = new ClassPathResource("applicationContext1.xml");//설정파일을 읽어올려면..   스프링 폴더에 docs에 api를 보면.. org.springframework.core.io라는 패키지를 들어가면 ClasspathResource(패키지 안에 같은경로에 있어야 한다.), FileSystemResource(프로젝트 안에 있어야 한다.)두개의 클래스를 사용할수 있다.
BeanFactory factory = new XmlbeanFactory(ressource); //xml에 설정되어 잇는 빈객체를 생성하는곳  둘다.. 부모 클래스로 받아준다.
MessageBean bean = (MessageBean)factory.getBean("msgBean"); //위에 xml에 있는 id를 이용할수 있다.
bean.sayHello();
}
}





--------------------------
//파일로 메시지 출력



pacakge myspring.sample2;
public    interface MessageBean{
public void sayHello();  //콘솔에다가 출력
}


pacakge myspring.sample2;
public   interface Outputter{
public void output(String msg)throwr IOExceptinon; //파일에다가 출력
}



package myspring.sample2;
public class FileOutputter implements Outputter{
private String filePath;
public void setFilePath(String filePath){
this.filePath = filePath;
}

public void output(String msg) throws IOException{
FileWriter out = new FileWriter(filepath);//파일로 만드는데는 바이트 스트림과, 문자 스트림 방식이 있다
out.wirte(msg);
out.close();
}
}



package myspring.sample2;
public class MessageBeanImpl implements MessageBean{
private String name;
private String  greeting;
private Outputter out ;
public MessageBeanImpl(String name){
super();
this.name = name;
}
public void setOut(Outputter out){
this.out = out;
}
public void setGreeting(String greeting){
this.greeting  = greeting;
}

public void sayHello(){
String msg = greetin + name + "!";
System.out.println(msg);
try{
out.output(msg);
}catch(IOException e ){
e.printStackTrace();
}
}
}

applicationContext2.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="msgBean" class="myspring.sample2.MessageBeanImpl">
<constructor-arg>
<value>임꺽정</value>
</constructor-arg> //생성자
<property name="greeting">
<value>안녕히 계세요.</value>
</property> //setter을 이용하는 방법
<property name="out">
<ref local="outter"/> //객체를 주입해야 한다.
</property>
</bean>
<bean id="outter" class="myspring.sample2.FileOutputter">
<property name="filePath">
<value>out.txt</value> //파일명
</propery>
</bean>
</beans>




활용을 하기 위한 클래스를 만든다.

package.myspring.sample2
public class HelloApp{
public static void main(String[] args){
Resource resource = new ClassPathResource("applicationContext2.xml");//설정파일을 읽어올려면..   스프링 폴더에 docs에 api를 보면.. org.springframework.core.io라는 패키지를 들어가면 ClasspathResource(패키지 안에 같은경로에 있어야 한다.), FileSystemResource(프로젝트 안에 있어야 한다.)두개의 클래스를 사용할수 있다.
BeanFactory factory = new XmlbeanFactory(ressource); //xml에 설정되어 잇는 빈객체를 생성하는곳  둘다.. 부모 클래스로 받아준다.
MessageBean bean = (MessageBean)factory.getBean("msgBean"); //위에 xml에 있는 id를 이용할수 있다.
bean.sayHello();
}
}


-----------------------
DI의 라이프사이클  (어플리케이션에서 중요..웹어플에서는.. 상관없음..)


스프링 컨테이너는 두가지 부류로 나눈다.

1. BeanFactory
XMLBeanFactory를 많이 사용한다.
org.springframework.beans.factory.BeanFactory

2. ApplicaionContext
BeanFactory는 가볍고, 단순하다.  하드웨어 장치가 열악한곳에 쓰이지만..
org.springframework.context.ApplicationContext
ApplicationContextAware도 많이 쓰이는 인터페이스다.

ApplicationContext는  BeanFacotry를 상속받아서 사용한다.




BeanFactory에서 사용하는 리소스들

org.springframework.core.io.ClassPathResource //외부로부터 파일시스템을 읽어들일..
.FileSystemResource



ApplicaitonContext에서 사용하는 리소스들
org.springframework.context.support.ClassPathXmlApplicationContext
.FileSystem.XmlApplicationContext




DI의 LifeCycle

1. BeanFactory

인스턴스화 - 프로퍼티 할당 - BeanNameAware의 setBeanName() (현재 사용되는 빈의 이름은 무엇인가.) - BeanFactoryAware의 setBeanFactory()(빈펙토리가 무엇인지..)- BeanPostProcessor의 사전초기화(두가지로 실행된다. 사전초기화, 후속 초기화 어떤 메서드가 실행되기 전에 한번 실행되고, 나중에 한번 더 실행된다.)
- InitialzingBean의 afterPropertiesSet() (특정 초기화 메서드를 선언을 하면, 그 함수를 실행할수 있게끔.. 하는..) - 커스텀 초기화 메서드 호출 - BeanPostProcessor의 후속초기화 - DisposableBean의 Destory()  - 커스텀 소멸 메서드 호출
2. ApplicationContext(BeanFactory에서 하나가 추가된다.)


인스턴스화 - 프로퍼티 할당 - BeanNameAware의 setBeanName() (현재 사용되는 빈의 이름은 무엇인가.) - BeanFactoryAware의 setBeanFactory()(빈펙토리가 무엇인지..)-ApplicationContextAware의  setApplicationContext()(이것이 BeanFactory와 다르다.)- BeanPostProcessor의 사전초기화(두가지로 실행된다. 사전초기화, 후속 초기화 어떤 메서드가 실행되기 전에 한번 실행되고, 나중에 한번 더 실행된다.)
- InitialzingBean의 afterPropertiesSet() (특정 초기화 메서드를 선언을 하면, 그 함수를 실행할수 있게끔.. 하는..) - 커스텀 초기화 메서드 호출 - BeanPostProcessor의 후속초기화 - DisposableBean의 Destory()  - 커스텀 소멸 메서드 호출





pacakge myspring.sample3;
public interface MessageBean{
void sayHello();
}

pcakge myspring.sample3;
public class MessageBeanImpl implements MessageBean, BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean{ // Life사이클을 테스트하기 위해서..
private String greeting;
private String beanName;
private BeanFactory factory;

public MessageBeanImpl(){
System.out.prinltn("1.인스턴스화");

}
  public void setGreeting(String greeting){
this.greeting = greeting;
System.out.prinltn("2.프로퍼티할당");
}

public void sayHello(){ //핵심주메서드
System.out.prinltn(greeting+beanName + "!");
}
public void setBeanName(String arg0){ //빈네임을 인자로 받을수 있다.
this.beanName = arg0;
System.out.prinltn("3.빈이름 설정" + "---->"+ beanName);

}
public void setBeanFactory(BeanFactory arg0)throws BeansException{//이름설정한다음에, 팩토리를 설정
System.out.prinltn("4.빈팩토리설정");
this.factory = arg0;
System.out.println("--->"+ factory.getClass()); // 현재 실행중인 클래스의 이름을 뽑아낸다.

}
public void afterPropertiesSet()throws Exception{ // 핵심 로직이 실행되기전에, 그리고 끝난후에 실행되는..  
//여기서 사용자가 만든 초기화 메서드가 실행된다. init가 실행되게 설정할것이다. init가 설정되기 전에
밑에 클래스  postProcessBeforeInitialization이게 먼저 실행되고, 그다음 이 함수를 벗어나서, 그다음 init가 실행되고, 다음에 postProcessAfterInitialization 이게 실행된다.
System.out.println("6. property설정완료");
}
public void destroy()throws Exception{
System.out.println("종료");
}
public void init(){
System.out.println("7. 초기화 메서드 실행");
}
}





//이 클래스는 BeanPostProcessor를 상속해서.. 빈펙토리 에서는 이거 applicationContext3.xml 에 설정 않해도 되고, ApplicationContext에서는 설정파일에 객체 생성을 해야 한다.

package myspring.sample3;

public class BeanPostProcessorImpl implements BeanPostProcessor{
//초기화 메서드가 실행이 끈나고 나서.. 실행되는 메서드
public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeanException{
System.out.println("8.초기화 후의 빈에 대한 처리 실행");
return arg0;
}
//초기화 메서드가 실행이 되기전에.. 실행되는 메서드
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException{
System.out.println("5.초기화 전의 빈에 대한 처리 실행");
return arg0;
}
}



applicationContext3.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="msgBean" class="myspring.sample3.MessageBeanImpl" init-method="init">//초기화 메서드를 만들었기 때문에 여기에다가 설정한다.
<property name="greeting">
<value>안녕하세요.....</value>
</property>
</bean>
</beans>







활용을 하기 위한 클래스를 만든다.

package.myspring.sample3
public class HelloApp{
public static void main(String[] args){
Resource rs = new ClassPathResource("applicationContext3.xml");//설정파일을 읽어올려면..   스프링 폴더에 docs에 api를 보면.. org.springframework.core.io라는 패키지를 들어가면 ClasspathResource(패키지 안에 같은경로에 있어야 한다.), FileSystemResource(프로젝트 안에 있어야 한다.)두개의 클래스를 사용할수 있다.
XMLBeanFactory factory = new XmlbeanFactory(rs); //xml에 설정되어 잇는 빈객체를 생성하는곳  둘다.. 부모 클래스로 받아준다.
factory.addBeanPostProcessor(new BeanPostProcessorImpl());//BeanPostProcessor 을 궂이 설정하게 되면.. 이렇게 설정하면 된다.
MessageBean bean = (MessageBean)factory.getBean("msgBean"); //위에 xml에 있는 id를 이용할수 있다.
bean.sayHello();
}
}


ApplicationContext에서는




applicationContext4.xml


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="msgBean" class="myspring.sample3.MessageBeanImpl" init-method="init">//초기화 메서드를 만들었기 때문에 여기에다가 설정한다.
<property name="greeting">
<value>안녕하세요.....</value>
</property>
</bean>
<bean class="myspring.sample3.BeanPostProcessorImpl"/> //이곳만 설정해주면 된다.
</beans>








활용을 하기 위한 클래스를 만든다.

package.myspring.sample3
public class HelloApp2{
public static void main(String[] args){
ApplicationContext factory;
factory = new FileSystemXmlApplicatiionContext("applicationContext4.xml");//프로젝트 루트에다가 설정팔일이 있어야 한다.
MessageBean bean = (MessageBean)factory.getBean("msgBean"); //위에 xml에 있는 id를 이용할수 있다.
bean.sayHello();
}
}





----------------------------------------------
AOP(Aspect Oriented Programming)= 관심사항, 관점

객체지향을 쪼금더 객체지향적으로.. 만들어준다.


관점을 두가지로 보면..

1.공통관점 cross-cutting concern
보안, 트랜젝션, 예외처리..같은 그안에서 필요한것들을.. 모든곳에서 중점적으로 필요로 하는곳    


2. 핵심관점
core concern


DI와 AOP의 차이는

DI는 어플리케이션간에 객체간의 결합도를 떨어뜨리는거고..

공통관심사와, 이와 영향을 받는 객체간의 결합도를 떨어뜨리는거다.


AOP의 용어

Join Point : 어떤 메서드의 시작점, 어떤 예외처리의 시작점..(분리를 하기 위해서는 기준점을 말한다.)
Joint Point가 한개이상 모인것을 PointCut이라고 한다.
PoinCut가 모이면 adviece(실제로 코딩을 할수 있는 부분)라고 한다.
advice,PoinCut 함께 모이면 advisor말한다..
advice만 모인것을 aspect라고 한다.


Log4j 를 활용한 AOP의 예

클래스(타겟 클래스)  --- AOP프레임워크(Spring)(호출까지 담당) ---- logging

DI패턴처럼 주입을 할수 있는데, 이것을 weaving라고 한다.

waving할때 세가지 분류

1.컴파일할때,
2.클래스가 로딩할때 끼어 넣을건지..
3.런타임할때 끼어넣을건지..



타겟클래스

connons-logging.jar
spring.jar
window-java-buildpath - user Libraries 에 유저 라이브러리를 선택하고..

springframework/lib/cglib/bglib nodcp2.1_3.jar파일을 추가한다.




package myspring.sample4;
public interface MessageBean{
void sayHello();
}


package myspring.sample4;
public class MessageBeanImpl implements MessageBean{

private String name;
public setName(String name){
this.name = name;
}
public void sayHello(){
try{
Thread.sleep(5000);
}
catch(InterruptedException err){
err.printStackTrace();
}
System.out.println("Hello"+name);
}
}



Advisor을 만들려면..

1.Advice클래스를 작성(로그기록을 출력할 내용을 작성)
2.Advice클래스를 어디에서 실행하는지, 설정파일에서 포인트컷에서 설정한다.
3.Advice와 PointCut을 묶어 놓은 Advisor를 설정한다.
4. 설정파일에서 ProxyFactoryBean클래스를 이용하여, sayHello와 advisor을 연결을 한다.
5. getBean()로 빈객체를 가져와서 사용



Advice클래스를 보면
org.aopalliance.intercept.MethodInterceptor ----BeforeAdvice(조인포인트 실행되기 전에 호출되는 어드바이스),AfterReturnningAdvice (핵심 로직이 호출된후에 실행되는 어드바이스), AroundAdvice(둘다 합쳐놓은 형태의 어드바이스)
org.springframework.aop.IntroductionInterception



package myspring.sample4;

public class logginAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation arg0) throws Throwable{
String methodName = arg0.getMethod().getName(); //조인포인트가 될 메서드의 클래스가 arg0에 전달이 된다.
StopWatch sw = new StopWatch();
sw.start(methodName); //어떤 메서드가 시작될때 시작될건지..
System.out.println("[Log] Method :"+ methodName + "is caling" );
Object obj = art0.proceed();//메서드가 실행되었을때의 시점을 가지고 있다.
sw.stop();
System.out.println("[LOG]Method : " + methodName + "was caaled");
System.out.println("[LOG] 처리시간 : "+ sw.getTotalTimeMillis()/1000 + "초" );
return obj; //객체를 돌려준다.
}
}


어느시점에 어드바이즈를 실행할것인지.. 포인트컷을 설정한다.

applicaitonContext5.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
sxi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="targetBean" class="myspring.sample4.MsgBeanImpl">
<property name="name">
<value>홍길동</value>
</property>
</bean>

<bean id="loggingAdvice" class="myspring.sample4.LoggingAdvice"/>

//2번과 3번을 같이 처리

<bean id="helloAdvisor" class="org.springfamework.aop.support.DefaultPointcutAdvisor">
<property name="advice"> //이부분은 변하지 않는다.
<ref local="logginAdvice"/> //타겟클래스를 넣는다.
</property>
<property name="pointcut"> //이부분은 변하지 않는다.
<been class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern">
<value>*sayHello.*</value>//정규표현식으로포인트컷이될 클래스
</property>
</bean>
</property>
</bean>

//위의 Advisor과 타겟빈을 연결한다.

<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="targetBean"/>
</property>
<property name="interceptorNames">//이부분은 변하지 않는다.
<list>
<value>helloAdvisor</value>
</list>
</property>
</bean>


</beans>








활용을 하기 위한 클래스를 만든다.

package.myspring.sample4
public class HelloApp{
public static void main(String[] args){
Resource rs = new ClassPathResource("applicationContext5.xml");
XmlBeanFactory factory = new XmlBeanFactory(rs);
MessageBean bean = (MessageBean)factory.getBean("proxy");
bean.sayHello();
}
}



Posted by 1010
반응형

Spring MVC Annotation

From JCFWiKi

Jump to: navigation , search 

그림:check.gif 

  • 산출물: Spring MVC Annotation
  • 작성자: 나윤주
  • 최초작성일 : 2008/06/24
  • 최종작성일 : 2008/06/24

Copyright © 2008 Daewoo Information Systems Co., Ltd.

그림:information.gif 

  • 이 문서는 Java 5+환경을 사용하는 Spring Web MVC Framework에서 적용할 수 있는 Annotation에 관한 것이다.


[편집 ] Spring MVC Annotation

  • Spring Web MVC Framework는 Java 5+ 부터 annotation을 제공한다. annotation의 사용으로 설정파일을 간결화하고, View 페이지와 객체 또는 메소드의 맵핑을 명확하게 할 수 있다.

[편집 ] @Controller

  • Controller annotation으로 Controller interface 및 class의 기능을 간단하게 사용할 수 있다.
    • Annotation을 사용하지 않고, Controller를 직접 상속받아 쓰는 경우 필요한 xml 설정을 생략할 수 있다.
    • SimpleFormController, MultiActionController 등 Controller의 종류를 명시하지 않고 @Controller 설정만으로 사용할 수 있다.
  • xxx-servlet.xml 파일에서 component-scan 으로 web controller가 있는 패키지를 명시해 줌으로써, 별도의 bean 설정을 하지 않아도 @Controller로 등록된 클래스 파일에 대한 bean을 자동으로 생성해준다.
    • Controller로 사용하고자 하는 클래스에 @Controller 지정해주면 component-scan으로 자동 등록된다.
<!-- blog-servlet.xml -->
<context:component-scan base-package="blog.web" />
/* BlogController.java */
package blog.web;
 
/* 기타 package import .. */
import org.springframework.stereotype.Controller;
 
@Controller
public class BlogController {
}

[편집 ] @RequestMapping

  • RequestMapping annotation은 url을 클래스 또는 메소드와 맵핑시켜주는 역할을 한다.
    • Annotation을 쓰지 않을때 지정했던 Controller 등록을 위한 url bean 설정을 생략할 수 있다.
  • class에 하나의 url 맵핑을 할 경우, 클래스 위에 @RequestMapping("/url")을 지정하며, GET 또는 POST 방식 등의 옵션을 줄 수 있다.
    • 해당되는 메소드가 실행된 후, return 페이지가 따로 정의되어 있지 않으면 @RequestMapping("/url")에서 설정된 url로 다시 돌아간다.
/* 중간생략 */
 
@Controller
@RequestMapping("/helloWorld")
public class helloController {
	/* 중간생략 */
	
	@RequestMapping(method=RequestMethod.GET)
	public returntype getController() {
		/* .... */
	}
 
	@RequestMapping(method=RequestMethod.POST)
	public returntype postController() {
		/* .... */
	}
 
	/* 중간생략 */
}
  • 메소드별로 url 맵핑을 할 경우는 메소드 위에 @RequestMapping("/url")로 지정한다.
  • return 페이지가 지정되지 않은 경우 원래의 맵핑되었던 url로 돌아간다.
    • return type을 String으로 하여 redirect:url또는 forward:url을 사용하여 다른 페이지로 넘길 수 있다.
/* BlogController.java */
package blog.web;
 
/* 중간생략 */
 
@Controller
public class BlogController {
	/* 중간생략 */
	
	@RequestMapping("/createBlog")
	public ModelMap createBlogHandler() {
		blog = new Blog();
		return new ModelMap(blog);
	}
 
	/* 중간생략 */
}

[편집 ] @RequestParam

  • RequestParam annotation은 key=value 형태로 화면에서 넘어오는 파라미터를 맵핑된 메소드의 파라미터로 지정해준다.
  • 주로 get 방식으로 들어오는 request에서 사용한다.
    • 아래 예제코드에서 xxx/editBlog.do?blogId=3 과 같이 접근할 때, editBlogHandler 메소드의 파라미터인 blogId에는 3이 셋팅된다.
    • 필수 요건이 아닐 경우, @RequestParam(value="id", required="false")와 같이 옵션을 주고 사용할 수 있다.
/* BlogController.java */
package blog.web;
 
/* 중간생략 */
 
@Controller
public class BlogController {
	/* 중간생략 */
	
	@RequestMapping("/editBlog")
	public ModelMap editBlogHandler(@RequestParam("blogId") int blogId) {
		blog = blogService.findBlog(blogId); 
		return new ModelMap(blog);
	}
 
	/* 중간생략 */
}

[편집 ] @ModelAttribute

  • ModelAttribute annotation은 화면의 form 속성으로 넘어온 model을 맵핑된 메소드의 파라미터로 지정해주는 역할을 한다.
  • 주로 POST 타입으로 넘어오는 form 속성의 model 값을 받아올 때 사용된다.
/* BlogController.java */
package blog.web;
 
/* 중간생략 */
 
@Controller
public class BlogController {
	/* 중간생략 */
	
	@RequestMapping("/updateBlog")
	public String updateBlogHandler(@ModelAttribute("blog") Blog blog) {
		blogService.updateBlog(blog);
		return "redirect:findBlogs.do";
	}
 
	/* 중간생략 */
}

[편집 ] @SessionAttributes

  • SessionAttributes annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용할 수 있다.
/* BlogController.java */
package blog.web;
 
/* 중간생략 */
 
@Controller
@SessionAttributes("blog")
public class BlogController {
	/* 중간생략 */
 
	@RequestMapping("/createBlog")
	public ModelMap createBlogHandler() {
		blog = new Blog();
		blog.setRegDate(new Date());
		return new ModelMap(blog);
	}
 
	/* 중간생략 */
}

[편집 ] @InitBinder

@InitBinder annotation은 WebDataBinder를 초기화하는 메소드를 지정할 수 있는 설정을 제공한다. 일반적으로 WebDataBinder는 annotated handler 메소드의 command와 form 객체 인자를 조작하는데 사용된다. Initbinder 메소드는 command/form 객체와 validation result 객체와 대응하는 것을 제외하고 RequestMapping을 지원하는 모든 인자를 지원한다. Initbinder 메소드가 필수적으로 반환값을 가질 필요는 없으며, 일반적으로 이런 경우에 void를 선언한다. 특별한 인자는 WebDataBinder와 WebRequest 또는 Locale의 조합으로 이루어지며, 이러한 조건이 만족되면 context-specific editors를 등록하는 것이 허용된다.

  • WebDataBinder : WebDataBinder는 web request parameter를 JavaBean 객체에 바인딩하는 특정한 DataBinder이다. WebDataBinder는 웹 환경이 필요하지만, Servlet API에 의존적이지 않다. Servlet API에 의존적인 ServletRequestDataBinder와 같이 특정한 DataBinder를 위한 더 많은 base classs를 제공한다.
  • RequestMapping : RequestMapping annotation은 web request를 특정한 handler class와/나 handler method에 매핑하는 역할을 수행한다. 대응하는 HandlerMapping (for type level annotations)과/이나 HandlerAdapter (for method level annotations)가 dispatcher에 존재한다면, @RequestMapping이 처리될 것이다.
  • WebRequest : WebRequest는 웹 요청에 대한 Generic interface이다. 주로 일반 request metadata에 generic web request interceptors의 접근을 허용하여 metadata에 대한 처리를 하기 위한 것이지 request 자체를 처리하기 위한 것은 아니다.
  • @InitBinder 예제

다음의 InitBinder는 Request에 포함된 JSON 데이터를 binding하여 처리하는 역할을 수행한다.

......
@InitBinder
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
 
		if (logger.isDebugEnabled()) {
			logger.debug("entering 'initBinder' method...");
		}
 
		JsonWriterConfiguratorTemplateRegistry registry = JsonWriterConfiguratorTemplateRegistry.load(request);
		registry.registerConfiguratorTemplate(new JsonlibJsonWriterConfiguratorTemplate() {
			@Override
			public JsonConfig getJsonConfig() {
				JsonConfig config = new JsonConfig();
 
				// Exclude all date properties
				config.setJsonPropertyFilter(new PropertyFilter() {
					public boolean apply(Object source, String name, Object value) {
						if (value != null && Date.class.isAssignableFrom(value.getClass())) {
							return true;
						}
						return false;
					}
				});
				return config;
			}
		});
	}
......

[편집 ] Spring MVC Annotation의 장점과 단점

[편집 ] 장점

  • XML 설정파일에 대한 설정을 최소화할 수 있다.
  • 설정방법이 단순하다.
  • 관리해야 하는 XML 설정파일의 개수가 감소한다.
  • 대상 클래스에서 Auto Completion을 통한 구현이 가능하다.
  • 개발자가 설정되는 대상 클래스와 메소드에 대한 정확한 이해(매핑, 파라미터, 모델, 폼 등) 후 적용하므로 유지보수 및 관리가 용이해 진다.
  • 개발자적 입장에서 보았을 때, 보기 명확하며 편안하다.

[편집 ] 단점

  • Java1.5 이상의 환경에서 지원된다.
  • XML 설정파일에서 제공되는 다양한 property 설정이 불가능하다.
  • Annotation의 적절한 사용을 위한 진입장벽이 발생한다. (Learning Curve: 일정 기간의 학습이 필요함)
  • Annotation의 내부 구조 이해가 어렵다.
  • 현재까지 Annotation 사용을 위한 Reference가 부족하다.

[편집 ] Spring MVC Blog 예제 다운로드

  • SpringMVC + springframework + Hibernate3으로 이루어진 예제이다.
  • Spring MVC Blog 예제 다운로드 
  • 데이터베이스는 hsql을 사용하였다. 예제를 실행시키기 전에 data 폴더안의 server.bat 파일을 먼저 실행시켜 데이터베이스를 띄워야한다.

그림:information.gif 

  • 예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. (개인 개발환경  참고)

그림:information.gif 

[편집 ] 참고자료


출처 : http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_Annotation

Posted by 1010
01.JAVA/Java2011. 2. 22. 13:23
반응형

public static String getHanStr(String number) {

                StringBuffer sb = new StringBuffer();
                String[] numArr = { "", "일", "이", "삼", "사", "오", "육", "칠", "팔", "구" };

                // 16자리 어레이로 만들기
                try{
                        int len = number.length();
                        if (len > 16){ throw new Exception("자릿수가 초과했습니다"); }
                        int[] snum = new int[16];
                        for (int i = (snum.length - (len)); i < snum.length; i++){
                                int k = i - (snum.length - len);
                                String a = String.valueOf(number.charAt(k));
                                snum[i] = Integer.parseInt(a);
                        }
                        for (int j = 0; j < 4; j++){
                                int k = (j * 4);
                                if (snum[k] + snum[k + 1] + snum[k + 2] + snum[k + 3] > 0){
                                        if (snum[k] > 0){
                                                sb.append(numArr[snum[k]]).append("천");
                                        }
                                        if (snum[k + 1] > 0){
                                                sb.append(numArr[snum[k + 1]]).append("백");
                                        }
                                        if (snum[k + 2] > 0){
                                                sb.append(numArr[snum[k + 2]]).append("십");
                                        }
                                        if (snum[k + 3] > 0){
                                                sb.append(numArr[snum[k + 3]]);
                                        }
                                        switch (j) {
                                                case 0:
                                                        sb.append("조");
                                                        break;
                                                case 1:
                                                        sb.append("억");
                                                        break;
                                                case 2:
                                                        sb.append("만");
                                                        break;
                                                case 3:
                                                        sb.append("원");
                                                        break;
                                        }
                                }
                        }
                        return sb.toString();
                }catch(NumberFormatException e){
                        return "";
                }catch(Exception e){
                        return "";
                }
        }

Posted by 1010
반응형
설정 간편화

스프링 3은 mvc 네임스페이스를 도입하여 스프링 MVC 설정을 대폭 간편화했다. 지금까지 다른 개선사항들은 스프링 MVC 애플리케이션을 구성하고 실행하는것을 간편화 시켜주지는 않았다. mvc-basic 예제를 통해 살펴보도록 하자.

mvc-basic 예제는 스프링 MVC 기능의 기본 구성을 보여주도록 만들었다. 프로젝트는 spring-samples SVN 저장소에서 얻을 수 있으며 메이븐으로 빌드하고 이클립스로 import할 수 있다. web.xml 부터 시작하여 거기에 있는 설정부터 살펴보자. 주목할 것은 DispatcherServlet이 단일 마스터 스프링 설정 파일로 설정되어 있고 그 안에서 모든 애플리케이션 구성요소를 초기화한다. URL Rewrite를 설정하여 모든 요청을 깔끔하고 REST-스러운 URL로 DispatcherServlet에 보낸다.

마스터 설정 app-config.xml에 서 일반적인 구성을 살펴볼 수 있다. 컴포넌트 스캔으로 클래스패스에서 애플리케이션 구성요소를 찾는다. MessageSource를 설정하여 지역화된 리소스 번들을 설정한다. 마지막으로 애플리케이션의 스프링 MVC 설정을 import한다.

mvc-config.xml 안에서 스프링 3의 첫번째 새 기능을 볼 수 있다.

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />

이 태그는 요청을 @Controller로 디스패치할 때 필요한 HadlerMapping과 HandlerAdapter를 등록한다. 또한 클래스패스에 무엇이 있는지에 따른 감각적인 기본값(sensible defaults)을 제공한다. 그러한 기본값은 다음과 같다.

- 자바빈 PropertyEditor 보다 더 견고한 대체제인 스프링 3 타입 ConversionService 사용하기
- @NumberFormat으로 숫자 필드 포매팅 지원
- @DateTimeFormat을 사용하여 Date, Calendar 포매팅 지원. Joda Time이 클래스패스에 있다면 Joda Time도 포매팅 지원.
- JSR-303 공급자가 클래스패스에 있다면 @Controller 입력값을 @Valid를 사용하여 검증
- JAXB가 클래스패스에 있다면 XML 읽기/쓰기 지원
- Jackson이 클래스패스에 있다면 JSON 읽기/쓰기 지원

꽤 멋지지 않은가? 훗

계속해서 mvc-config.xml 다음 줄에서 또다른 새로운 기능을 살펴보자.

<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="welcome" />

mvc:view-controller는 랜더링할 뷰를 선택하는 ParameterizableViewController를 등록한다. "/"를 요청하면 welcome 뷰를 랜더링하도록 설정했다. 실제 뷰 템플릿은 /WEB-INF/views 디렉토리의 .jsp가 랜더링 된다.

계속해서 mvc-config에서 살펴보지 않은 새로운 기능을 보도록 하자.

<!-- Configures Handler Interceptors -->
<mvc:interceptors>
   <!-- Changes the locale when a 'locale' request parameter is sent; e.g. /?locale=de -->
   <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
</mvc:interceptors>

mvc:interceptors 태그는 모든 컨트롤러에 적용할 HandlerInterceptor를 등록하게 해준다. 이전에는 반복적으로 모든 HandlerMapping 빈에 interceptor들을 등록했었다. 또한 이 태그를 사용하여 인터셉터를 적용할 URL 경로를 제한할 수 있다.

자 지금까지 살펴본 것을 종합하여, 예제를 배포하면 다음과 같은 welcome 뷰가 랜더링 될 것이다.


다른 지역 링크를 클릭하여 LocaleChangeInterceptor가 사용자 지역을 교체하도록 해보자.

데이터 바인딩 간편화

다음으로 설명할 새 기능은 @Controller 바인딩과 검증이다. 몇주 전에 글을 올렸다시피 이 부분에 새로운 기능이 많이 있다.

예제에서, @Controller Example 링크를 클릭하면 다음과 같은 폼이 랜더링 된다.


이 폼은 지역 정보 변경에 따라 국체화 필드 포매팅이 적용된다. 예를 들어, en에서 de로 바꾸면 날짜 형식을 12/21/10에서 12.12.10으로 바꾼다. 이런 동작과 폼 검증 규칙은 모델 애노테이션을 기반으로 한다.

public class Account {

    @NotNull
   @Size(min=1, max=25)
   private String name;

    @NotNull
   @NumberFormat(style=Style.CURRENCY)
   private BigDecimal balance = new BigDecimal("1000");

    @NotNull
   @NumberFormat(style=Style.PERCENT)
   private BigDecimal equityAllocation = new BigDecimal(".60");

    @DateTimeFormat(style="S-")
   @Future
   private Date renewalDate = new Date(new Date().getTime() + 31536000000L);

}

폼 서브밋은 다음의 AccountController 메서드가 처리한다.

@RequestMapping(method=RequestMethod.POST)
public String create(@Valid Account account, BindingResult result) {
   if (result.hasErrors()) {
       return "account/createForm";
   }
   this.accounts.put(account.assignId(), account);
   return "redirect:/account/" + account.getId();
}

이 메소드는 바인딩과 검증 작업 이후에 호출되며, Account 검증은 @Valid 애노테이션에 의해 수행된다. 만약 어떠한 검증 에러라도 존재한다면 createForm을 다시 랜더링 한다. 그렇지 않을 경우 Account는 저장되고 사용자는 http://localhost:8080/mvc-basic/account/1로 리다이렉트 된다.

또 다른 멋진 기능을 사용해보려면 /account/99 같이 존재하지 않는 계정을 요청해보기 바란다.

요약

스프링 3은 다양한 새 기능과 여러 기존 분야에 대한 간편화를 제공한다. 이 글을 통해 여러분에게 유용한 새로운 스프링 MVC 개선 사항들을 파악했기를 바란다. 맨 처음에 언급했듯이 더 많은 "스프링 3 간편화" 시리즈를 통해 계속해서 스프링 최신 버전의 새롭고 흥미로운 기능들을 소개할테니 기대하기 바란다.

출처 : http://whiteship.me/2517
Posted by 1010
01.JAVA/Java2011. 2. 12. 16:56
반응형
HttpRequestWithModifiableParameters param = new HttpRequestWithModifiableParameters(request); //요렇게 생성해서
param.setParameter(name, values); //요렇게 값 넣고

request = (HttpServletRequest)param; //req로 받으면 됩니다.




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


public class HttpRequestWithModifiableParameters extends HttpServletRequestWrapper {
 
    HashMap params;
    
    /**
     * @param request
     */
    public HttpRequestWithModifiableParameters(HttpServletRequest request) {
        super(request);
        this.params = new HashMap(request.getParameterMap());
    }
 
    /* (non-Javadoc)
     * @see javax.servlet.ServletRequest#getParameter(java.lang.String)
     */
    public String getParameter(String name) {
        String returnValue = null;
        String[] paramArray = getParameterValues(name);
        if (paramArray != null && paramArray.length > 0){
          returnValue = paramArray[0];   
        }
        return returnValue;
    }
    /* (non-Javadoc)
     * @see javax.servlet.ServletRequest#getParameterMap()
     */
    public Map getParameterMap() {
        return Collections.unmodifiableMap(params);
    }
    /* (non-Javadoc)
     * @see javax.servlet.ServletRequest#getParameterNames()
     */
    public Enumeration getParameterNames() {
        return Collections.enumeration(params.keySet());        
    }
    /* (non-Javadoc)
     * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String)
     */
    public String[] getParameterValues(String name) {
    	String[] result = null;
    	String[] temp = (String[])params.get(name);
    	if (temp != null){
    		result = new String[temp.length];
    		System.arraycopy(temp, 0, result, 0, temp.length);    		
    	}
        return result;
    }
       
    
    /**
     * Sets the a single value for the parameter.  Overwrites any current values.
     * @param name Name of the parameter to set
     * @param value Value of the parameter.
     */
    public void setParameter(String name, String value){
      String[] oneParam = {value};
      setParameter(name, oneParam);
    }
    
    /**
     * Sets multiple values for a parameter.
     * Overwrites any current values.
     * @param name Name of the parameter to set
     * @param values String[] of values.
     */
    public void setParameter(String name, String[] values){
      params.put(name, values);   
    }
}
Posted by 1010
61.Linux2011. 2. 10. 11:24
반응형

Java Runtime Environment(JRE)에 대한 Linux x64 RPM 다운로드 및 설치 지침


적용 대상::
  • 플랫폼: Red Hat Linux, SUSE Linux
  • 브라우저: Mozilla 1.4+
  • Java 버전: 1.5.0

다음 단계에 따라 Linux용 JRE를 다운로드하여 설치합니다.
  1. 다운로드
  2. 설치


Linux 시스템 요구 사항

플랫폼 버전 메모리 브라우저 디스크 공간
LINUX 32비트
Intel IA32 Red Hat 9.0 64MB Mozilla 1.4+ 58MB
Red Hat Enterprise Linux AS 3.0 64MB
Red Hat Enterprise Linux WS 2.1 64MB
Red Hat Enterprise Linux ES 2.1 64MB
Red Hat Enterprise Linux AS 2.1 64MB
SuSE 8.2 64MB
SLEC 8 64MB
SLES 8 64MB
TurboLinux 8.0 64MB
Sun Java Desktop System, Release 1 64MB
Sun Java Desktop System, Release 2 64MB

AMD Opteron 32비트 Red Hat Enterprise Linux AS 3.0
SLES 8

LINUX 64비트
AMD Opteron 64비트 Red Hat Enterprise Linux AS 3.0
Mozilla 1.4+ 56MB
SLES 8




I. 다운로드
  1. http://java.com 으로 이동합니다.
  2. Java 소프트웨어 다운로드 버튼을 누릅니다.

    주: Linux RPM(Redhat Package Manager)은 RPM을 사용하여 JRE를 설치합니다. 이 방법을 사용하려면 시스템에서 RPM을 사용할 수 있어야 합니다.

    주: 다음은 JRE 1.5.0_02 설치를 위한 지침입니다. 다른 버전을 설치하는 경우에는 터미널에 명령을 입력할 때 버전 번호를 적절하게 변경하십시오.
RPM Linux x64 다운로드 버튼을 누릅니다.
  1. Linux RPM x64 패키지 옆에 있는 다운로드 버튼을 누릅니다.
  2. 다운로드한 후 다음을 확인합니다.
  3. Linux RPM x64 패키지의 경우
    • 파일 이름이 jre-1_5_0_02-linux-amd64-rpm.bin입니다.
    • 크기가 약 14.91MB입니다.
II. Linux RPM x64 파일을 설치하려면

다음 지침을 따릅니다.
  1. 터미널에 다음을 입력합니다.
    su
  2. 루트 암호를 입력합니다.
  3. 설치할 디렉토리로 변경합니다. 다음을 입력합니다.
    cd
    예를 들어 소프트웨어를 /usr/java/ 디렉토리에 설치하는 경우 다음과 같이 입력합니다.
    cd /usr/java

    루트 액세스에 대한 참고 사항: JRE를 /usr/local과 같은 시스템 차원의 위치에 설치하려는 경우 필요한 권한을 얻으려면 루트 사용자로 로그인해야 합니다. 루트 액세스 권한이 없으면 JRE를 홈 디렉토리나 쓰기 권한이 있는 하위 디렉토리에 설치합니다.
  4. 다운로드한 파일을 실행할 수 있도록 권한을 변경합니다. 다음을 입력합니다.
    chmod a+x jre-1_5_0_02-linux-amd64-rpm.bin
  5. 파일을 실행할 권한이 있는지 확인합니다. 다음을 입력합니다.
    ls -l
설치 파일에 대한 권한 변경
  1. 설치 프로세스를 시작하려면 다음을 입력합니다.
    ./jre-1_5_0_02-linux-amd64-rpm.bin
    주: 파일이 현재 디렉토리에 들어 있는 경우는 파일 앞에 './'를 추가해야 합니다.

    이진 라이센스 계약서가 표시됩니다. 계약서를 자세히 읽어보십시오. 스페이스바를 누르면 다음 페이지가 표시됩니다. 계약서 끝에서 yes를 입력하여 설치를 계속합니다.
Yes를 입력하여 라이센스 계약에 동의
  1. 설치 파일이 현재 디렉토리에 jre-1_5_0_02-linux-amd64.rpm 파일을 만듭니다.
  2. 터미널에서 RPM 명령을 실행하여 패키지를 설치합니다. 다음을 입력합니다.
    rpm -iv jre-1_5_0_02-linux-amd64.rpm
RPM 압축 풀림 완료
  1. JRE가 현재 디렉토리의 1.5.0_(버전 번호) 하위 디렉토리에 설치됩니다. 여기서는 /usr/java 디렉토리에 설치됩니다. jre1.5.0_02 하위 디렉토리가 현재 디렉토리 아래에 나열되는지 확인합니다. 다음을 입력합니다.
    ls
설치 확인
  1. 디스크 공간을 절약하려면 bin 파일과 rpm 파일을 삭제합니다.
  2. 루트 셸을 끝냅니다.
Posted by 1010
61.Linux2011. 2. 8. 14:53
반응형
#sudo apt-get install virtualbox-ose-guest-x11
#sudo reboot
Posted by 1010
반응형

Developing a Spring Framework MVC application step-by-step

Authors

Thomas Risberg, Rick Evans, Portia Tung

2.5

Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Table of Contents

Overview
1. What's covered
2. Prerequisite software
3. The application we are building
1. Basic Application and Environment Setup
1.1. Create the project directory structure
1.2. Create 'index.jsp'
1.3. Deploy the application to Tomcat
1.4. Check the application works
1.5. Download the Spring Framework
1.6. Modify 'web.xml' in the 'WEB-INF' directory
1.7. Copy libraries to 'WEB-INF/lib'
1.8. Create the Controller
1.9. Write a test for the Controller
1.10. Create the View
1.11. Compile and deploy the application
1.12. Try out the application
1.13. Summary
2. Developing and Configuring the Views and the Controller
2.1. Configure JSTL and add JSP header file
2.2. Improve the controller
2.3. Decouple the view from the controller
2.4. Summary
3. Developing the Business Logic
3.1. Review the business case of the Inventory Management System
3.2. Add some classes for business logic
3.3. Summary
4. Developing the Web Interface
4.1. Add reference to business logic in the controller
4.2. Modify the view to display business data and add support for message bundle
4.3. Add some test data to automatically populate some business objects
4.4. Add the message bundle and a 'clean' target to 'build.xml'
4.5. Adding a form
4.6. Adding a form controller
4.7. Summary
5. Implementing Database Persistence
5.1. Create database startup script
5.2. Create table and test data scripts
5.3. Add Ant tasks to run scripts and load test data
5.4. Create a Data Access Object (DAO) implementation for JDBC
5.5. Implement tests for JDBC DAO implementation
5.6. Summary
6. Integrating the Web Application with the Persistence Layer
6.1. Modify service layer
6.2. Fix the failing tests
6.3. Create new application context for service layer configuration
6.4. Add transaction and connection pool configuration to application context
6.5. Final test of the complete application
6.6. Summary
A. Build Scripts
Posted by 1010
98..Etc/Etc...2011. 2. 7. 12:39
반응형
야후에서 만든 YUI Compressor도 있죠.
하 지만 구글에서 만든 Closure Compiler는 다양한 방법으로 제공합니다. YUI Compressor같은 경우에는 java로 만든 jar파일을 통해 콘솔로 실행하는 법 밖에 없는 반면에 Closure Compiler는 웹에서 UI형태, API, 애플리케이션(JAR형태) 3가지 방법이 존재합니다.

Google Code프로젝트 Closure Compiler
http://code.google.com/intl/ko-KR/closure/compiler/

UI페이지는 아래와 같습니다.
http://closure-compiler.appspot.com/

URL을 보면 appspot인 것을 보니, 구글앱엔진으로 만들어진 것 같습니다^^ 구글은 구글제품을 활용을 너무 잘하네요^^
이 사이트에 가보면 좌측이 원본소스를 입력하는 곳이 있고, 우측에 컴파일된 파일이 나오는 곳이 있습니다. 사용법은 간단하네요~ 근데 모드를 3가지 중 선택할 수 있는데, 하나는 그냥 공백만 없애고, 하나는 노멀한 심플모드고, 하나가 Advanced모드인데, 이걸로 하니 내부 변수까지 다 바꿔버리네요. 그래서 이걸 사용하고 있는 곳에도 같이 compile을 해버리던가 아님 사용하고 있는 곳에 변수를 바꿔줘야하네요^^
물론 Advanced모드가 훨씬 많이 줄어드네요^^ 변수명도 한자리로 다 바뀌고 ^^

사용자 삽입 이미지

잘 안보이는데-_-
Original Size: 3.56KB (1.07KB gzipped)
Compiled Size: 2.82KB (835 bytes gzipped)
요렇게 줄어들었네요~ 좋네요~

API 방식을 이용해서 다양하게 응용이 가능할 것 같네요.
저희도 개발할 땐 그냥 개발하다가 배포시에는 컴파일해서 배포하도록 스크립트를 짤 수도 있고 뭐 그런식으로 응용이 가능할 듯 합니다^^


출처 : http://mudchobo.tistory.com/?page=4
Posted by 1010
반응형
사용자 삽입 이미지
Posted by 1010
반응형

XHTML Strict부터는 target속성이 폐기되었습니다. (이용자의 이동 선택권 침해 때문)

따라서 xhtml strict를 준수하기 위해서는 아래의 방법을 사용해 새로운 창을 띄워야 합니다.


<a href="http://www.aaa.com" onclick="window.open(this.href,'_blank');return false;">[이동]</a>

원칙대로 생각해보자면 위의 방법도 사용하지 않는것이 옳습니다만, 불가피하게 사용할때는 유용한 방법입니다.

 

단, 위의 방법 사용시에는 레퍼러가 남지 않습니다.


출처 : http://ajax.textcube.com/2

Posted by 1010
반응형
 

첫째, ‘실전 웹 표준 가이드’(무료배포, PDF형식)로 웹 표준 개념잡기

아직 ‘실전 웹 표준 가이드(모질라 커뮤니티 배포)’ 라는 문서를 접해보지 못한 분이 계시다면 우선 읽어보실 것을 권합니다. ‘실전 웹 표준 가이드’ 는 국내에서 웹 표준으로 잘 알려진 분들(윤석찬, 신현석, 이성노, 신정식)께서 저작하고 ‘KIPA(한국소프트웨어진흥원)‘ 와 ‘IABF(정보통신 접근성 향상 표준화 포럼)‘ 에서 무료로 배포하는 PDF 형식의 자료 입니다. 목차는 아래와 같으며 다른 어떤 서적보다 먼저 읽어볼 것을 권해드립니다. 표준 XHTML/CSS/DOM 구현 기법과 웹 표준 방식의 개발 프로세스에 대한 개념을 전반적으로 다루고 있습니다.

  1. 실전 XHTML 가이드
  2. 실전 CSS 레이아웃
  3. 실전 DOM/Script 가이드
  4. 실전 표준 웹 프로그래밍
  5. 실전 웹 표준 개발 프로세스
  6. 웹 표준 브라우저 호환표

PDF 형식의 ‘실전 웹 표준 가이드’ 직접 다운로드: 모질라 방문

둘째, ‘웹 접근성을 고려한 콘텐츠 제작기법’(무료배포, PDF)으로 HTML 다시배우기

‘실전 웹 표준 가이드’ 가 웹 표준과 관련하여 다양한 실무분야를 다룬것에 비하여 KADO(한국정보문화진흥원) 에서 발간한 연구보고서 ‘웹 접근성을 고려한 콘텐츠 제작기법‘ 은 (X)HTML의 바른 바크업(Valid Markup & Semantic Markup)에 대하여 보다 집중적으로 세세하게 다루고 있습니다. 웹 표준을 처음 접하는 개발자들은 당장의 필요(현실)에 의하여 바른 Markup 보다 CSS 관련기법을 먼저 학습하는 경우가 많은것 같은데 이는 다소간의 조율이 필요합니다. Markup 이 잘못되면 아무리 유능한 CSS 기법이라 할지라도 ‘그 의미가 없다’ 할 수 있습니다. ‘실전 웹 표준 가이드’ 다음으로 읽어볼 것을 추천합니다. 이 문서에는 ‘한국형 웹 콘텐츠 접근성 지침(KWCAG) 1.0‘ 이 함께 첨부되어 있습니다. 참여(최두진 센터장, 김석일 교수, 홍경순 팀장, 조웅희 대표, 신승식 과장, 현준호 전임연구원).

  1. 웹 접근성이란?
  2. 대체 텍스트
  3. 동영상
  4. 색상
  5. 이미지 맵
  6. 프레임
  7. 깜박임, 움직임
  8. 장치 독립성
  9. 링크를 통한 이동
  10. 시간 제한
  11. 데이터 테이블
  12. 콘텐츠의 배치
  13. 온라인 양식(form)
  14. 스크립트, 애플릿
  15. 별도(대체) 페이지
  16. 첨부 : 한국형 웹 콘텐츠 접근성 지침 1.0

PDF 형식의 ‘웹 접근성을 고려한 콘텐츠 제작기법’ 직접 다운로드 : 모질라 제공

셋째, 예제중심의 ‘웹 표준 완전정복 세트’(3권 1셋)로 CSS 스킬 향상

아래 소개하는 책보다 지금은 미투데이 서비스로 더욱 유명해지신 박수만님께서 번역하신 책입니다. 아래 책은 가장 많은 분들에게 알려져 있어서 굳이 설명이 필요없을것 같습니다. 최근에는 3권을 하나의 셋트로 묶어 ‘웹 표준 완전정복‘ 이라는 패키지로 판매(정가 66,000, 할인가 59,400)하고 있군요. 예제중심이므로 CSS에 대한 기본지식이 있다면 아래 세권은 모두 빠르게 읽어내려가실 수 있습니다.

  1. 실용예제로 배우는 웹표준
    1. 리스트
    2. 머리글
    3. 테이블을 쓰면 안된다?
    4. 인용문
    5. 구문표현 엘리먼트
    6. 앵커
    7. 리스트의 고급 기능
    8. 마크업 용량 줄이기
    9. CSS적용하기
    10. 인쇄를 위한 스타일
    11. CSS로 레이아웃 잡기
    12. 텍스트 스타일
    13. 이미지 바꿔치기
    14. <body>를 위한 스타일
    15. 새로운 도약
    16. 부록1 – 웹 표준 블로그 만들기
    17. 부록2 – 국내외 웹 접근성 소개 및 현황
  2. 웹 2.0을 이끄는 방탄웹
    1. 글꼴 크기를 내 마음대로
    2. 자유롭게 크기가 조절되는 네비게이션 메뉴바
    3. 자유자재로 높낮이가 조절되는 행 만들기
    4. 나만의 Float 활용 비법
    5. 깨지지 않는 상자 만들기
    6. 이미지나 CSS가 없이도 볼 수 있게 하기
    7. 쉽게 변환할 수 있는 테이블 만들기
    8. 유동적인 레이아웃 만들기
    9. 방탄웹 구축 완결 종합편
  3. CSS 마스터 전략
    1. 기초 다지기
    2. 화면 표시를 위한 모델 완벽 정리
    3. 배경 이미지와 이미지 대치 기법
    4. 링크 모양 꾸미기
    5. 리스트 스타일과 네비게이션 바 만들기
    6. 접근성 높은 폼과 테이블 만들기
    7. 레이아웃
    8. 핵과 필터
    9. 브라우저 버그 해결하기
    10. 부록1 – 동호회 사이트 만들기
    11. 부록2 – 투스카니 럭셔리 리조트

YES24에서 ‘웹 표준 완전정복’ 구매하기

넷째, ‘웹 표준 교과서’로 W3C의 방대한 표준 스펙 이해하기

저는 지금도 (X)HTML/CSS 스펙을 확인하기 위하여 일주일에 2~3번은 W3C 웹사이트에 방문합니다. 하지만 W3C에 방문해도 원하는 목적을 달성하지 못하는 경우가 있는데, 그 의미가 명확하지 않거나 원문으로 되어 있어서 이해하기 힘들기 때문입니다. 처음 ‘웹 표준 교과서‘라는 책을 받았을 때에는 마치 사전 같다는 생각을 했는데 정말 사전 같습니다.(ㅡㅡ;) 그리고 마치 W3C의 스팩 해설서 같습니다. 이런 책을 보면 안읽고는 배겨내기 어렵기 때문에 앞에서부터 보려고 시도하였지만 이러한 방식 보다는 가까운 곳에 두고 필요할 때마다 필요한 페이지를 펼쳐보는 방식으로 접근해야 겠다고 생각을 바꿨습니다. 지금까지 소개한 책들 가운데 가장 빈틈없는 웹 표준 서적이라고 소개드리고 싶습니다. NmindPlus라는 블로그로 잘 알려져 있고 NHN Japan에 근무하시는 김대석님께서 번역해 주셨습니다.

  1. 소개 – 웹표준은 무엇인가
  2. 문서구조 – XHTML 웹페이지 구축 시작
  3. 시각표현 – CSS 웹페이지를 자유롭게 디자인 하기
  4. 상호작용 – 웹 사이트를 장식하는 다양한 콘텐츠
  5. 리디자인 – 웹표준으로 매끄러운 전환
  6. 크로스 브라우저 레이아웃 – 브라우저를 차별하지 않는 레이아웃 기법
  7. 접근성 – 다양한 사용자를 배려하는 설계
  8. 메타데이터 – 효율적인 정보 수집을 지원하는 웹 기술

YES24에서 ‘웹 표준 교과서’ 구매하기

다섯째, ‘DOM 스크립트’로 Javascript 다시 배우기

DOM 스크립트‘는 기존의 자바스크립트 서적과는 확실히 다릅니다. 자바스크립트 문법을 알려주기 전에 ‘지금 구현하려고 하는 기능이 정말 사용자에게 유용한 것인가? 오히려 웹의 가치를 훼손하고 있지는 않은가?’ 라는 질문을 던져주고 사용성과 접근성을 해치지 않으면서도 웹 표준에 근거한 겸손한 코드를 작성할 수 있도록 개념을 새롭게 환기시켜 주는 책입니다. 웹의 접근성을 떨어뜨리지 않으면서 사용자 경험을 확장할 수 있는 방법으로 고민하고 있다면 이 책이 좋은 입문서가 될 것 같습니다. 특히, 이 책에서 소개하고 있는 ‘단계적 기능축소, 스크립트 분리’와 같은 개념들은 매우 중요하게 생각되는군요. 한국의 대표적인 웹 표준 전도사로 잘 알려진 다음 커뮤니케이션의 윤석찬님께서 번역하셨습니다.

  1. 간단히 살펴보는 자바스크립트 역사
  2. 자바스크립트 문법 익히기
  3. 문서 객체 모델(DOM)이란?
  4. 자바스크립트로 만드는 온라인 사진첩
  5. 꼭 알아야 할 핵심 기본기
  6. 사진첩 기능 개선하기
  7. 실행 시에 마크업 코드 생성하기
  8. 의미가 살도록 컨텐츠 개선하기
  9. CSS와 DOM 연동하기
  10. 애니메이션 슬라이드쇼 만들기
  11. 총정리 : 더블트랙 밴드 웹사이트 제작
  12. DOM 스크립트의 미래
  13. 부록1 – 유용한 DOM 메소드와 프로퍼티
  14. 부록2 – 웹 표준 기반의 멋진 DOM 스크립트 예제
  15. 부록3 – 다이내믹한 웹사이트를 위한 고려 사항


출처 : http://web.dicnote.com/bbs/board.php?bo_table=web_tip&wr_id=718

Posted by 1010
반응형
ie 에서 사용한걸
f.txtEstopn.value = eval("document.all."+estopn+".innerText");
 


ee 에서도 사용하게..
 f.txtEstopn.value = document.getElementById(estopn).innerHTML;
Posted by 1010
반응형
1. W3C html Validator : Xhtml 1.0 Transitional 표준 문법 준수 판단
http://validator.w3.org

2. W3C CSS Validator : CSS2.1표준 문법 준수 판단
http://jigsaw.w3.org/css-validator

3. Kado-Wah : 웹접근성 자동 검증툴
http://www.wah.or.kr/Achive/Kadowah.asp

4. AIS : IE에서 작동하는 웹접근성 툴바
http://www.visionaustralia.org.au/ais/toolbar

5. Firefox Webdeveloper Toolbar : 파이어폭스 웹접근성 툴바
https://addons.mozilla.org/ko/firefox/addon/60
Posted by 1010
반응형
ㅇ try catch문

   사용할때 : 보통 자바스크립트로 작업하다 보면 정말 어떨때는 구문에서 틀리지도 않았는데,
               브라우저 버젼에 따라 에러가 발생하기도 하고, 정말 몇달간 디버깅에 지칠때도 있다.
               대부분 열심히하면 나타나는데, 다음의 try catch문을 사용하면 편리하다.
   사용예   :
             try
             {
                  // 실제 실행시킬부분
                  var a   = opener.Location.href;
             }
             catch (e)
             {
                  // 위의 "실행시킬부분"에서 에러가 났을때 처리해줄 부분
                  alert ("opener를 찾을수 없습니다.");
             }
             finally
             {
                  // 에러가 나든 나지 않든 무조건 실행시키는 부분
                  window.status   = "opener.locatoin.href 부분 실행되었음";
             }
ㅇ typeof문
   사용할때 : 보통 데이터나 오브젝트 타입등을 검사할때 많이 사용하는데.
                만약 "undefined"이면 인식을 못한거고 "unknown"이 나올때가
                있다.. 만약 부모창에서 새창을 열고 부모창을 닫았는지 새창에서 검사할때
                if (typeof (opener) == "unknown") 이면 으로 검사할때 유용하다~ㅇ

ㅇ regExp (정규표현식)
   사용할때 : 만약 <textarea name="taContent"></textarea>에 사용자가 입력한  value값중에서
                "/아싸1/" ~ "/아싸10/" 까지를 다 "/호호1/" ~ "/호호10/" 까지로 바꿀려면 어케할까?
               
                var sTaContent   = taContent.value;
                for (var nI = 1; nI <= 10; nI++)
                {
                       var expTest = new RegExp("/아싸" + nI + "/", "ig");   // i는 대소문자 구분없고, g는 중복되어도 다처리
                       sTaContent   = sTaContent.r-place (expTest, "/호호" + nI + "/");
                }
                taContent.value   = sTaContent;
             
                하면 된다~ㅇ

                위의 expTest의 메소드들도 몇개있으므로 알아두면 많이 도움이 된다~ㅇ
                또한, 게시판의 글보기에 나오는 글들에 자동링크 걸때도 사용한다~ㅇ



ㅇ var a="08", b="09"일때
   parseInt (a)나 parseInt (b)의 값은 0 이다
   Number (a)나 Number (b)값을 해야 제대로 8과 9의 값이 나온다~ㅇ
   한번 고생한적이 있어서여~ㅇ 다른분들에게 도움이 되었으면...



ㅇ   <img name="pic1" src="">
   <img name="pic2" src="">
   <img name="pic3" src="">

   위와 같이 있고 javascript에서 pic1 ~ pic3의 src주소값을 바꾸고자 할때
   
   for (var nI = 1; nI <= 3; nI ++)
   {
        e-al("document.pic" + nI + ".src ='http://image.aaa.com/p" + nI + ".gif'");
   }
   
   위와 같이 eval을 넣어주어야 되더라구여~ㅇ



ㅇ 현재의 html파일을 다른이름을로 저장할때 뜨는 dialog박스를 열어서 저장하고 싶을때
   
   그냥 다음한줄을 실행시키면 저장 dialog박스가 뜨는걸로 뭐하는지 알겁니다~ㅇ
   document.execCommand("SaveAs", null, "a.html")

   다르게하면 다음의 한줄을 넣고
   <iframe name="ID_LOG" style="display:none"></iframe>가 body에 있다고 하고

   var sHTML = "<center>Testing...</center>";
   document.all.ID_LOG.document.close ();
   document.all.ID_LOG.document.write (sHTML);
   document.all.ID_LOG.document.execCommand("SaveAs", null, sFileName);

   하면 Testing가 찍히는 html문서를 저장할수 있져~ㅇ 그런데 이거는 IE 5.5이상에서만 됩니다.

   5.0에서는

   var sHTML   = "<input type='button' value='저장' 허용되지않은 태그 사용중=\"window.document.execCommand('SaveAs', null, 'a.html')\">";
       sHTML   += "<br><center> Testing..</center>";
   
   var oLogWin   = window.open ("", "popLog", "어쩌구...");
   
   oLogWin.document.write (sHTML);

   해서 새창띄워서 클릭하게 하면 됩니다~ㅇ



ㅇ 그리고 Javascript에서 name이나 id값이 같은것이 있으면 Array로 변하더군요...
   Javascript많이 사용하다보면 많이 접하셨을겁니다~ㅇ
   
   동적으로 name이나 id값이 1나 1이상을로 늘어날때에

   <span id="ID_A"></span>
   <span id="ID_A"></span>
   이 있다고 할때

   Javascript 안에서 에서

   var oID_A   = document.all.ID_A;

   if (typeof (oID_A [0]) != "undefined")) // 1개 이상일때
   {
   
   }
   else   // 1개만 있을경우
   {
   
   }

   물론 "ID_A" id값을 가지고 있는것이 있는지 먼저 검사하면 좋져~ㅇ



ㅇ 만약 a와 b와 c의 값을 구분자 ","로 구분하는 String (a,b,c)을 만들고 싶을때

   var oTmpArray = new Array ("a", "b", "c");
   var sValue = oTmpArray.j-in (",");



ㅇ javascript 연관배열
   
   var oMethod =   {
        "ALERT"   : goAlert,
        "MSG"   : goMsg
   }

   oMethod ["ALERT"] 는
   goAlert가 됩니다.



ㅇ 허용되지않은 태그 사허용되지않은 태그 사용중그 사용중, onMousewheel... 등등의 이벤트를 붙이거나 떼기
   
   window.attachEvent ("onscroll", procScroll);
    하면 onscroll이벤트 발생시 procScroll함수 실행
   
   window.detachEvent ("onscroll", procScroll);
   하면 onscroll이벤트 떼기



ㅇ 움직이는 gif이미지를 key이벤트나 등등 이벤트사용하면 움직이던 gif이미지가 멈추어버립니다.
   알고보니 return값땜시 "event.returnValue = 'false'" 해주면 되더라구여~ㅇ



ㅇ ActiveX를 사용시 ActiveX클라이언트가 ActiveX를 다운 받았는지 확인할때는
   
   <object name=AX1 id=AX1></object> 가 있을때

   var bnResult   = typeof (AX1.proc) == "unknown")? true : false;
   proc는 AX1의 method입니다~ㅇ
   이렇게 확인하면 되더라구여~ㅇ



ㅇ F5번 누를때 경고창(confirm같은것)띄워서 새로고침 할건지 물어보기
   
   window.onbeforeunload   = hoho ();

   function hoho ()
   {
        var sMsg = "새로고침을 정말로 정말로 정말로 할꺼예여?";
        return (sMsg);
   }
   물론 F5번 눌렀을때를 key Event로 잡아서 함수안에서 실행해도 됩니다~ㅇ



ㅇ VBscript에만 있는줄 알았던 with 많이 쓰일때가 있더군요 switch문을 안에다가 사용하면 정말 깔끔!
   
   with (window)
   {
           = pageOnLoad;
        o-unload = pageUnload;
   }

Posted by 1010
반응형
img tag 에 onclick="javascript:self.close();" 을 사용하면 w3c에 잘못된 형식이라고 나온다


이때는


<img src="/image/biz/s_close.gif" width="42" height="25" onclick="self.close();" style="cursor:hand" alt="현재창을 닫습니다.">


이런식으로...img 안에 self 내장객체를 인식하지 못해서 그런거 같기도 하고...

여튼..대충 보면 알듯...
Posted by 1010
98..Etc/70.JEUS2010. 12. 21. 09:48
반응형

Tidy: character ";" not allowed in attribute specification list

Possible Cause:

Unescaped JavaScript generates multiple validation errors, this is one of them.

Example:


잘못된 예
<script language="javascript">
for(x=0;x<item.length;x++){
    //
}
</script>

올바른 예
<script language="javascript">
//<![CDATA[
for(x=0;x<item.length;x++){
    //
}
//]]>
</script>

Solution:

Wrap the JavaScript code in CDATA; Hide the CDATA from JavaScript with a // comment.

References:

Posted by 1010