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

  1. 2009.09.27 물론 이클립스에서는 아주 간단하게 대부분의 추가 기능을 장착할 수 있도록 지원합니다.
  2. 2009.09.27 Google에서 GWT
  3. 2009.09.25 Google Plugin for Eclipse 3.5(Galileo) 이클립스 3.5 용 구글 플러그인
  4. 2009.09.25 •The Google Plugin for Eclipse, for Eclipse 3.5 (Galileo):
  5. 2009.09.25 JFree Chart Plugin
  6. 2009.09.24 ORA-02069: global_names parameter must be set to TRUE for this operation
  7. 2009.09.21 [펌] spring 2.5 자동화 유틸
  8. 2009.09.16 @SuppressWarnings("unchecked") 란 무엇인가?
  9. 2009.09.15 javascript 익명함수 예제
  10. 2009.09.14 smtp 메일 보내기
  11. 2009.09.08 유용한 자바스크립트 하나
  12. 2009.09.03 Request Object
  13. 2009.09.03 eclipse OutOfMemoryError: PermGen space 1
  14. 2009.09.03 Eclipse Galileo 시작시 JVM 종료 에러 해결
  15. 2009.09.03 오라클에서의 데이터 암호화 기능
  16. 2009.09.01 jQuery mootools 충돌 해결
  17. 2009.09.01 jQuery로 작업하기, Part 1: 브라우저로 데스크톱 응용 옮기기
  18. 2009.09.01 JAR 파일
  19. 2009.08.31 자바스크립트 휴대폰번호 검증 ( 간단한 정규식 표현)
  20. 2009.08.28 html 즐겨찾기 추가
  21. 2009.08.26 document.all 을 쓰지 맙시다!
  22. 2009.08.26 location.href 에서 target=_blank 효과 사용
  23. 2009.08.26 firefox 에서 form submit 이 안될경우
  24. 2009.08.26 파이어폭스에서 javascript 시 this.value 가 않먹을때
  25. 2009.08.26 Ajax 한글 파라미터 보내기 2
  26. 2009.08.25 아파치 앤트용 외부 자료의 목록
  27. 2009.08.25 java jsp 소스 코드 정렬 플러그인
  28. 2009.08.25 java jsp 소스 코드 정렬 플러그인 1
  29. 2009.08.25 사람을 위한 자동화: Eclipse 플러그인으로 코드 품질 높이기
  30. 2009.08.25 [java] java.util.Calendar 사용한 날짜출력 및 윤년 판단 조건식
98..Etc/GWT2009. 9. 27. 16:35
반응형
물론 이클립스에서는 아주 간단하게 대부분의 추가 기능을 장착할 수 있도록 지원합니다.
하지만 조금 크다고 하는 IT 관련 회사에서는 내부적으로 방화벽을 어찌나 잘 구축해 놓았던지 업데이트 관련한 네트웍을 거의 무용화 시켜 버리더군요.

그래서 이에 대해 조금이라고 고생을 해본 프로그램제공업자들은 로컬로 업데이트할 수 있는 방법을 제공하기도 합니다.
하지만 구글에서는 GWT(Google Web Toolkit)을 제공하면서 그렇게 하지 않았더군요. ㅎ..

GWT를 이용해보고자 하는 열망에 어느정도의 삽질을 통해 다음과 같은 방법을 찾았습니다.
언제쯤 이클립에서 몇번의 클릭만으로 원하는 기능을 장착하게 될런지.. ㅎ..

어쨋든..
일단 임시디렉토리를 하나 만들어 놓습니다.
저같은 경우는 "/GWT" 머 이렇게 만들어 놓았습니다.
그리고 여기에 하부디렉토리 두개를 만듭니다. "/GWT/features", "/GWT/plugins"

"/GWT"에 http://dl.google.com/eclipse/plugin/3.4/site.xml 를 다운받아서 옮겨놓습니다.
"/GWT/site.xml"이 생기겠죠.

다음..
"/GWT/features"에 아래 파일들을 다운받습니다.
"/GWT/plugins"에는 다음과 같은 파일들을 다운받습니다.


이제 다 되었네요.
이클립스의 Software Updates에 들어가서 Available Software 탭의 Add Site를 통해서 업데이트를 진행하면 됩니다.


Posted by 1010
98..Etc/GWT2009. 9. 27. 16:23
반응형

GWT 1.6이 나오면서 프로젝트 구조와 embeded Java Servlet (Jetty) server가 달라졌다.

게다가 Google에서 GWT를 위한 플러그인을 제공하므로 Cypal Studio를 사용할 필요가 없어졌으므로

Google 플러그인을 활용한 방법으로 수정한다.

참고: http://paulgrenyer.blogspot.com/2009/04/setting-up-gwt-ext-for-gwt-16-with.html


GWT - Google Web Toolkit(http://code.google.com/webtoolkit/)
  • 복잡한 AJAX 애플리케이션 개발을 손쉽게 해주는 프레임워크이다.
  • JAVA 코드로 작성하고 GWT 컴파일러가 자바코드를 자바스크립트로 변환한다. 모든 자바코드를 변환할 수 있는 것은 아니고, java.util, java.io 패키지의 기능들만 사용할 수 있다.
  • 구동되는 환경은 hosted mode와 web mode가 있다.

    • hosted mode: 컴파일 과정 없이 작성한 코드를 테스트하고 디버깅 할 수 있다. JVM환경의 GWT 브라우저에서 구동된다.
    • web mode: 컴파일러가 자바스크립트와 HTML파일을 생성하고, 이것을 웹브라우저로 구동한다.

GWT-Ext - GWT-Ext Widget Library(http://gwt-ext.com)
  • 강력하고 화려한 위젯 라이브러리. GWT와 자바스크립트 라이브러리 EXT(http://extjs.com/)를 활용하였다. http://extjs.com/에서 소개되는 Ext-GWT와는 다르다.

GWT-Ext with Eclipse

참고: http://code.google.com/eclipse/docs/getting_started.html

  • Eclipse plugin 설치
    Europa(3.3): http://dl.google.com/eclipse/plugin/3.3Ganymede(3.4): http://dl.google.com/eclipse/plugin/3.4
  • 이클립스 메뉴에서 File -> New -> Web Application Project 선택
  • 프로젝트와 패키지 이름을 넣고, Use Google App Engine 체크박스를 해제한다.
  • Run As -> Run Configurations에서 Automatically Select Unused Port의 체크박스를 체크한다.
  • 여기까지는 일반적인 GWT 애플리케이션의 실행 방법이다.
  • 다음 라이브러리를 다운로드 한다.

    • GWT-Ext(http://gwt-ext.com/download/)
      압축을 풀어 gwtext.jar파일을 프로젝트의 war\WEB-INF\lib 디렉토리에 넣는다.
    • war 디렉토리 아래에 js 디렉토리를 만든다.
    • Ext(http://gwt-ext.com/download/) 여기 링크에서 화면 아래쪽의 Ext 2.0.2 here의 here를 클릭해서 다운받는다.
      압축을 풀어 js 디렉토리에 넣는다.(디렉토리 2개 파일 4개만 하면 된다. (adapter/, resources/, ext-all.js, ext-all-debug.js, ext-core.js, ext-core-debug.js))
      (디렉토리가 이런 구조가 되도록 주의 js/ext-2.0.2/resources/...)
  • 프로젝트에 gwtext.jar를 추가한다.
    프로젝트를 우클릭한 후,
    Properties -> Java Build Path -> Libraries에서 Add JARs를 클릭한 다음 방금 넣었던 gwtext.jar를 선택한다.
  • oo(프로젝트 이름).gwt.xml 파일에 아래 굵은글씨 부분을 추가한다.
    <inherits name='com.google.gwt.user.User'/>
    <inherits name='com.gwtext.GwtExt' /> ...
    <entry-point class='com.megadeth.client.MegaDeth'/>
    <stylesheet src="../js/ext-2.0.2/resources/css/ext-all.css" />
    <script src="../js/ext-2.0.2/adapter/ext/ext-base.js" />
    <script src="../js/ext-2.0.2/ext-all.js" />
  • oo.client 패키지의 모듈 파일의 일부를 아래와 같이 수정한다.
    public void onModuleLoad(){
      Panel mainPanel = new Panel();
      mainPanel.setTitle("Hello World!");
      mainPanel.setHeight(300);
      mainPanel.setWidth(500);  
      RootPanel.get().add(mainPanel);
    }

  • war 디렉토리 아래의 html파일의 아래 부분을 삭제한다.
    <h1>Web Application Starter Project</h1>
    <table align="center">
      <tr>
        <td colspan="2" style="font-weight:bold;">Please enter your name:</td>
      </tr>
      <tr>
        <td id="nameFieldContainer"></td>
        <td id="sendButtonContainer"></td>
      </tr>
    </table>

  • 플러그인이 제공하는 Run As Web Application을 실행해 보면 작동하는 화면이 보인다.
  • 리모트 서비스를 만들어 본다. oo.client 패키지의 모듈 파일을 아래와 같이 수정한다.
       private Label label = new Label("Today is: ");
       private final GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
        public void onModuleLoad() {
            Button button = new Button("Get Date");
            Panel panel = new Panel();      
            button.addListener(new ButtonListenerAdapter(){
              public void onClick(Button button, EventObject e) {
                    greetingService.getDate(new NumberCallback());
                }
            });     
            panel.add(label);
            panel.add(button);
            RootPanel.get().add(panel);
        }
        public class NumberCallback implements AsyncCallback {
            public void onFailure(Throwable error) {
                MessageBox.alert("Getting date failed");
            }
            public void onSuccess(Object resp) {
                label.setText("Today is: " + resp.toString());
            }
        }

  • GreetingService에 다음 코드를 추가한다.
    String getDate();
  • GreetingServiceAsync에 다음 코드를 추가한다.
    void getDate(AsyncCallback<String> numberCallback);
  • GreetingServiceImpl에 다음 코드를 추가한다.
    public String getDate() {
         Date date = new Date();
         date.setTime(System.currentTimeMillis());
         SimpleDateFormat sDate = new SimpleDateFormat("MM월 dd일 HH시 mm분 ss초");
         return sDate.format(date);
     }
  • Cypal studio는 OO.gwt.xml, web.xml 파일을 수정하고, RemoteService와 Async파일의 메소드를 자동으로 맞춰주는 기능이 있다.
    그 외에는 Google 플러그인과 큰 기능차이가 없다.

이 글은 스프링노트에서 작성되었습니다.


출처 : http://uratang.egloos.com/2136671

Posted by 1010
56. Eclipse Etc.../Eclipse2009. 9. 25. 20:42
반응형
구글에서 eclipse 3.5 버전용 플러그인을 오픈하였다.
Google App Engine Java SDK 1.2.2와 Google Toolkit SDK 1.7.0을 포함하고 있다.


Posted by 1010
01.JAVA/Java2009. 9. 25. 20:40
반응형
이전에도 Eclipse Plugin을 Eclipse에서 설치해서 사용하는 것에 대해서 설명한 적이 있다.
이이 Eclipse에 익숙한 개발자라면,

구글에서 제공하는 아래와 간은 정보를 이용해서 원하는 버전에 적합한 Plug-in을 설치할 수 있을 것이다.

  • The Google Plugin for Eclipse, for Eclipse 3.3 (Europa):
    http://dl.google.com/eclipse/plugin/3.3
  • The Google Plugin for Eclipse, for Eclipse 3.4 (Ganymede):
    http://dl.google.com/eclipse/plugin/3.4
  • The Google Plugin for Eclipse, for Eclipse 3.5 (Galileo):
    http://dl.google.com/eclipse/plugin/3.5

구글의 Plug-in은 위와 같이 Eclipse의 세가지 버전(3.3, 3.4, 3.5)을 지원한다.
이중 3.5버전인 Galileo는 최근에 구글에서 Plug-in을 제공하기 시작했다. (얼마전까지는은 Eclipse 3.5버전에서는 사용하지 못했다는 말이다.)
 
어떻게 설치하고, 환경을 만드는지는 "Google App Engine Java SDK 1.2.1 Released" 의 글을 참조하면 된다. (처음 Eclipse를 사용하는  사람은 "Google App Engine SDK 설치 및 실행"를 참조)

Eclipse 3.5인 Galileo는 이전 버전들과 Plug-in 설치 방식이 약간 달라졌다.
이전 3.4 버전에서 제공 하던 방식은 플러그인을 찾는 방식이 편하지 많은 않았다. 왜냐하면, 백그라운드에서 사용자가 입력한 플러그인 이름을 실시간으로 키 입력시마다 추천해 주는 방식을 제공했는데, 네트워크에서 대기하는 시간에 대한 부담을 사용자가 가져야 했기 때문이다. 3.5 버전에서는 이러한 것들이 개선되어 졌다.

아래는 Eclipse 3.5에 GAE 플러그인을 설치한 것들을 캡쳐한 화면이다.

Eclipse 3.5의 Help > Install New Software... 를 클릭하면 아래 화면이 나타난다.


위 화면에서 상단 오른쪽에 있는 "Add..." 버튼을 클릭하면 창이 나타나면 아래와 같이 "Name"과 "Location"을 입력하고 "OK"버튼을 누른다. (Name은 사용자가 원하는 이름을 넣으면 된다.)


입력한 주소(Location) 정보가 정확하면, 아래과 같이 설치 가능한 플러그인들 목록이 표시된다.
모두 설치를 할것이므로 아래처럼 모두 체크해서 선택하면 된다. 그리고 "Next"버튼을 클릭한다.


위에서 "Next" 버튼을 클릭하면, 아래와 같이 상세 정보들이 나타난다. 다시 "Next"버튼을 클릭한다.

설치할 플러그인들에 대한 Licese 정책에 동의 할 것인지를 묻는 창인데, 당연히 동의해야 한다.
만약 동의하지 않는다면, 설치가 안될테니까... ^^;;;

위에서 동의하고 "Finish"버트을 누루면, 아래와 같이 설치가 진행된다.



출처 : http://happyzoo.tistory.com/169
Posted by 1010
01.JAVA/Java2009. 9. 25. 20:35
반응형
Java plug in 중 chart 를 쉽고 빠르게  만들 수 있게 해주는 JFree Chart Plugin을 소개한다.



다음과 같이 원형과 막대형의 그래프도 만들 수 있고 그외 만들수 있는 그래프의 숫자는 아주 많다. 지원되는 많은 차트를 확인 하려면
http://www.jfree.org/jfreechart/jfreechart-1.0.13-demo.jnlp

Library Download:

 http://www.jfree.org/ -->Download -->SourceForge Download page Click --> 하단의 jfreechart-1.0.13-javadocs.zip와 jfreechart-1.0.13.zip 받기


다음을 실행 시켜서 확인해 보면 된다.


작업순서

일단 차트를 만드는 기본적인 컨셉은 데이터가 있어야 차트로 변환할 수 있다는 점이다. 데이터가 들어가 있지 않으면 어떤것도 차트로 표현 할 수 없는 것은 당연한 일이다.


기본적인 Class의 구조는 다음과 같다.(API를 확인 하면서 보면 된다.)

가장 큰 밑바탕의 역할을 하는 JFreeChart Class가 존재 한다. JFreeChart class의 인스턴스를 생성하려면 Plot이라는 Class가 필요하다.
Plot은 정확하게 어떤 모양을 구현할지 선택하는 클래스 이다.(원형, 막대형, 꺽은선형...)
Plot은 모든 그래프 모형의 상위에 존재 하며 하위의 클래스들은 Plot을 상속하고 있다.
예를 들어 PiePlot 이라는 클래스는 원형 모델을 지원하며 PiePlot class로 구현한 그래프트는 맨 첫번째 그림의 왼쪽 모형이 되겠다.
PiePlot이라는 class는 또 다양한 형태의 class에 부모가 되며 하위 클래스 들은 3D형태의 클래스 부터 다양한 모양의 클래스가 존재 하며 예를 들면 PiePlot3D class가 원형이면서 3D형태로 구현된다.



                                                               Plot
                                                                ↑
                                                            PiePlot
                                                                ↑
                                                            PiePlot3D

이런 형태가 된다.

이 Pie class에 데이터를 넣어 줘야 하는데 데이터를 저장하고 넣게 해주는 것은 PieDataset 이라는 interface가 존재 하고 이것을 구현하고 있는 다양한 class가 있는데 일반적으로 DefaultPieDataset class를 사용한다.

작업순서
               
                           
1) Library파일 추가

struts 2 에서 제공하는 다음과 같은 library를 추가한다.

struts2-jfreechart-plugin-2.0.14.jar
commons-digester-1.8.jar

위에서 다운받은 JFreeChart library를 추가 한다.

jcommon-1.0.16.jar
jfreechart-1.0.13.jar

2) action mapping 설정

extends="struts-default,jfreechart-default"

<action name="register"
           class="chart.actions.RegisterAction"
           method="execute">
          <result name="success" type="chart">
              <param name="width">500</param>
              <param name="height">400</param>
          </result>   
 </action>

꼭 extends를 다음과 같이 설정해 주어야 하고 result type을 chart로 해주면 jFreeChart가 실행되어 차트가 보여지게 된다.
그러나 보통 웹페이지에서는 웹페이지에 전체 다 차트가 나오는 경우는 없으며 html 사이에 추가 되길 원한다.

그렇기 때문에 보통은 type="chart" 로 선언하지 않고 BusinussLogic상에서 차트를 이미지로 만들어 주어 저장한후 jsp페이지에서 링크를 걸어 주는 형식을 취하고 있다.

<action name="result"
           class="chart.actions.ResultAction"
           method="execute">
          <result name="success">/chart/result.jsp</result>    
</action>

다음과 같이 평범하게 결과 페이지로 이동시킨다.


3) Business Logic을 수행하고 JFreeChart class로 chart를 생성한다.

Logic을 수행할 class - 투표로직!
----------------------------------------------------------------------------------------------------------
package chart.actions;

import org.jfree.chart.JFreeChart;

import com.opensymphony.xwork2.ActionSupport;
import chart.model.dao.ChartDAO;
import chart.model.dto.ChartDTO;
import chart.poll.PollChart;

public class RegisterAction extends ActionSupport {

 public static final long serialVersionUID = 1L;
 
 /*property fields*/
 private int answer;
 private ChartDTO dto;
 private JFreeChart chart;
 
 public JFreeChart getChart(){          //action mapping 의 result로 데이터를 보내야 하기 때문에 JFreeChart로 리턴한다.
  return chart;
 }

 
 @Override
 public String execute()throws Exception {
  dto = new ChartDTO();
  calc();                                        //jsp페이지의 radio 버튼으로 들어오는 오는 값을 세팅 시켜준다.
  ChartDAO dao = new ChartDAO();
  dao.update(dto);                          //DB에 데이터 업데이트
  //list query
  dto = dao.list(dto);                        //DB에 있는 데이터 가져옴
  //chart 정보 가져옴
  chart = PollChart.getPie3dChart(dto);  // 실질적 차트를 생성하는 부분
  return SUCCESS;
 }

 public void calc(){
  switch(answer){
   case 1 : dto.setAnswer1(1);break;
   case 2 : dto.setAnswer2(1);break;
   case 3 : dto.setAnswer3(1);break;
   case 4 : dto.setAnswer4(1);
  }
  dto.setTot(1);
 }
 
 public int getAnswer() {
  return answer;
 }

 public void setAnswer(int answer) {
  this.answer = answer;
 }


}
----------------------------------------------------------------------------------------------------------

PollChart class

----------------------------------------------------------------------------------------------------------
package chart.poll;

import org.jfree.chart.JFreeChart;
//import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.category.DefaultCategoryDataset;
//import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.entity.StandardEntityCollection;
import chart.model.dto.ChartDTO;
import java.io.File;

import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.axis.CategoryAxis3D;
import org.jfree.chart.axis.NumberAxis3D;
import org.jfree.chart.renderer.category.BarRenderer3D;

public class PollChart {
 
 
 
 /*pie 3D chart*/
 public static JFreeChart getPie3dChart(ChartDTO dto)throws Exception {
 
  String path="D://JAVA/java document/web 2/workspace/struts2/WebContent/chart_images/pie3d.png";  //이미지 파일을 저장할 경로 설정
  JFreeChart chart = null;
// 차트에 삽입할 데이터를 집어 넣는다.
  DefaultPieDataset dataset = new DefaultPieDataset();
  dataset.setValue("1번("+dto.getAnswer1()+"명)", dto.getAnswer1());
  dataset.setValue("2번("+dto.getAnswer2()+"명)", dto.getAnswer2());
  dataset.setValue("3번("+dto.getAnswer3()+"명)", dto.getAnswer3());
  dataset.setValue("4번("+dto.getAnswer4()+"명)", dto.getAnswer4());
  PiePlot3D plot = new PiePlot3D(dataset);         //값을 넣어서 3DChart를 생성한다.
  chart = new JFreeChart(
     "설문조사 통계",
     JFreeChart.DEFAULT_TITLE_FONT,
     plot,
     true
          ); //true는 범례설정
  plot.setOutlineVisible(false);  //사각 테두리 사용하지 않음
  chart.setBackgroundPaint(java.awt.Color.WHITE); //background color설정
  new PollChart().createImage(path, chart);   //png파일로 저장해서 저장한 폴더위치에 저장하자
 
  return chart;
 }
 
 /*bar 3D chart*/
 public static JFreeChart getBar3dChart(ChartDTO dto)throws Exception {
  String path="D://JAVA/java document/web 2/workspace/struts2/WebContent/chart_images/bar3d.png";
  JFreeChart chart = null;
  DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  dataset.setValue(dto.getAnswer1(), "1번", "1번("+dto.getAnswer1()+"명)");
  dataset.setValue(dto.getAnswer2(), "2번", "2번("+dto.getAnswer2()+"명)");
  dataset.setValue(dto.getAnswer3(), "3번", "3번("+dto.getAnswer3()+"명)");
  dataset.setValue(dto.getAnswer4(), "4번", "4번("+dto.getAnswer4()+"명)");
  /*
  chart = ChartFactory.createBarChart3D(
    "설문조사 통계",
    "선택항목",
    "인원수",
    dataset,
    PlotOrientation.VERTICAL,
    true, false, false);
  */
  CategoryAxis3D axis = new CategoryAxis3D("선택항목");
  NumberAxis3D numAxis = new NumberAxis3D("인원수");
  BarRenderer3D renderer = new BarRenderer3D(35.0,10.0);
  renderer.setItemMargin(0.10);
  renderer.setShadowVisible(true);
  CategoryPlot plot = new CategoryPlot(dataset,axis,numAxis, renderer);
  chart = new JFreeChart(
    "설문조사 통계",
    JFreeChart.DEFAULT_TITLE_FONT,
    plot,
    false
  );
  chart.setBackgroundPaint(java.awt.Color.WHITE);
  new PollChart().createImage(path, chart);
  return chart;
 }
 
 /*image 생성부분*/
 public void createImage(String file, JFreeChart chart)throws Exception {
  ChartRenderingInfo info = new ChartRenderingInfo(
                      new StandardEntityCollection());
  ChartUtilities.saveChartAsPNG(new File(file), chart, 380, 300, info);
 }

}

----------------------------------------------------------------------------------------------------------
사진 파일을 저장할 위치를 프로젝트가 접근 가능한 폴더에 넣어야 jsp페이지에서 링크 걸때 정확하게 걸린다.


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

Posted by 1010
02.Oracle/DataBase2009. 9. 24. 19:48
반응형
alter session set global_names=true;


dblink tl seq 를 자동증가 할때  ***.nextval

ORA-04054: 데이터베이스 링크 'HSCPROD.NEXTVAL'가 존재하지 않습니다
                    
SELECT AAA_SEQ@hscprod.NEXTVAL
  FROM DUAL; (X)

SELECT AAA_SEQ.NEXTVAL@hscprod
  FROM DUAL (O)



SEQUENCE

 CREATE TABLE T1(ID NUMBER(4) CONSTRAINT T1_PK PRIMARY KEY, DATA VARCHAR2(30));


PK에 대해 SEQUENCE를 줄수 있다. 입력시에 아래처럼. 테이블에 시퀀스 하나씩!

 SQL> INSERT INTO T1 VALUES(T1_S.NEXTVAL, 'AA');

1 개의 행이 만들어졌습니다.

 SQL> CREATE SEQUENCE T1_S;

시퀀스가 생성되었습니다.

SQL> SELECT * FROM T1;

        ID DATA
---------- ------------------------------
         1 AA
         2 BB


 세션마다 CURRVAL은 다르지만, NEXTVAL은 같다. 세션에서 NEXTVAL을 사용하게 되면 하나씩 올라가게 된다..

 GAP이 생기면 시퀀스를 쓰지 말아야 하는거죠. 시퀀스대신 SELECT MAX(ID)+1 처럼 해야 된다. <- LOCK이 걸릴수 있기때문에 쓰지 마라.

 ISQL에서는 트랜젝션이 있으니까 상관없긴 하다.


  1  CREATE SEQUENCE DEPT_S
  2  INCREMENT BY 10
  3* START WITH 10
SQL> /

시퀀스가 생성되었습니다.

SQL> SELECT DEPT_S.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        10

SQL> SELECT DEPT_S.NEXTVAL FROM DUAL;

   NEXTVAL
----------
        20


3,5,2,4,6,2,4,6 으로 증가하게 하려면?

 SQL>
  1  CREATE SEQUENCE TS
  2  INCREMENT BY 2
  3  START WITH 3
  4  MAXVALUE 6
  5  MINVALUE 2
  6* CYCLE NOCACHE

시퀀스가 생성되었습니다.

SQL> SELECT TS.NEXTVAL FROM EMP;

   NEXTVAL
----------
         3
         5
         2
         4
         6
         2
         4
         6
         2
         4
         6

   NEXTVAL
----------
         2
         4
         6

14 개의 행이 선택되었습니다.

Posted by 1010
반응형
Spring 3.0 가 곧 출시(4월경) 될 것이라는 이야기 속에, Spring 2.5 버전에 대한 이야기를 해야겠다.
Spring 2.1로 줄곧 개발하고 있었는데, 항상 느끼던게 지나치도록 복잡한 설정이었다. 진입장벽이 높다고 했던가? 아마도 SpringFramework의 초기 진입시 가장 어려운 점은 무엇보다도 설정 이 아닌가 생각되었다.
Spring 2.1에서의 복잡한 설정(물론 몇 번 해보면 익숙해지면 금방 copy & paste 가 가능하다.)은 Spring 2.5에서 어노테이션이라는 강력한 기능으로 중앙집중적인 설정에서 지방분권적인 설정을 가능하게 만들었다.
(xml에 의한 설정이 아닌 개별 java 파일로 설정이 옮겨감)


Hello World를 찍어보라구!!

공실장 : 어이 김과장, 내가 이번에 Spring을 공부 해보고 싶은데 어떤 책을 봐야하지? Spring in Action은 한번 죽 훓어 봤는데, 다른 좀 쉬운 책 그런거 없나?
김과장 : ... Hello World는 찍어보셨나요?
공실장 : 허허허, 나보고 Hello World나 찍어보라는건가? 내가 그런걸... 허허허

(며칠 뒤)
김과장 : 공실장님, Spring 은 어떻게 잘 되고 계세요?
공실장 : 나 Spring은 포기 했네, 설정이 어려워서 그런지 Hello World가 도무지 실행이 안되던데...
어이없이 들릴지 몰라도, 처음 Spring을 접하는 사람이라면 Hello World 조차도 왠지 멀게만 느껴질 것이다. 위의 예처럼 설정만 누군가 해준다면, 자바 소스는 짤 수 있겠는데... 라는 말이 나오겠지만, 무엇보다도 설정을 할 줄 아는게 중요하겠다.

하지만, 개발기간이 초초 단기라면, 한달 이내에 분석부터 구현까지 모두 끝내야하는 것이라면 Step by Step으로 설정부터 배워나가서 Spring을 구성하기가 어려울 것이다. 아마, Spring은 배제될 것이 뻔하다. 단순히 jsp 페이지만으로 구성해서 빨리 마치고자 노력할 것이다. 온통 Copy & Paste 범벅이 될 게 자명하다. 누군가 Copy & Paste도 실력이라는 진리를 이야기 해 준적이 있지만, 생각없는 Copy & Paste는 내 프로그램의 사명이라고 생각되지 않는다면 다른 길을 찾아야 하지 않을까?


Utility를 만들어서 사용하는건 어때?

몇 번의 Copy & Paste 로 만든 사이트가 지긋지긋하다면, 혹은 비즈니스 로직에만 집중하라는 만고의 진리를 느껴보고 싶다면, Utility를 만들어 보는 것도 나쁜 생각은 아닌 것 같다. 초기 진입을 낮춰 주는 무언가가 있다면 난 정말 비즈니스 로직은 환상적으로 짤 수 있을거야라는 정말 Lazy 한 생각이라면 Utility로 간단히 해결하자.

PCube(회사 내 서브 프로젝트명으로 Spring 2.5 기반 설정 파일 자동화 Utility의 이름) 의 시작은 프로젝트 시간이 촉박한 개발자를 위해 시작한 사내 프로젝트이다. Spring을 이용하되, 설정을 쉽게 도와줌으로써 "시작" 할 수 있는 여건을 마련해 준다. 이제 한 컷 씩 따라하면서 "Spring을 누군가 설정만 해준다면..." 라는 Lazy한 개발자가 되보자.

 
위의 2개 파일을 일단 다운로드 받도록 한다.

각 파일의 설명은 아래와 같다.

 pcube-1.0.1.jar Generate 해주는 클래스 실행 파일 모음

 project.pcube Generate 해야 할 각족 설정이 담긴Seed 파일

project.pcube 에 설정된 값들을 가지고, pcube-1.0.1.jar 파일로 설정 파일을 Generate 한다. 특별히, project.pcube 파일은 JSON 파일 형식으로 되어 있어서 실제로 열어보면 간단한 중첩 구조로 되어 있음을 알 수 있다.

샘플을 보면서 실제로 어떤 설정을 해야 하는지 살펴보자.
{
    project:
    {
        name:'Test Project generate by Utility(PCube)',
        directory:'C:/eclipse_spring/workspace/TestProject/WebContent',
        package:'com.company.project.package',
        author:'Hyoseok Kim',
        email:'toriworks@gmail.com',
        comment:'프로젝트의 설명을 넣어주세요.',
        schema:
        {
            kind:'MySql',
            version:'5.0',
            connects:
            [
                {id:'jdbc/JNDIName', url:'localhost', db:'testDB', uid:'root', pwd:'123456'}
            ],
            tables:
            [
                {
                    name:'User',
                    lang:'UTF8',
                    fields:
                    [
                        {fname:'user_id',type:'varchar(20)',jtype:'String',auto:'no',key:'yes',nil:'no',default:''},
                        {fname:'user_name',type:'varchar(20)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                        {fname:'auth_code',type:'int',jtype:'int',auto:'no',key:'no',nil:'yes',default:''},
                        {fname:'last_login',type:'datetime',jtype:'String',auto:'no',key:'no',nil:'no',default:'now()'},
                        {fname:'login_count',type:'int',jtype:'int',auto:'no',key:'no',nil:'no',default:'0'},
                        {fname:'email_address',type:'varchar(150)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                        {fname:'contact1',type:'varchar(50)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                        {fname:'contact2',type:'varchar(50)',jtype:'String',auto:'no',key:'no',nil:'yes',default:''},           
                        {fname:'title_code',type:'varchar(20)',jtype:'String',auto:'no',key:'no',nil:'yes',default:''},
                        {fname:'title',type:'varchar(20)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                    ]
                },
                {
                    name:'Manager',
                    lang:'UTF8',
                    fields:
                    [
                        {fname:'manager_id',type:'varchar(20)',jtype:'String',auto:'no',key:'yes',nil:'no',default:''},
                        {fname:'manager_name',type:'varchar(20)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                        {fname:'last_login',type:'datetime',jtype:'String',auto:'no',key:'no',nil:'no',default:'now()'},
                        {fname:'login_count',type:'int',jtype:'int',auto:'no',key:'no',nil:'no',default:'0'},
                        {fname:'email_address',type:'varchar(150)',jtype:'String',auto:'no',key:'no',nil:'no',default:''},
                    ]
                }               
            ]
        }
    }
}

데이터베이스에 대한 설계가 모두 끝난 다음에 PCube를 이용하는게 가장 best practice라고 생각이 되는데, 왜냐하면 위의 Seed 파일의 내용을 보면 데이터베이스의 엔티티 정보가 그대로 들어가 있기 때문이다. 이 정보를 바탕으로 iBatis 쿼리를 만들어 내도록 되어 있기 때문임을 이해해 줬으면 한다.

Seed 파일의 첫 문장은 project: 로 시작하고, 기본적인 프로젝트 정보를 담는 부분과 데이터베이스 엔티티 부분으로 크게 나눌 수가 있다. 기본적인 프로젝트 정보를 담는 부분은 나중에 Java 소스의 주석부분으로 옮겨지게 된다. 중요한 점은 package: 인데, package: 부분에 쓰인 대로 Java 소스에 Package 정보가 부여된다.


패키지명이 Seed 파일에 기술된 대로(com.company.project.package) 구성되었음을 확인 해 볼 수 있다.

옆에 보여지는 이미지가 자동생성 된 이후에 구성된 Java package 인데, 실제로 controller, dao, domain, service, test, utils, validation 총 7가지의 파일을 자동적으로 생성해 낸다.





domain package 의 파일을 살펴보면 아래와 같다.

대강 살펴보면, Seed 파일에서 작성한 내용이 그대로 옮겨졌다는 걸 알 수가 있다.

domain 클래스만 살펴보았지만, 기타 다른 package를 보면 규칙에 따라서 파일이 생성됨을 알 수가 있다.



















본격적으로 실습을 해보자!!!



File을 누르고, Dynamic Web Project 를 선택하자.


Project 명으로 TestProject 라고 입력하고, 하단의 Finish 버튼을 누른다.(Project contents, Target Runtime, Dynamic Web Module version, Configuration 등의 설정은 필요에 따라 설정하자.)



lib 폴더를 펼친 후에, 아까 다운로드 받아놓은 pcube-1.0.1.jar 파일을 lib 폴더에 복사한다.

그리고, 2개의 폴더를 새로 만든다.
input 과 output 폴더를 만든다.

위 과정까지 마친 후의 폴더 모습은 다음과 같다.



input 폴더와 output 폴더가 추가되었고, WEB-INF 밑의 lib 폴더에 pcube-1.0.1.jar 파일이 추가되었음을 알 수가 있다.

그리고, input 폴더에 위에서 받아 놓은 Seed 파일인 project.pcube 파일을 복사 해 둔다.
input 폴더에 project.pcube 파일을 읽어 들여서, output 폴더로 파일들이 생성될 예정이다.








이제 파일들을 Generate 하기 위해서, 클래스 파일 하나를 만들어 보자.


클래스명에 GenerateFilesByAutomation 이라 입력하고, main 함수를 만들 예정이므로 public static void main(String[] args) 에 체크를 했다. Finish 버튼을 누르면, 파일 작성을 하기 위해 파일이 열린다.

GenerateFilesByAutomation.java 에 이렇게 내용을 기록하자.

import java.io.IOException;
import org.json.JSONException;

import com.cs.pcube.repository.start.GenerateFiles;

/**
 * @author Hyoseok Kim(
toriworks@gmail.com)
 *
 */

public class GenerateFilesByAutomation {

 /**
  * @param args
  * @throws JSONException
  * @throws IOException
  */
 public static void main(String[] args) throws IOException, JSONException {
 
  // 파일을 자동으로 만들어보자.
  GenerateFiles generator = new GenerateFiles();  
  generator.generateAllFiles(0); 

 
 }
}

수기로 작성해야 하는 부분은 위에처럼 파란색 굵은 글씨로 표시를 했다. 이렇게 작성을 했으면, Java 파일을 실행 시켜보자.

Shift + Alt + X 누른 후에, J 버튼을 눌러서 Java application을 실행 시켜보자.

 
실행 후에, output 폴더를 새로 고침을 눌러서 갱신을 해보자.(처음에는 생성된게 잘 보이지 않는다. 꼭 새로 고침을 눌러보자.)

새로 고침을 누르면, 크게 2부분으로 파일들이 나눠져 있음을 알 수가 있다.
첫째는 .java 파일들이고, 둘째는 Tomcat 쪽 파일과 .xml 파일들이다. 생성되어진 모든 파일을 한번 살펴보자.




생성된 디렉토리와 파일들을 Full로 펼쳐 보이면 이 정도 구조를 가지는 파일들이 생성되었음을 알수 있다.

com 밑의 폴더들은 기본적인 .java 파일과 iBATIS 용 .xml 파일들이 보이고, etc 밑의 폴더에서는 tomcat 용 설정파일과 WebContent에 위치해야 할 .jsp 파일과 .xml 파일들이 있음을 볼 수가 있다.

또한 SiteMesh를 이용하고 있기 때문에 이에 따르는 decorator.xml 이 폴더 구조에서 보여지고 있다.

정리하자면, Spring 2.5 + iBATIS + SiteMesh 를 사용하는 프로젝트를 자동생성해 준다.

이후 작업은 단순히 폴더를 복사해서, 폴더 구조에 맞게끔 복사를 해주면 그만이다. 예를 들어서, WebContent 폴더는 프로젝트의 WebContent 밑에 통째로 복사해 주면 된다.


그렇다면, 생성된 Spring 설정 파일은?

일단 Spring 2.5에서 사용할 설정 파일에 대해 살펴보자. 3개의 파일을 생성해 주고 있는데, 프로젝트명-data.xml, 프로젝트명-service.xml, 프로젝트명-servlet.xml 이다. 각 각의 파일에 대해 살펴보자.

<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 파일은 XML Schema 기반으로 Spring 설정을 구성합니다. -->

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <!-- dataSource 설정 설정 -->
  <!-- (주의) dataSource가 여러개 일 경우 bean id 값을 조정하셔야 합니다. -->
  <!-- 1번째 dataSource 설정 -->

  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
   p:jndiName="java:comp/env/jdbc/JNDIName" />

  <!-- 트랜잭션 부분 코드를 삽입한다. -->
  <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
   <property name="dataSource" ref="dataSource" />
  </bean>

  <tx:annotation-driven transaction-manager="txManager"/>

  <!-- SqlMap와 dataSource를 연결해준다. -->
  <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
   p:configLocation="/WEB-INF/resources/ibatis/sql-map-config.xml"
   p:dataSource-ref="dataSource" />

  <!-- 이 곳에 하위로 사용자와 관리자용 Spring 설정 파일 설정 부분 import 태그를 이용해 입력합니다.
  또는 이 예시에 주어진 대로 파일을 생성 하고 아래 내용을 복사하세요.
  예시
  <import resource="resources/operation/sample-manager-data.xml" />
  <import resource="resources/operation/sample-user-data.xml" /> -->

  <!-- User DAO 선언 -->
  <bean id="userDao" class="com.company.project.package.dao.ibatis.UserDaoImpl">
   <property name="sqlMapClient" ref="sqlMapClient" />
  </bean>

  <!-- Manager DAO 선언 -->
  <bean id="managerDao" class="com.company.project.package.dao.ibatis.ManagerDaoImpl">
   <property name="sqlMapClient" ref="sqlMapClient" />
  </bean>

</beans>



수작업으로 할일은 거의 없다. 자동으로 파일을 만들었으니, 그냥 설정이 이렇게 구성되는구나 라고 알고 있으면 되겠다. 하지만, 설정을 보면서 Spring 책을 꼭 찾아서 봄 직하다.

다음은 프로젝트명-service.xml을 살펴보자. 크게 어렵지 않다.

<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 파일은 XML Schema 기반으로 Spring 설정을 구성합니다. -->

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <!-- 빈 스캐닝 부분을 추가한다. -->
  <context:annotation-config />
  <context:component-scan base-package="com.company.project.package" />

  <!-- 이 곳에 하위로 사용자와 관리자용 Spring 설정 파일 설정 부분 import 태그를 이용해 입력합니다. -->
  <!-- 예시 -->
  <!-- <import resource="resources/operation/sample-manager-service.xml" /> -->
  <!-- <import resource="resources/operation/sample-user-service.xml" /> -->

</beans>

service 는 더 간단하다. 왜냐하면, 빈 스캐닝을 통해서 굳이 .xml 파일에 설정을 넣을 필요가 없어졌기 때문이다. 그렇다면, Service 레이어를 담당하는 .java 파일을 함께 살펴보자.(좀 길게 되어 있으나, 한번 쯤은 꼭 봐야 하기에 전체 소스를 옮긴다.)

/**
 * Test Project generate by Utility(PCube)
 *  This file is generate by PCUBE system automatically.
 *  Generated by Sun Feb 01 18:52:46 KST 2009
 */
package com.company.project.package.service.impl;

// << Please import packages >>
// TODO : import package name if you want to add

import org.springframework.stereotype.Service;

import org.springframework.dao.DataAccessException;
import com.company.project.package.dao.IManagerDao;
import com.company.project.package.domain.Manager;
import com.company.project.package.service.IManagerService;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

// << Please insert import packages (for example, import java.util.List; ) >>


/**
 * @author Hyoseok Kim (
toriworks@gmail.com)
 *
 */

@Service
public class ManagerServiceImpl implements IManagerService {

 /**
  * Constructor
  */

 public ManagerServiceImpl() {}

 // Setter injection 대신에 @Autowired와 @Qualifier annotation 사용으로 injection 수행
 @Autowired
 private IManagerDao managerDao = null;

 public void setManagerDao(IManagerDao managerDao) {
  this.managerDao = managerDao;
 }

 /**
 * C of CRUD - 새로운 정보를 데이터베이스에 입력하기 위해서 DAO 객체에 역할을 위임합니다.
 */

 @Override
 public void create(Manager manager) throws DataAccessException {
  managerDao.create(manager);
 }

 /**
 * U of CRUD - 기존에 등록된 정보를 수정하기 위해서 DAO 객체에 역할을 위임합니다.
 */
 @Override
 public void update(Manager manager) throws DataAccessException {
  managerDao.update(manager);
 }

 /**
 * D of CRUD - 기존에 등록된 정보를 삭제하기 위해서 DAO 객체에 역할을 위임합니다.
 */
 @Override
 public void delete(Object parameter) throws DataAccessException {
  managerDao.delete(parameter);
 }

 /**
 * R of CRUD - DAO 객체에 위임하여 요청받은 목록을 반환합니다.
 */

 @SuppressWarnings("unchecked")
 @Override
 public List<Manager> lists(Object parameter) throws DataAccessException {
  return managerDao.lists(parameter);
 }

 /**
 * DAO 객체에 위임하여 목록 개수를 반환합니다.
 */
 @Override
 public Integer listsCount(Object parameter) throws DataAccessException {
  return (Integer) managerDao.listsCount(parameter);
 }

 /**
 * R of CRUD - DAO 객체에 위임하여 요청받은 자료의 상세정보를 반환합니다.
 */
 @Override
 public Manager detail(Object parameter) throws DataAccessException {
  return managerDao.detail(parameter);
 }

} // class end



CRUD 에 관한 메소드가 선언되어 있고, 특이점으로 파일 상단에 @Service 라고 어노테이션이 선언되어 있다. @Service 어노테이션 덕분에 빈 스캐닝을 통해 자동적으로 빈이 컨테이너에 올라갈 수 있다.

마지막으로 프로젝트명-servlet.xml 파일을 살펴보자.

<?xml version="1.0" encoding="UTF-8"?>
<!-- 이 파일은 XML Schema 기반으로 Spring 설정을 구성합니다. -->

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <!-- @RequestMapping 을 사용하기 위한 빈 설정 2개 추가한다. -->
  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

  <!-- 빈 스캐닝 부분을 추가한다. -->
  <context:annotation-config />
  <context:component-scan base-package="com.company.project.package" />

  <!-- 뷰 리졸버를 선언합니다. -->
  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
   p:prefix="/WEB-INF/jsp" p:suffix=".jsp">
  </bean>

  <!-- 에러 뷰 리졸버를 선언합니다. -->
  <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
   <property name="exceptionMappings">
    <props>
     <prop key="java.lang.Exception">errorPage</prop>
     <prop key="org.springframework.dao.DataAccessException">errorPage</prop>
    </props>
   </property>
  </bean>

  <!-- 업로드 리졸버를 선언합니다. -->
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="maxUploadSize" value="100000000" />
   <property name="defaultEncoding" value="utf-8" />
   <property name="uploadTempDir" ref="uploadDirResource" />
  </bean>

  <!-- 업로드 임시 공간을 선언합니다. -->
  <bean id="uploadDirResource" class="org.springframework.core.io.FileSystemResource">
   <constructor-arg>
    <value>C:/eclipse_spring/workspace/TestProject/WebContent/respository_temp/</value>
   </constructor-arg>
  </bean>

  <!-- 이 곳에 하위로 사용자와 관리자용 Spring 설정 파일 설정 부분 import 태그를 이용해 입력합니다. -->
  <!-- 예시 -->
  <!-- <import resource="resources/operation/sample-manager-servlet.xml" /> -->
  <!-- <import resource="resources/operation/sample-user-servlet.xml" /> -->

</beans>



@RequestMapping 을 사용하기 위해서 추가된 2개의 태그가 있다는 것만 기억하면 될 것 같다.
그렇다면, 실제로 Controller에서 @RequestMapping이 사용되는 걸 보자.

package com.company.project.package.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;


/**
 * @author Hyoseok Kim (
toriworks@gmail.com)
 *
 */

@Controller
public class IndexController {

 @RequestMapping("/index.html")
 public ModelAndView viewDefaultIndex() {

  ModelAndView mav = new ModelAndView();
  mav.setViewName("index");

  return mav;
 }
}



@RequestMapping 어노테이션의 사용법에 대해서는 차후 좋은 블로그를 찾아서 소개를 하던, 아니면 다뤄보도록 하겠다.


이제 결론을 내보자!!!

작은 귀찮음에서 시작한 거였지만, 그럭저럭 설정에 애 먹고 있는 사람들에게 요긴했으면 한다. 혹 SpringFramework 3.0에는 이런 기능도 함께 있으면 싶기도 하다. 부족하나마, 잘 따라해 주기만 한다면, 데이터베이스 엔티티가 많으면 많은 수록 프로젝트의 기간은 더 많이 단축할 수 있으리라 생각된다. 위의 예에서는 단순히 2개의 엔티티만을 대상으로 했지만, 그 수가 많으면 많을 수록 빛을 발하리라 기대해 본다.


출처 : http://toriworks.tistory.com/106

Posted by 1010
01.JAVA/Java2009. 9. 16. 09:48
반응형

Jdk 5.0 에서 새로 선보인 (Annotation) 어노테이션 이라는 겁니다.


자바 언어로 표현할수 없지만 프로그램 전체적으로 표현해야할 테이터를 기술하는 방법을 제공하죠.

다시말하면, 어노테이션을 사용하면 프로그램에서 컴파일러가 테스트하고 검증해야하는 부가 정보를 정해진

형식으로 설명하는 것이 가능하게 됩니다. 또한 설명 파일이나 새로운 클래스 정의를 생성하여 공통코드를

작성하는 부담을 줄이는 용도로도 활용할 수 있죠.


가장 자주 쓰이는 어노테이션은


@Override

 : 기반 클래스의 메소드를 오버라이드한 것을 표시한다. 메소드 이름을 잘못 표기하거나 시그니처를 잘못 지정할

경우 컴파일 에러 발생


@Deprecated

 : 해당 요소가 사용될 경우 컴파일러가 경고를 발생 시킨다.


@SuppressWarning

 : 부적절한 컴파일러의 경고를 제거하기 위해 사용된다.


음..어노테이션은 자바 고급기술에 속하는 편이어서 그냥 이런게 있구나 하고 넘어가셔도 무방합니다만

좀더 자세히 알고 싶으시면 관련서적을 보시거나 검색해보시는 편이 나으실 겁니다^^


출처 : http://ydeity.tistory.com/tag/@SuppressWarnings

Posted by 1010
반응형

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <SCRIPT LANGUAGE="JavaScript">
  <!--
 var sayHi = new Function("to","alert('hi'+to);");

 function test(imsi){
  sayHi(imsi);
 }
  //-->
  </SCRIPT>
 </HEAD>

 <BODY>
  <input type="button" value="123" onClick="test('바보');"/>
 

 </BODY>
</HTML>

Posted by 1010
05.JSP2009. 9. 14. 18:03
반응형

import java.util.Date;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMailBean {
//        private String host = "121.131.70.113";
        private String host = "127.0.0.1"; 
        private String to = null; 
        private String tname = null;
        private String from = null;
        private String fname = null;
        private String msgSubj = null;
        private String msgText = null;
        private Message msg = null;
       
        
        public SendMailBean(){  super();        }
       
        /**
         * 메일 설정
         * @param to 받는 사람 
         * @param tname 받는 사람 이름
         * @param from 보내는 사람
         * @param fname 보내는 사람 이름
         * @param msgSubj 메일 제목
         * @param msgText 메일 내용
         */
        public void setMail(String to, String tname, String from, String fname, String msgSubj, String msgText) {
                this.to = to;
                this.tname = tname;
                this.from = from;
                this.fname = fname;
                this.msgSubj = msgSubj;
                this.msgText = msgText;
               
                this.send();
        }
       
       
        public void send()  {
                try {
                        Properties props = new Properties();
                       
                        props.put("mail.smtp.host", host);
                         Session sess = Session.getInstance(props,null);
                         MimeMessage msg = new MimeMessage(sess);
                        
                        
                        // create a message
                        InternetAddress address = new InternetAddress(to, tname, "EUC-KR");
                        InternetAddress fadd = new InternetAddress(from, fname, "EUC-KR");
                       
                       
                        msg = new MimeMessage(sess);
                       
                        msg.setFrom(fadd);
                        msg.setRecipient(Message.RecipientType.TO, address);
                        msg.setSubject(msgSubj);
                        msg.setSentDate(new Date());
                        msg.setContent(msgText,"text/html;charset=euc-kr"); // HTML type
                        msg.setText(msgText); // 본문
       
                        Transport.send(msg);
                       
               
                } catch (Exception e) {
                        e.printStackTrace();
//                        return false;
                }  // end try
//                return true;
        }
}


Posted by 1010
반응형

출처 : http://okjsp.pe.kr/seq/138831

prototype.js를 보다가 유용한 기능이 있어서 글을 올립니다.

보통 자바스크립트로 아래와 같은 코드를 사용할 일이 종종있는데요.

//----------------------------------------

    var str = "히히";
    if (str == "하하" || str == "호호" || str == "후후" || str == "히히" ||  str == "헤헤") {
        alert("기존 방식!");
    }


//----------------------------------------

위의 코드를 아래처럼 줄일 수 있습니다.

//----------------------------------------

    var str = "히히";
    if (["하하", "호호", "후후", "히히", "헤헤"].include(str)) {
        alert("include 사용시!");
    }

//----------------------------------------


아래 함수를 공통.js 같은곳에 넣으셔서 사용하시면 됩니다.


<script>

    Array.prototype.include = function () {
        for (var index in this) {
            if (this[index] == arguments[0]) {
                return true;
            }
        }
        return false;
    }

</script>


예제코딩된 html 첨부합니다.

감사합니다.

Posted by 1010
98..Etc/ASP.NET2.02009. 9. 3. 20:58
반응형

ASP 내장 객체

   강좌 최초 작성일 : 1999년 x월 x일
   강좌 최종 수정일 : 2001년 7월 17일

   작성자 : Taeyo(김 태영)
   편집자 : Taeyo(김 태영)

   강좌 제목 : Request Object

Request Object

Request Object는 주로 사용자로부터 정보를 전달 받을때 사용되는 개체입니다우리는 ASP 라는 서버 사이드를 공부하는 것이기에 모든 관점은 서버쪽에서 바라보는 습관이 필요함다

Request 라는 말은 "요청하다" 이지만 이것은 서버측에서 요청한다는 의미입니다... 즉, 사용자가 서버로 보내오는 요청이나 데이터를 얻어내는 역할을 하는 것이 바로 이 Request 개체가 담당하는 역할이지요..

이 개체가 가지고 있는 주요기능은 다음 표와 같습니다만...아무래도 강좌에서 이 개체의 컬렉션등을 구체적으로  모두 알아보기에는 어려움이 있기에...우린 여기서 그 중 중요한 몇가지만 체크하려 합니다....  (더 깊숙한 내용은 책이나 MSDN을 참고해 주세요)

Collection (컬렉션)
ClientCertificate 사용자가 페이지나 리소스를 액세스할 때 서버로 전달한 클라이언트 증명서에 있는 모든 필드와 엔트리값(읽기 전용)
Cookies 사용자의 시스템에서 요청과 함께 전달된 모든 쿠키값
Form 폼 요청으로 전송된(POST 사용) 모든 HTML 컨트롤 요소 값
QueryString 사용자 요청에서 URL에 추가된 모든 이름/값 쌍들이나, GET 방식이 사용된 폼에 있는 HTML 컨트롤 요소값들(읽기 전용)
ServerVariables 클라이언트로부터 이들의 요청과 함께 전달된 모든 HTTP 헤더 값들과 웹 서버의 여러 가지 환경 변수값들(읽기 전용)

Property (속성)
TotalBytes 사용자에 의해 전송된 요청의 본문에 있는 바이트들의 총 수(읽기전용)

Method (메소드)
BinaryRead(count) 데이터가 POST 요청의 일부로 서버로 전송될 때, 사용자 요청으로부터 count 바이트의 데이터를 얻어낸다. 이것은 Variant 배열로 반환되며 ASP 코드가 이미 Request.Form 컬렉션을 참조했으면 이 메소드는 사용될 수 없다. 마찬가지로 여러분이 BinaryRead 메쏘드를 사용했으면 Request.Form 컬렉션도 사용할 수 없게 된다. 둘 중에 하나만이 사용

위의 표에서 굵게 처리한 것들이 Request 개체의 자주 쓰이는 것들입니다.가장 많이 쓰이는 것이 바로 QueryString, Form 입니다만...아마도 이들을 명시해서 사용하는 분은 없을 것입니다... 반드시 명시할 필요는 없기 때문이지요...  ^^   그 이야기는 이따가 다시 하시고 하구요.. 이제 한번 조금은 더 구체적으로 알아볼까요?


1. QueryString & Form

이 컬렉션은 한 페이지에서 다른페이지로 GET 방식으로 데이터를 보낼때, 그 클라이언트가 보낸값을 알아내기 위해 쓰입니다. 간단하게 예를 코드로 보면 다음과 같은 코드를 통해서 알 수 있습니다.

Form.htm

<html>
<body>
    <form Action="Result.asp" METHOD="GET">
        이름 : <INPUT TYPE="Text" NAME="name"><br>
        나이 : <INPUT TYPE="Text" NAME="age"><br>
    <INPUT TYPE="Submit" NAME="Enter" Value="확인">
    </form>
</body>
</html>

Result.asp

<html>
<body>
    이름은 <%=Request.QueryString("name")%> 이구요..<br>
    나이는 <%=Request.QueryString("age")%> 입니다
</body>
</html>

각각의 페이지를 작성해서... 웹 서버의 디렉토리에 올리고...  ^^Form.htm 부터 로딩해서 살펴보면,... 각각의 폼안의 컨트롤에 입력한 값이..Result.asp에 제대로 찍혀나오는 것을 볼 수 있을 것입니다.

중요한 것은 폼안의 컨트롤들의 이름과 Request.QueryString 할 때의 이름이 같아야 한다는 겁니다.이 이름은 반드시 맞추어 주셔야만 합니다. 반드시요.. 안 그러면, 그 값으로 NULL이 나오게 되기에 문제가 될 수 있습니다.

그리고, 위의 소스에서는 Form.htm 페이지의 폼 태그안에서..그 폼의 Method를 GET으로 준 것을 볼 수가 있습니다. 만일, 위처럼 GET 방식으로 데이터를 전송한다면반드시 ASP 측에서는 Request 개체의 QueryString로 그 값을 받아야 합니다.  ^^QueryString 이란 메소드가 바로 GET 방식으로 넘어오는 데이터를 서버측에서 얻어내는 역할을 하니까요

하지만, GET 방식으로 넘어오는 데이터들은 그다지 보안에 좋지 못합니다.이러한 데이터들은 브라우저의 URL바에 그 넘어오는 값이 모두 노출되기 때문이지요...

해서, 그보다는 POST 방식으로 데이터를 전송하는 것이 추천되는데..폼을 통해서 데이터를 전송할 경우 폼의 Method를 POST 로 지정해 주게되면 해당 데이터들이 URL의 꼬리에 붙어서 전송되는 것(브라우저의 URL바에 다 보임)이 아니라HTTP 헤더안에 포함되어져 오기에 조금은 보안적인 데이터 전송방법이라고 볼 수 있지요..물론, 완전한 보안적인 방법은 아니구요. QueryString 에 비하면 그렇다는 것입니다. ^^

이 방법은 뭐 많이 바꿀 것이 없습니다. 단지, 위의 소스에서 Form 태그안의 Method를 POST로만지정하면 그게 전부이지요..  ^^ 위의 소스를 POST 방식으로 바꾼 소스를 한번 보입시다.

Form.htm

<html>
<body>
    <form Action="Result.asp" METHOD="POST">
        이름 : <INPUT TYPE="Text" NAME="name"><br>
        나이 : <INPUT TYPE="Text" NAME="age"><br>
        <INPUT TYPE="Submit" NAME="Enter" Value="확인">
    </form>
</body>
</html>

Result.asp

<html>
<body>
    이름은 <%=Request.Form("name")%> 이구요..<br>
    나이는 <%=Request.Form("age")%> 입니다
</body>
</html>

소스중에 굵고, 빨갛게 처리된 부분이 수정된 부분입니다. 두 페이지 모두 다음과 같은 결과를 가져다 주기는 하지요...


단지 중요한 것은 하이퍼링크로 정보를 보낼때는 form을 쓰지못하고 반드시 Querystring를 써야만 한다는 것입니다. 하이퍼링크를 통해서 넘어오는 데이터는 GET 방식으로 넘어오게 되기에 말입니다.

하지만, 이 두가지 컬렉션 QueryString, Form 을 반드시 명시해 주어야 하는 것은 아닙니다..GET 방식으로 넘어오던, POST 방식으로 넘어오던 그 데이터를 서버측에서 얻어내기 위해서는

GET : Request.QueryString("...")POST : Request.Form("...")
GET, POST : Request("...")

와 같이 할 수 있다는 뜻입니다. 고로, 위의 Result.asp 소스는... 폼에 GET 방식이던, POST 방식이던지에 무관하게다음처럼 작성할 수 있다는 것이지요.

Result.asp

<html>
<body>
    이름은 <%=Request("name")%> 이구요..<br>
    나이는 <%=Request("age")%> 입니다
</body>
</html>

이 방법은 간단하기는 하지만, 그다지 서버의 성능에 좋지 못한 방법입니다...고로, 튜닝시에는 반드시 제대로 된 컬렉션의 이름을 지정하는 것이 필요합니다.

그러니 첨부터 프로그래밍시에 QueryString 이나 Form 을 사용해주는 것이 바람직합니다.개발자에게 가장 귀찮은 방법이 가장 빠른 방법이고는 합니다..  ^^


2. ServerVariables

Servervariable는 서버자체의 CGI버전이나 PORT, 로그인 유저명,IP주소등을 알려주는 컬렉션입니다.만일, 현재 서버의 웹 서버 버전을 알고 싶다면 다음처럼 하시면 됩니다..

Request.Servervariables("SERVER_SOFTWARE") 혹은 Request("SERVER_SOFTWARE") 처럼 사용하면 된답니다. 하지만, 역시 Request("SERVER_SOFTWARE") 라고 하는 방법은 서버의 성능에좋지 못합니다. 가급적 Request.Servervariables("SERVER_SOFTWARE") 라고 사용하세요

이 컬렉션을 사용해서 우리가 개발자의 입장에서 쓸만한 것은 사용자의 접속 IP 주소를 알아오는

Request.Servervariables("REMOTE_ADDR")

가 있습니다. 그리고, 사용자의 브라우저나 OS 버전을 알 수 있게 해주는

Request.Servervariables("HTTP_AGENT")

정도입니다. 이것은 나름대로 유용한 정보이지요...  ^^그렇다면, 위의 몇 가지 외에 얻어올 수 있는 또 다른 정보들로는 어떤 것들이 있을까요?그것이 사정없이 궁금해 지지 않나요? 하하... 궁금해 지지요?해서 따로 강좌를 준비해 두었습니다.

아래의 링크를 눌러 이 컬렉션의 활용법을 좀 더 알아봅시다. 이 링크를 누르신다면 지금 접속하신 분(당신!!!) 의 접속사항을 보실수 있습니다.

ServerVariables 활용법

출처 : http://www.taeyo.pe.kr/lecture/3_beginner_Objects/Request.htm

Posted by 1010
반응형
OutOfMemoryError: PermGen space

  근래에 들어와서 위의 메세지를 띄우면서 이클립스가 죽는 경우가 많이 생겼다. 'out of memory'라는 단어만으로 단순히 메모리가 부족해서라고 생각했고, 웹검색을 통해서 이클립스를 실행할 때 JVM의 힙 메모리의 용량을 지정할 수 있는 방법을 찾아냈다.

  메모리를 넉넉하게 지정하고 사용하면서 한동안 보이지 않았던 위의 에러 메세지가 얼마 전 부터 다시 보이기 시작했다. 또 다시 웹 검색을 시작했다. 덕분에 오늘 많은 것들을 배울 수 있었다.

  자바의 Heap공간은 내가 알던 것 보다 더 많은 부분으로 나누어져 있다는 것을 알게 되었고 더불어 GC(Garbage Collection)에 대한 부분도 몇 가지 GC알고리즘이 있고 그 중 어플리케이션의 사용 환경에 따라 선택하여 사용할 수 있게 하는 JVM옵션이 있다는 것도 알았다.


New/Young(신세대 힙)
- 객체가 생성되자마자 저장되고, 생긴지 얼마 안된 객체가 저장되는곳. 이 곳에 있는 객체들은 시간이 지남에 따라 우선순위가 낮아지면서 Old영역으로 옮겨진다.

Old 영역(구세대 힙)
- New/Young 영역에 저장되었던 객체중에 오래된 객체가 이동되어 저장되는 영역

Perm 영역(영구세대 힙)
- Class, Method 등의 Code 등이 저장되는 영역. JVM에 의해서 사용된다.


  JVM의 Heap공간은 위의 3가지가 있는데, 내 문제는 그 중에서도 Perm영역의 메모리 공간이 부족했던 것 같다. 이클립스의 WTP를 쓰다보면 클래스의 양이 늘어남에 따라 Permanent generation의 공간이 부족하게 되고, 부족하게 되면 종종 이클립스가 'OutOfMemoryError: PermGen space'에러를 내 뿜으며 쓰러지곤 한다고 한다는 글들을 발견했다.

-vmargs
-Xverify:none
-XX:PermSize=64M
-XX:MaxPermSize=256M
-Xms256m
-Xmx512m

    해결 방법으로 이클립스에 위의 내용처럼 옵션을 줘서 사용하기로 했다.

  이클립스 뿐만 아니라 JVM을 사용하는 어플리케이션에서 메모리로 인한 에러가 발생한다면 메모리 관련 JVM옵션을 사용 해 주면 해결되니 좀 더 관련 자료를 봐 두기로 했다.


  도움이 많이 되었던 문서들을 블로그에 남긴다.S


출처 : http://signpen.net/blog/2510863
Posted by 1010
반응형

오늘 부터 eclipse galileo에 flash builder를 얹어서 사용하려고 새로나온 galileo를 깔았더니, 이런 에러는 내뱉었습니다.


흠...

초기화가 문제로 보여져서 ecslipse.ini파일을 편집해 봤습니다.


eslipcse.ini 내용

-startup
plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.jee.product
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m

-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m

빨간색으로 표시한 부분이 웬지 석연치 않습니다. 그래서 다음과 같이 변경했습니다.


-startup
plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.jee.product
-launcher.XXMaxPermSize
256m
-showsplash
org.eclipse.platform
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m

-- 을 -로 변경하고 M을 m으로 변경했습니다.  그리고 중복적인 구문이라 제거했습니다.

어짜피 주석 처리했던 것이니 제거하셔도 무방합니다. 해당 매개 변수는 이클립스가 실핼 될 때 할당될 최대 메모리 사이즈로 보입니다.



실행됩니다. ㅡ,.ㅡ;;
주석 처리를 하려면 제대로 해야죵~

이클립스 개발자님들~  고쳐주세요~ ^^


출처 : http://lovedev.tistory.com/482
Posted by 1010
02.Oracle/DataBase2009. 9. 3. 11:36
반응형
1. 설 명

☞ Bulletin no : 12036 참고

 
Oracle 8i Release2(8.1.6)에서는 데이터를 암호화하여 저장할 수 있는
향상된 기능(DES Encryption)을 제공 합니다
 
 
신용카드번호, 패스워드 등 보안이 필요한 데이터를 암호화된 형태로 저장하여
기존의 3rd Party Tool이나, Application Logic으로 구현하던 암호화 정책을
데이터베이스 차원에서 구현할 수 있도록 해줍니다.
 
 
 
DBMS_OBFUSCATION_TOOLKIT

암호화 기능을 이용하려면 DBMS_OBFUSCATION_TOOLKIT을 이용해야 합니다.
 
 
이 패키지는 4개의 프로시져로 이루어져 있습니다.

- VARCHAR2 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져

- RAW 타입을 Encrypt/Decrypt할 수 있는 2개의 프로시져
(다른 타입은 지원하지 않으므로 number인 경우는 to_char 이용)
 
 

DBMS_OBFUSCATION_TOOLKIT을 이용하기 위해서는 :

1) SYS 유저로 아래의 스크립트를 실행 시킵니다.

   @$ORACLE_HOME/rdbms/admin/dbmsobtk.sql
   @$ORACLE_HOME/rdbms/admin/prvtobtk.plb
   
2) 권한을 부여 합니다.

   SQL>GRANT execute ON dbms_obfuscation_toolkit TO public;


2. 패키지 실행하기



--> 패키지 선언부 생성

CREATE OR REPLACE PACKAGE CryptIT AS
   FUNCTION encrypt( Str VARCHAR2,  
                     hash VARCHAR2 ) RETURN VARCHAR2;

   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2;
END CryptIT;
/
 
 
 
--> 패키지 본체 생성

CREATE OR REPLACE PACKAGE BODY CryptIT AS
   crypted_string VARCHAR2(2000);
 
   FUNCTION encrypt( Str VARCHAR2,  
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   pieces_of_eight INTEGER := ((FLOOR(LENGTH(Str)/8 + .9)) * 8);
 
   BEGIN
 
      dbms_obfuscation_toolkit.DESEncrypt(
               input_string     => RPAD( Str, pieces_of_eight ),
               key_string       => RPAD(hash,8,’#’),
               encrypted_string => crypted_string );
      RETURN crypted_string;
   END;
 
   FUNCTION decrypt( xCrypt VARCHAR2,
                     hash VARCHAR2 ) RETURN VARCHAR2 AS
   BEGIN
      dbms_obfuscation_toolkit.DESDecrypt(
               input_string     => xCrypt,
               key_string       => RPAD(hash,8,’#’),
               decrypted_string => crypted_string );
      RETURN trim(crypted_string);
   END;
END CryptIT;
/

 



3. 실행 예제


1) Encrypt하여 데이터 입력

-- 테스트 테이블을 생성 합니다.

SQL>create table encrypt_table( id number, passwd varchar(20) );


 
-- 테스트 데이트럴 입력 합니다.
-- CryptIT.encrypt(비밀번호, 키값)

SQL>INSERT INTO encrypt_table VALUES( 1, CryptIT.encrypt(’1234’, ’storm’));
1 개의 행이 만들어졌습니다.

 
SQL>INSERT INTO encrypt_table VALUES( 2, CryptIT.encrypt(’5678’, ’oramaster’));
1 개의 행이 만들어졌습니다.

 
 
2) Decrypt하여 데이터 조회
 
--> Decrypt하지 않으면 암호화된 데이터와 비교되서 결과값이 출력되지 않습니다.
SQL> select id, passwd from encrypt_table where passwd = ’1234’;
 
선택된 레코드가 없습니다.
 
 
--> 저장장치에 Encrypt된 값으로 저장 됩니다.

SQL> col passwd format a60
SQL> select id, dump(passwd) passwd from encrypt_table;

         ID PASSWD
---------- -------------------------------------------------------------
         1 Typ=1 Len=8: 246,27,80,184,227,225,245,31
         2 Typ=1 Len=8: 175,231,213,125,85,223,46,133
 


--> Encrypt할 때 사용한 Key로만 Decrypt할 수 있습니다.
 
SQL>SELECT id, CryptIT.decrypt(passwd,’storm’) passwd
       FROM encrypt_table
       WHERE CryptIT.decrypt(passwd,’storm’) = ’1234’;
 
        ID PASSWD
---------- -----------
         1 1234
 
 
SQL>SELECT id, CryptIT.decrypt(passwd,’oramaster’) passwd
    FROM encrypt_table
    WHERE CryptIT.decrypt(passwd,’oramaster’) = ’5678’;
 
        ID PASSWD
---------- -----------
         2 5678
 
 
주의) Table에 접근 권한이 있는 다른 유저도 Key값을 알면 Decrypt할 수 있습니다.
 
 
 
4) 관련 ORA error number
 
ORA error 28231 "Invalid input to Obfuscation toolkit"
- input data, key값이 NULL일 경우 발생
 
ORA error 28232 "Invalid input size for Obfuscation toolkit"
- input data가 8 bytes 배수가 아닐 경우 발생
 
ORA error 28233 "Double encryption not supported by DESEncrypt in Obfuscation toolkit"
- encrypt data를 다시 encrypt경우 발생
 

관 련 자 료
===========
Oracle8i Supplied PL/SQL Packages Reference Release 2 (8.1.6)
 

  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^


출처 : http://www.oracleclub.com/lectureview.action
Posted by 1010
반응형
 jQuery  mootools 충돌 해결

마지막으로 기억할 사항은 jQuery나 다른 자바스크립트 라이브러리를 사용할 때, 서로 어울려 동작하지 않을 경우가 있다는 사실이다. 다시 말해, 라이브러리 두 개 이상을 사용할 경우, 라이브러리 둘 이상에서 변수 "$"를 사용한다면 엔진은 어떤 라이브러리가 "$" 호출을 참조해야 할지 모르는 사태가 벌어진다. 이런 현상을 설명하는 완벽한 예제는 protyotype.js에 내장된 CakePHP 라이브러리다. 이런 라이브러리를 사용하는 페이지에서 수정없이 jQuery를 호출하려고 시도하면 오류가 발생한다. 이런 문제를 해결하기 위해 jQuery는 "$" 변수를 다른 변수로 사상하는 방법을 제공한다. 다음 예를 살펴보자.


Listing 4. jQuery 충돌 해결
j$ = jQuery.noConflict();
j$("div").addClass("a");


-------실무예제--------

j$ = jQuery.noConflict();
//j$("div").addClass("a");

// �α�
function inFocus(i) {
 (i).style.background='none';
}
function outFocus(i) {
}
// Jquery GNB
 j$(function() {
  j$("#inquiry").tabs();
  j$("#counsel").tabs();
 });

Posted by 1010
카테고리 없음2009. 9. 1. 12:00
반응형

jQuery로 작업하기, Part 1: 브라우저로 데스크톱 응용 옮기기

난이도 : 중급

Michael Abernethy, 제품 개발 관리자, Optimal Auctions

옮긴이: 박재호 이해영 dwkorea@kr.ibm.com

2008 년 11 월 18 일

jQuery는 동적 RIA(Rich Internet Application)를 쉽게 만들기 위해 개발자가 고려하는 자바스크립트 라이브러리로 뜨고 있습니다. 브라우저 기반 응용은 데스크톱 응용을 계속해서 대체하고 있기에, 이런 라이브러리는 계속해서 활용 범위가 넓어질 것입니다. jQuery 연재물을 통해 jQuery 관련 지식을 얻고 웹 응용 프로젝트에 활용하는 방법을 익혀봅시다.

도입

jQuery는 웹 개발자를 위한 라이브러리 선택 과정에서 다른 자바스크립트 라이브러리 옵션과 간격을 벌리기 시작했으며, 클라이언트 쪽 개발을 쉽게 도와주며 RIA를 빠르고 효과적으로 만드는 방법을 찾고 있는 프로그래머의 관심을 한몸에 받고 있다. RIA 활용이 점점 더 세상에 널리 퍼짐에 따라, 개발을 돕기 위한 자바스크립트 라이브러리 활용도 함께 늘어날 것이다. RIA는 데스크톱에서 동작하는 응용과 비슷한 효과를 얻기 위해 CSS/자바스크립트/Ajax를 조합해 브라우저를 통해 동작하는 응용으로 (대충) 정의할 수 있다. 파이어폭스, IE, 사파리, 구글이 최근 선보인 새로운 크롬 브라우저에 추가된 최신 기능은 브라우저 내부 자바스크립트 엔진 속력을 높이는 데 초점을 맞추고 있다. 이렇게 하는 가장 중요한 이유는 브라우저 제조사가 우리에게 머지 않은 장래에 등장할 좀 더 매혹적인 RIA 보급을 장려하기 위해서다. 브라우저 회사들은 수만 행에 이르는 자바스크립트 코드를 포함하는 웹 페이지를 마음 속에 그리고 있으며, 시작부터 숙성되고 버그가 없는 라이브러리의 중요성을 강조한다.

따라서 웹 응용의 미래가 사람들을 몰두하게 만드는 풍부한 인터페이스로 이동함에 따라 웹 개발자는 점점 더 이런 작업을 쉽게 도와주는 도구로 방향을 바꾸고 있다. 지금 바로 사용할 수 있는 자바스크립트 라이브러리가 시중에 나와 있으며, 각각은 나름대로 장단점은 물론이고 열성파와 반대파도 있다. 기능 측면에서 우월성을 따지지 않는 이유는 궁극적으로 그다지 중요한 문제가 아니기 때문이다. 궁극적으로 어떤 라이브러리가 양으로 승부를 걸어 인기가 더 많은지를 고려해야 한다. 네 가지 가장 인기 있는 자바스크립트 라이브러리를 구글 트렌드 그래프로 살펴본 모습은 다음과 같다. 과거 6~8개월 동안에 jQuery가 자바스크립트 라이브러리 중에서 가장 인기를 끌고 있으며, 가파르게 성장중이다.


그림 1. 인기있는 자바스크립트 라이브러리를 구글 트렌드로 추적한 결과
인기있는 자바스크립트 라이브러리를 구글 트렌드로 추적한 결과

구인 시장에도 자바스크립트 라이브러리로 jQuery가 뜨고 있음을 확인할 수 있다. 경력 관리 네트워크인 Monster.com을 대충 살펴봐도 "jQuery" 관련 일자리가 113개가 나오는 반면에 YUI는 67개, ExtJS는 19개, mootools는 13개만 나온다.

jQuery 연재물 중 첫 번째 기사는 jQuery 문법, 설정 방법, 함수 호출 방법부터 살펴본다. 이 기사 후반부에는 라이브러리에 들어있는 핵심 함수를 탐험하고 DOM 탐색을 쉽고 직관적으로 가능하게 만드는 강력한 선택자와 필터 활용법을 탐험한다. 나중에 나오는 기사에서는 CSS 처리, 폼 제어, 텍스트 변경, Ajax 단순화, (모든 사람의 눈을 즐겁게 만들어주는) 애니메이션을 소개한다. jQuery에서 가장 흥미로운 기능은 플러그인 아키텍처로, 개발자가 jQuery 기능을 추가하도록 도와준다. 마지막 기사에서는 RIA 개발 과정을 완료하기 위해 활용 가능한 강력한 플러그인 몇 가지를 소개한다.

이 연재물은 자바스크립트 문법, CSS 문법, DOM 문법을 미리 알고 있는 독자를 염두에 둔다. 연재물을 읽기 전에 각각에 대한 문법을 다시 한번 기억할 필요가 있다면, 이 기사 참고자료 절에 실어 놓은 W3Schools를 강력하게 추천한다.

기초

jQuery로 즐거운 여행을 떠나기 전에 설치나 시작 같은 기초 내용을 확인할 필요가 있다. 다운로드 절에서 jQuery 라이브러리를 내려받아 다른 외부 자바스크립트 파일과 마찬가지로 연결하는 작업부터 시작하자.


Listing 1. 코드에 jQuery를 설치하는 방법
<script type="text/javascript" src="jquery.js"></script>

jQuery가 DOM 객체를 다루므로, 페이지에 있는 모든 엘리먼트를 메모리에 올리기 전에 자바스크립트에서 이런 객체를 처리한다면 문제가 생긴다. 하지만 jQuery 코드를 호출하기 전에 이미지, 배너 광고, 분석 코드, 유튜브 미리 보기 같이 페이지에 있는 모든 구성 요소가 메모리에 올라올 때까지 기다리기도 원하지 않을 것이다. 적당히 타협점을 찾아 페이지에 있는 모든 엘리먼트가 올라오고 이미지, 링크 처리, 렌더링이 끝나기 전에 안전하고 오류도 없는 상황에서 jQuery 코드를 호출하면 된다. 이런 중요한 원칙을 지키려면, 모든 jQuery 코드는 on page나 자체 함수에서 이런 기능을 수행할 필요가 있다. 함수가 아닌 다른 자바스크립트 영역에 jQuery 코드를 놓아두지 말자.


Listing 2. 적절하게 jQuery 함수를 호출하는 방법
// 틀림
<script language=JavaScript>
   $("div").addClass("a");
</script>

// 바름
$(document).ready(function(){
   $("div").addClass("a");
 });

// - 또는 -

$(document).ready(function(){
   myAddClass();
 });

function myAddClass()
{
   $("div").addClass("a");
}

또한 추가로 도움이 될 만한 내용을 하나 더 소개한다. 한 페이지에서 document.ready() 함수를 여러 번 사용할 수 있으며, 각각은 차례로 호출이 일어난다. 모듈로 페이지를 동적으로 구성하며, 모듈마다 독자적인 jQuery 코드를 지원할 때(예: 작은 PHP 코드 조각으로 구성된 PHP 페이지) 이를 염두에 두는 편이 좋다.

jQuery에서 가장 흥미로운 기능 중 하나는 "체인 연결"이다. 이 기능은 가독성과 코드 용이성을 높이기 위해 일련의 함수를 하나로 붙이도록 만든다. 거의 모든 jQuery 함수는 jQuery 객체를 반환하므로, 간단하게 반환된 객체에 추가적인 함수를 호출하는 방식으로 체인을 여러 개 연결해서 완벽한 jQuery 명령을 만들 수 있다. 자바에서 제공하는 String 클래스와 이 기능을 비교한다. 자바에서 여러 함수가 한 행에 반환한 String 객체를 결합하듯이 jQuery에서는 여러 함수를 한 행에 체인으로 연결한다.


Listing 3. jQuery 체인 연결
String man = new String("manipulated").toUpperCase().substring(0,5).toLowerCase();

$("div").addClass("a").show().text("manipulated");

마지막으로 기억할 사항은 jQuery나 다른 자바스크립트 라이브러리를 사용할 때, 서로 어울려 동작하지 않을 경우가 있다는 사실이다. 다시 말해, 라이브러리 두 개 이상을 사용할 경우, 라이브러리 둘 이상에서 변수 "$"를 사용한다면 엔진은 어떤 라이브러리가 "$" 호출을 참조해야 할지 모르는 사태가 벌어진다. 이런 현상을 설명하는 완벽한 예제는 protyotype.js에 내장된 CakePHP 라이브러리다. 이런 라이브러리를 사용하는 페이지에서 수정없이 jQuery를 호출하려고 시도하면 오류가 발생한다. 이런 문제를 해결하기 위해 jQuery는 "$" 변수를 다른 변수로 사상하는 방법을 제공한다. 다음 예를 살펴보자.


Listing 4. jQuery 충돌 해결
j$ = jQuery.noConflict();
j$("div").addClass("a");

선택

모든 jQuery 루트는 페이지에서 특정 엘리먼트를 선택해 다룰 수 있는 능력이 있다. jQuery 라이브러리에 포함된 함수를 둘러싼 다양한 객체가 있다. 따라서 일반 HTML 페이지에서 사용 가능한 수 많은 옵션에서, 작업하기 원하는 엘리먼트를 (더도 말고 덜도 말고) 페이지에서 꼭 집어내어 빠르고 효율적으로 선택하는 방법이 필요하다. 예상했겠지만, jQuery는 강력한 선택 메서드를 제공해서 페이지에서 객체를 찾아내어 선택하도록 만든다. jQuery는 선택을 위한 독자적인 구문을 만들어 내었으며, 상당히 배우기 쉽다.

(아래 소개하는 다양한 예에서 사용하는 함수는 다음 기사에서 설명하겠지만, 무엇을 하는 함수인지 이해하기에 충분할 정도로 직관적이다.)

루트에서, jQuery 선택 과정은 정말 거대한 필터 과정이다. 페이지에 존재하는 모든 엘리먼트를 명령에서 제공하는 필터에 밀어넣은 다음에, 일치하는 객체 자체나 탐색이 가능한 객체 배열을 반환한다.

첫 세 가지 예제가 가장 널리 쓰인다. HTML 태그, ID, CLASS로 객체를 찾아내는 방법이다.

HTML

페이지에서 일치하는 모든 HTML 엘리먼트 배열을 얻으려면, 중괄호 없이 단순히 HTML 태그 자체를 jQuery 검색 필드에 전달하면 된다. 이는 객체를 찾아내는 "빠르지만 우아하지는 않은" 방법이며, 일반적인 HTML 엘리먼트에 속성을 붙일 때 유용하다.


Listing 5. HTML 선택
// 이 예제는 페이지에서 모든 <div> 태그를 보여준다. 여기서
// 처음이나 마지막에 걸리는 태그가 아니라 모든 <div> 태그를 보여줌에 주목하자.
// 배열 탐색은 이 기사 후반부에 다룬다.
$("div").show();

// 페이지에 존재하는 모든 <p> 태그에 붉은 배경색을 부여한다.
$("p").css("background", "#ff0000");

ID

페이지 디자인을 제대로 하려면 페이지에 있는 모든 ID를 유일하게 만들어야 한다. 물론 이런 규칙이 (의도적이든 의도적이지 않든) 종종 깨지긴 하지만 말이다. jQuery가 ID 선택 과정에서 첫 번째 일치하는 엘리먼트만 반환하는 이유는 적절한 페이지 디자인을 따른다고 가정하고 있기 때문이다. 동일한 페이지에 존재하는 여러 엘리먼트에 태그를 붙일 필요가 있다면 CLASS 태그가 좀 더 적절한 선택이다.


Listing 6. ID 선택
// 이 예제는 "sampleText"라는 id가 달린 innerHTML이나 span 엘리먼트를 찾아서 id를 "Hi"로 바꾼다.
// 명령어 처음에 나오는 "#"에 주목하자. 이는 jQuery가 사용하는 구문으로, ID를 찾는다.
// "#"은 반드시 있어야 하며, 만일 빠뜨리면 jQuery는 HTML 태그를 대신 찾으며,
// <sampleText> 태그가 페이지에 없으므로 결국 아무런 결과도 반환하지 않는다.
// 이럴 경우 아주 찾기 어려운 버그에 직면한다.

$("#sampleText").html("Hi");

CLASS

CLASS는 ID와 비슷하지만 페이지에 들어있는 엘리먼트 한 개 이상을 위해 쓰일 수 있다. 따라서 페이지에 ID당 엘리먼트 하나만 존재한다는 제약을 풀어야 한다면 페이지에 동일한 CLASS로 표시한 여러 엘리먼트를 배치할 수 있다. CLASS를 활용하면 CLASS 이름 하나만 전달하는 방식으로 페이지에 존재하는 광범위한 엘리먼트를 돌면서 함수를 실행하는 자유를 얻는다.


Listing 7. CLASS 선택
// 특정 페이지에서 "redBack"이라는 CLASS로 지정된 모든 엘리먼트 배경을 붉은색으로 만든다.
// 이 "redBack" CLASS 태그가 어떤 HTML 엘리먼트에 붙어있는지 상관하지 않음에 주목하자.
// 또한 질의 용어 앞에 붙은 .에 주목하자. CLASS 이름을 찾기 위한 jQuery 구문이다.

$(".redBack").css("background", "#ff0000");

<p class="redBack">This is a paragraph</p>
<div class="redBack">This is a big div</div>
<table class="redBack"><tr><td>Sample table</td></tr></table>

검색 기준 결합하기

상기 세 가지 검색 기준과 아래 제시하는 필터를 결합해 검색을 내릴 수 있다. 검색 기준은 ","로 구분하며, 검색 결과로 검색 단어에 일치하는 결과를 모두 결합한 내용을 반환한다.


Listing 8. 검색 결합하기
// 모든 <p>, <span>, or <div> 태그를 가린다.
$("p, span, div").hide();

다른 필터

jQuery에서 가장 널리 사용하는 검색 매개변수 세 가지를 소개했는데, 페이지에서 원하는 엘리먼트를 빨리 찾도록 도와주는 다른 필터도 존재한다. 이런 필터는 모두 jQuery 검색 단어에서 필터를 나타내는 ":" 글자로 시작한다. 검색 범주에서 단독으로 사용이 가능하지만, 주로 원하는 구체적인 엘리먼트를 찾기 위해 검색 기준을 튜닝하는 방식으로 앞서 소개한 세 가지 검색 기준과 함께 사용하도록 설계되었다.


Listing 9. 다른 필터
// 페이지에서 모든 <p> 태그를 가린다.
$("p").hide();

// 페이지에서 HTML 태그에 무관하게 첫 엘리먼트를 가린다.
$(":first").hide();

// 검색 기준을 좀 더 정교하게 튜닝하게 다듬는 기능을 제공하기 위해 섞어서 사용하는
// 방법을 보여준다. 특정 페이지에서 첫 번째 <p> 태그만 감춘다.
$("p:first").hide();

다중 필터를 검색 엘리먼트로 사용할 수 있다. 여기에 모든 필터를 열거하지는 않겠지만(API 페이지를 보면 다 나오는 내용이다), 몇몇은 페이지나 엘리먼트 검색 작업에 아주 간편하게 쓸 수 있다.

선택 패키지에서 몇 가지 아주 중요한 필터를 설명하겠는데, 바로 폼 엘리먼트 필터다. 오늘날 RIA(Rich Internet Application)는 폼과 서버로 정보를 주고 받기 위한 목적으로 폼에 포함된 엘리먼트(텍스트 필드, 버튼, 체크 박스, 라디오 버튼 등)에 초점을 맞추는 듯이 보인다. 폼이 RIA에서 중요한 위치를 차지하므로 오늘날 웹 응용 프로그램에서 jQuery를 사용하는 관례는 특히 중요하다.

추가 필터와 마찬가지로 이 기사에서 소개하는 폼 필터도 필터임을 알려주는 ":" 문자로 시작한다. 또한 검색 결과를 좀 더 정교하게 얻기 위해 다른 검색 필터와 섞어서 사용하기도 한다. 따라서 ":text"라는 검색 필터는 페이지에 존재하는 모든 텍스트 필터를 반환하며, ".largeFont:text"라는 검색 필터는 페이지에서 "largeFont" 클래스인 텍스트 필드만 반환한다. 이는 폼 엘리먼트를 정교하게 조작하기 위한 기능을 제공한다.

폼 필터는 또한 개발자가 알아 두면 좋은 내용인 엘리먼트의 개별 속성을 포함한다. 따라서 ":checked", ":disabled", ':selected"와 같은 필터는 검색 기준을 정교하게 지정하도록 사용할 수 있다.

탐색

페이지에 있는 모든 엘리먼트를 탐색하고 필터링하는 방법을 익혔다면, 결과를 탐색하고 이런 엘리먼트를 조작하는 효과적인 방법이 필요하다. 놀랍지 않게도, jQuery는 이런 검색 결과를 탐색하는 다양한 방법을 제공한다.

가장 대표적이면서 널리 사용되는 탐색 기법은 each() 함수다. 이 함수는 엘리먼트 각각을 순회하며 루프를 돌 때마다 엘리먼트를 하나씩 처리하기에 프로그래밍 측면에서 "for loop"와 동일하다. 추가적으로 "this"(일반적인 자바스크립트 구문을 사용할 경우)나 $(this)(jQuery 명령어를 사용할 경우)로 루프 내에서 각 엘리먼트를 참조할 수 있다.

다음 예를 살펴보자.


Listing 10. 개별 루프
// 페이지에 있는 각 <p> 태그를 대상으로 순회한다. 여기서 인라인 함수 사용에 주목하자.
// 자바에서 anonymous 클래스와 비슷한 기능이다.
// 개별 함수를 호출하거나 이와 같이 인라인 함수를 작성할 수 있다.

var increment = 1;
$("p").each(function(){

    // 이제 태그를 만날 때마다 문단 카운터를 하나씩 더한다. $(this) 변수를 사용해
    // 개별 문단 엘리먼트를 참조하는 방법에 주목하자.

    $(this).text(increment + ". " + $(this).text());
    increment++;
});

검색 결과가 배열에 저장되므로 일반적인 프로그래밍 언어에서 자료 객체와 비슷하게 배열을 순회하면서 작업하는 함수를 기대할 것이다. 특정 검색 결과 길이를 알기 위해 배열에 $().length를 호출한다. Listing 11에 다른 배열 탐색 함수도 등장하는데, 다른 프로그래밍 언어와 마찬가지로 배열 탐색에 적합한 형태를 보여준다.


Listing 11. 추가적인 배열 함수
// eq() 함수는 직접 배열에 속한 구성 요소를 참조할 때 사용한다.
// 이 경우 세 번째 문단(당연히 0이 시작 기준이다)을 얻은 다음에 감춘다.
$("p").eq(2).hide();

// slice() 함수는 배열에서 처음과 끝 색인을 받아서 새끼 배열을 친다.
// 다음은 페이지에서 세 번째부터 다섯 번째까지 문단을 감춘다.
$("p").slice(2,5).hide();

이런 배열 탐색 함수 이외에, jQuery는 또한 검색 단어를 둘러싼 충첩된 엘리먼트를 찾도록 도와주는 함수도 제공한다. 이런 함수가 유용한 경우가 있을까? 글쎄, 종종 그림에 따라나오는 텍스트 라벨이나 폼 엘리먼트 다음에 오류 메시지를 포함하기를 원한다. 이런 명령어를 사용하면 특정 폼 엘리먼트를 찾아서 span 태그와 같이 다음 엘리먼트에 바로 오류 메시지를 표시하는 방법으로 사용자에게 경고 메시지를 보여줄 수 있다. Listing 12는 이런 디자인 예를 보여준다.


Listing 12. next() 함수 예
<input type=text class=validate><span></span>

function validateForm()
{
    $(".validate:text").each(function(){
    if ($(this).val()=="")
    //  페이지에서 "validate" 클래스로 정의된 각 textfiled를 순회한다.
    //  비어 있다면, <span> 바로 뒤에 오류 메시지를 집어 넣는다.

        $(this).next().html("This field cannot be blank");
});
}

이 기사에서 배운 내용을 하나로 합치기

이 기사에서 배운 내용을 하나로 합친 결과를 보기 위해, 이 기사에 들어 있는 데모 용응을 살펴보자(다운로드 절을 참조한다).

데모 응용은 여기서 간략하게 소개하는 편이 좋겠다. 이 기사 연재 전반에 걸쳐 데모 응용을 사용해서 다양한 jQuery 예제를 보여주며, 거의 모든 사람이 친숙한 RIA 웹 메일이라는 응용을 다룰 계획이기 때문이다. 이 데모 응용은 간단한 메일 클라이언트로서 jQuery를 활용해서 사용자에게 실제로 데스크톱 응용에서 볼 수 있는 전자편지 클라이언트를 사용하는 느낌을 전달한다. 최종 기사가 끝날 무렵이면 사용자를 위한 외형과 느낌을 만들어내는 과정은 물론이고 jQuery로 얼마나 손쉽게 이런 작업을 하는지 확인할 수 있을 것이다.

이 기사에서는 웹 메일 테이블에 있는 좌상단 컬럼에 보이는 "Select All"/"Deselect All" 체크 박스에 초점을 맞춘다(아래에 강조했다). 이 체크 박스를 선택하면, 컬럼에 있는 모든 체크 박스를 선택하며, 체크 박스 선택을 해제하면, 컬럼에 있는 모든 체크 박스 선택을 해제한다.


그림 2. "Select All" 체크 박스
Select All 체크 박스

Listing 13. 여기서 배운 모든 내용을 하나로 합치기
				
<!-- 1 단계는 Select All 체크박스 자체 생성이다.
페이지에서 체크박스에 유일한 ID를 부여한다. -->

<input type=checkbox id=selectall>

<!-- 2 단계는 체크박스에 속한 각 행을 만들어낸다.
각 행에 속한 체크박스에 'selectable' 클래스를 지정한다. 행이 여러 개며
또한 행에 속한 각 체크박스가 동일한 행동 방식을 보이기를 원하기 때문이다. -->

<input type=checkbox class=selectable>

<!-- 3 단계(마지막)는 jQuery 코드를 사용해서 하나로 합친다. -->

// 모든 jQuery 설정 코드는 이 document.ready() 함수에 있어야 함을 기억하자.
// 아니면 올바르게 동작하기 위해 자체 함수에 포함되어 있어야 한다.

$(document).ready(function(){
   // 페이지에서 selectall 체크박스를 찾기 위해 jQuery 선택 구문을 활용한다.
   // (ID를 지정하는 '#'에 주목하자) 그리고 jQuery에게 selectAll() 함수를 
   // 누군가 체크박스에 클릭할 때마다 호출하도록 알려준다.(이벤트는 다음 기사에서
   // 다루겠다).

   $("#selectall").click(selectAll);
});

// 이 함수는 누군가 selectall 체크박스를 누를 때마다 호출될 것이다.
function selectAll()
{
    // 이 행은 selectall 체크박스가 체크되었는지 아닌지를 판단한다.
    // 다음번 기사에 소개할 attr() 함수는 넘어온 객체에서 속성을 반환한다.
    // 여기서 체크 되었으면 true를, 그렇지 않으면 undefined를 반환한다.

    var checked = $("#selectall").attr("checked");

    // 이제 jQuery 선택 구문을 활용해서 페이지에 속한 모든 체크박스를 찾는다.
    // 여기서 (각 행의 체크박스인) selectable class를 지정하는 방법을 쓴다.
    // 선택 결과 넘어오는 배열을 얻어서 each() 함수를 사용해서 순회한다.
    // 이렇게 되면 한번에 하나씩 결과 항목을 처리할 수 있다. each() 함수 내부에서
    // $(this) 변수를 사용해서 개별 결과를 참조할 수 있다. 따라서 루프 내부에서
    // 각 체크박스 값을 찾아서 selectall 체크박스와 일치하도록 만든다.

    $(".selectable").each(function(){
       var subChecked = $(this).attr("checked");
       if (subChecked != checked)
          $(this).click();
    });
}

결론

jQuery는 웹 응용 개발 공동체에서 선호하는 자바스크립트로 자리를 잡아가는 중이며, RIA가 점점 더 널리 퍼짐에 따라 꾸준한 성장세를 보이고 있다. 여러 회사가 내부 응용을 온라인으로 이주하며, (워드 프로세서와 스프레드시트를 포함해서) 매일 사용하는 데스크톱 응용도 온라인으로 옮기는 상황에서, 개발을 쉽게 만들어주며 교차 플랫폼 지원을 약속하는 자바스크립트 라이브러리는 응용을 설계할 때 선택하는 기술의 일부가 될 것이다.

jQuery 연재물에서 첫 번째 기사는 jQuery 구문, 자바스크립트 코드에서 jQuery를 올바르게 사용하는 방법, 다른 라이브러리와 함께 사용할 때 함정을 피하는 방법을 소개한다. 또한 jQuery가 제공하는 다양한 기능 중에서 jQuery 검색과 선택 구문을 소개한다. 원하는 페이지 엘리먼트를 간편하고 빠르게 찾아내는 방법과 찾아낸 엘리먼트를 처리하는 방법을 소개한다. 또한 이 기사에서는 개별 엘리먼트를 처리하도록 이런 검색 결과를 순회하는 방법도 보여준다. 이번 기사에서 설명한 선택과 처리 방법은 연재물에서 소개할 다음 기사를 뒷받침하는 기초가 되며, 여러분이 만든 jQuery 코드를 뒷받침하는 기본 기술이 될 것이다.

마지막으로 RIA 웹 메일이라는 응용 시연을 다뤘다. 이 기사에서 배운 jQuery를 사용해서 Select All/Deselect All 체크 박스 선택 기능을 만들어 보았다. 살펴보면 알겠지만 단지 몇 줄만으로 다양한 웹 사이트에서 볼 수 있는 공통 위젯을 만든다.

이번 연재물에 이어지는 다음 기사는 예제 웹 응용에 상호대화식 기능을 추가하는 방법을 소개한다. (엘리먼트 클릭, 버튼 클릭, 콤보 박스 클릭 등) 페이지 이벤트를 다루는 방법, 페이지에 들어있는 엘리먼트에서 값을 얻는 방법, 페이지를 다시 읽지 않고서도 색상, 레이아웃 등을 바꾸기 위해 표준 CSS를 변경하는 방법을 배울 것이다.

출처 : http://www.ibm.com/developerworks/kr/library/wa-jquery1/index.html



Posted by 1010
01.JAVA/Java2009. 9. 1. 10:26
반응형


JAR 파일

JAR 파일 포맷의 힘

문서 옵션

 

 


제안 및 의견
피드백

난이도 : 초급

Pagadala J. Suresh, 소프트웨어 엔지니어, IBM Global Services India
Palaniyappan Thiagarajan, 소프트웨어 엔지니어, IBM Global Services India

2003 년 10 월 09 일

대부분의 자바 프로그래머들은 JAR 파일의 기본 작동에 익숙하다. 하지만 JAR 파일 포맷의 막강한 힘을 아는 개발자는 드물다.

JAR 파일

JAR 파일 포맷은 대중적인 ZIP 파일 포맷을 근간으로 하여 많은 파일들을 하나로 모으는데 사용된다. ZIP 파일과는 달리 JAR 파일은 압축과 디스트리뷰션 뿐만 아니라 라이브러리, 컴포넌트, 플러그인 등의 전개와 캡슐화에도 사용되며 컴파일러나 JVM 같은 툴이 직접 사용하기도 한다. 전개 디스크립터 같이 JAR에 포함된 특별한 파일은 특정 JAR가 취급되는 방법을 툴에 지시한다.

JAR 파일은 다음과 같은 데에 사용된다:

JAR 파일 포맷은 많은 혜택과 기능을 제공하며 ZIP 또는 TAR 같은 전통적인 아카이브 포맷이 줄 수 없는 많은 것들을 제공한다. 이를 테면:

JAR의 압축과 압축풀기

jar 툴(jar 참조)은 파일을 기본적으로 압축한다. 압축이 풀린 JAR 파일은 압축된 JAR 파일 보다 더 빠르게 로딩될 수 있다. 로딩 시간 동안 파일의 압축 풀기 시간이 줄어들기 때문이다. 하지만 네트워크를 통한 다운로드 시간은 압축이 풀린 파일이 더 길다.

META-INF 디렉토리

대부분의 JAR 파일에는 META-INF 디렉토리가 포함되어 있는데 이는 패키지의 저장과 보안 및 버저닝 정보 같은 확장 설정 데이터를 저장하는데 사용된다. META-INF 디렉토리의 파일과 디렉토리는 Java2platform에서 인식 및 인터프리팅되어 애플리케이션, 확장, 클래스 로더를 설정한다:

jar 툴

JAR 파일로 기본적인 태스크를 수행하려면 자바 개발 킷의 일부로 제공되는 Java Archive Tool (jar 툴)을 사용한다. jar 툴을 jar 명령어로 호출한다. 표 1은 일반 애플리케이션이다:

표 1. jar 툴의 일반적인 사용

기능 명령어
개별 파일에서 JAR 파일 만들기 jar cf jar-file input-file...
디렉토리에서 JAR 파일 만들기 jar cf jar-file dir-name
압축 풀린 JAR 파일 만들기 jar cf0 jar-file dir-name
JAR 파일 업데이트 jar uf jar-file input-file...
JAR 파일 내용보기 jar tf jar-file
JAR 파일 내용 추출하기 jar xf jar-file
JAR 파일에서 특정 파일 추출하기 jar xf jar-file archived-file...
실행 JAR 파일로 패키지된 애플리케이션 실행하기 java -jar app.jar



위로


실행 JAR 파일

실행 JAR 파일은 특별히 설정된 JAR 파일에 저장된 독립적인 자바 애플리케이션이다. 파일을 추출하거나 클래스 경로를 설정하지 않고 JVM에 의해 직접 실행될 수 있다. 비 실행 JAR에 저장된 애플리케이션을 구동하려면 이를 클래스 경로에 추가하고 애플리케이션의 메인 클래스를 이름별로 호출해야한다. 하지만 실행 JAR 파일을 사용하면 이를 추출하거나 메인 엔트리 포인트를 알 필요 없이 애플리케이션을 실행할 수 있다.

실행 JAR 파일 만들기

실행 JAR 파일을 만들기는 쉽다. 모든 애플리케이션 코드를 하나의 디렉토리에 놓는 것으로 시작한다. 애플리케이션의 메인 클래스가 com.mycompany.myapp.Sample이라고 가정해보자. 애플리케이션 코드를 포함하고 메인 클래스를 구분하는 JAR 파일 생성이 필요하다. 이를 위해 라는 manifest 파일을 어딘가에(애플리케이션 디렉토리는 아니다) 만들고 여기에 다음 행을 추가한다:


Main-Class: com.mycompany.myapp.Sample

그런 다음 JAR 파일을 다음과 같이 만든다:


jar cmf manifest ExecutableJar.jar application-dir

실행 JAR 파일 시작하기

애플리케이션을 ExecutableJar.jar라는 실행 JAR 파일로 묶었으므로 다음 명령어를 사용하여 파일에서 직접 애플리케이션을 시작할 수 있다:


java -jar ExecutableJar.jar




위로


패키지 실링(sealing)

JAR 파일안에 패키지를 봉합(sealing)한다는 것은 이 패키지에 정의된 모든 클래스가 같은 JAR 파일에서 찾아져야 한다는 것을 의미한다. 이로서 패키지 작성자는 패키지된 클래스들의 버전 영속성을 강화할 수 있다. 봉합은 보안 조치도 제공하여 코드 탬퍼링을 탐지한다.

패키지를 봉합하려면 패키지용 Name 헤더를 추가한다. 그 뒤에 Sealed 헤더 값을 JAR manifest 파일에 대해 "true"로 한다. 실행 JAR 파일과 마찬가지로 manifest 파일을 적절한 헤더 엘리먼트로 지정하여 JAR를 봉합할 수 있다:


Name: com/samplePackage/
Sealed: true

Name 헤더는 패키지의 관련 경로명을 정한다. 파일이름과 구별되도록 "/"로 끝난다. Name 헤더에 뒤따르는 모든 헤더는 공백 라인 없이 Name 헤더에 지정된 파일이나 패키지에 붙는다. 위 예제에서 Sealed 헤더가 공백 라인 없이 Name 헤더 다음에 발생했기 때문에 Sealed 헤더는 com/samplePackage 패키지에만 붙는것으로 인터프리팅된다.

확장 패키징

확장은 자바 플랫폼에 기능을 추가한다. 확장 메커니즘은 JAR 파일 포맷에 구현된다. 확장 메커니즘으로 JAR 파일이 다른 필요한 JAR 파일들을 Class-Path 헤더를 통해 manifest 파일에 지정할 수 있다.

extension1.jar와 extension2.jar가 같은 디렉토리 안의 두 개의 JAR 파일에 있다고 가정해보자. extension1.jar의 manifest는 다음 헤더를 포함하고 있다:


Class-Path: extension2.jar

이 헤더는 extension2.jar의 클래스들이 extension1.jar의 클래스를 목표에 맞춘 확장 클래스로서 작용한다는 것을 나타내고 있다. extension1.jar의 클래스들은 extension2.jar가 클랫의 경로의 일부가 될 필요 없이 extension2.jar의 클래스를 호출할 수 있다.

예를 들어 ExtensionDemo 클래스를 레퍼런싱하는 ExtensionClient 클래스가 ExtensionClient.jar라고 하는 JAR 파일에 번들되었고 ExtensionDemo 클래스가 ExtensionDemo.jar에 번들되었다고 가정해보자. ExtensionDemo.jar가 확장으로 취급되기 위해서는 ExtensionDemo.jar는 ExtensionClient.jar의 manifest 안의 Class-Path 헤더에 리스트되어야 한다:


Manifest-Version: 1.0
Class-Path: ExtensionDemo.jar




위로


JAR 파일의 보안

JAR 파일은 jarsigner 툴을 사용하거나 java.security API를 통해서 직접 서명될 수 있다. 서명된 JAR 파일은 원래 JAR 파일과 정확히 같다. manifest만이 업데이트 된 것과 두 개의 추가 파일들이 META-INF 디렉토리에 추가된 것을 제외하고.

Keystore 데이터베이스에 저장된 인증을 사용하여 JAR 파일은 서명된다. Keystore에 저장된 인증은 패스워드로 보호된다.


그림 1. Keystore 데이터베이스
Keystore Database

JAR의 각 서명자는 JAR 파일의 META-INF 디렉토리안에 있는 .SF 확장자가 붙은 서명으로 표현된다. 이 파일의 포맷은 manifest 파일과 비슷하다. 메인 섹션과 개별 엔트리들로 구성되어 있다. 서명된 JAR에서 오는 파일을 확인하기 위해 서명 파일의 다이제스트 값은 JAR 파일의 상응 엔트리에 대비하여 계산된 다이제스트와 비교된다.


Listing 1. Manifest와 서명 파일
Contents of signature file META-INF/MANIFEST.MF

Manifest-Version: 1.0
Created-By: 1.3.0 (Sun Microsystems Inc.)

Name: Sample.java
SHA1-Digest: 3+DdYW8INICtyG8ZarHlFxX0W6g=

Name: Sample.class
SHA1-Digest: YJ5yQHBZBJ3SsTNcHJFqUkfWEmI=

Contents of signature file META-INF/JAMES.SF

Signature-Version: 1.0
SHA1-Digest-Manifest: HBstZOJBuuTJ6QMIdB90T8sjaOM=
Created-By: 1.3.0 (Sun Microsystems Inc.)

Name: Sample.java
SHA1-Digest: qipMDrkurQcKwnyIlI3Jtrnia8Q=

Name: Sample.class
SHA1-Digest: pT2DYby8QXPcCzv2NwpLxd8p4G4=

디지틀 서명

디지틀 서명은 .SF 서명 파일의 서명완료된 버전이다. 디지틀 서명 파일은 바이너리 파일이며 .SF 파일과 같은 파일이름을 갖고 있지만 다른 확장이다. 확장은 디지틀 서명 유형에 따라 다양하고 (RSA, DSA, PGP). JAR 서명에 사용된 인증 유형에 따라 다르다.

Keystore

JAR 파일에 서명하려면 프라이빗 키를 가져야 한다. 프라이빗 키와 관련 퍼블릭 키 인증은 패스워드로 보호된 데이터베이스(keystores)에 저장된다. JDK는 Keystore를 구현 및 변경하는 툴을 포함하고 있다. Keystore의 각 키는 앨리어스에 의해 구분되는데 전형적으로 키를 소유한 서명자의 이름이다.

모든 Keystore 엔트리들은 고유 앨리어스로 액세스된다. 앨리어스는 Keystore에 엔터티를 추가할 때 keytool -genkey 명령어를 사용하여 지정되어 키 쌍을 만든다. 뒤따르는 keytool 명령어는 이와 같은 앨리어스를 사용하여 엔터티를 언급해야 한다.

예를 들어 "james"라는 앨리어스로 새로운 퍼블릭/프라이빗 키 쌍을 만들고 퍼블릭 키를 자가 서명된 인증으로 래핑하려면 다음 명령어를 사용한다:


keytool -genkey -alias james -keypass jamespass 
        -validity 80 -keystore jamesKeyStore 
        -storepass jamesKeyStorePass

jarsigner 툴

jarsigner 툴은 Keystore를 사용하여 JAR 파일에 대한 디지틀 서명을 만들거나 확인한다.

위 예제에서 처럼 "jamesKeyStore" Keystore를 만들었고 여기에 "james" 앨리어스와 키를 포함하고 있다고 가정해보자. 다음 명령어로 JAR 파일에 서명할 수 있다:


jarsigner -keystore jamesKeyStore -storepass jamesKeyStorePass 
          -keypass jamespass -signedjar SSample.jar Sample.jar james

이 명령어는 앨리어스가 "james"이고 패스워드가 "jamespass"인 키를 보내 Sample.jar 파일에 서명하고 SSample.jar라는 서명된 JAR를 만든다.


jarsigner -verify SSample.jar




위로


JAR 인덱싱(indexing)

애플리케이션 또는 애플릿이 다중의 JAR 파일들로 번들된다면 클래스 로더는 단순한 리니어 검색 알고리즘을 사용하여 클래스 경로의 엘리먼트를 검색한다. 클래스 로더가 존재하지 않은 리소스를 찾으려고 하면 애플리케이션 또는 애플릿 내의 모든 JAR 파일들은 다운로드 되어야한다. 큰 네트워크 애플리케이션과 애플릿의 경우 늦은 시작, 지연된 응답, 네트워크 대역 낭비를 초래한다.

JDK 1.3 이후 JAR 파일 포맷은 인덱싱(indexing)을 지원하여 네트워크 애플리케이션(특히 애플릿)의 클래스 검색 프로세스를 최적화했다. JarIndex 메커니즘은 애플릿 또는 애플리케이션에 정의된 모든 JAR 파일의 내용을 모아 첫 번째 JAR 파일의 인덱스 파일에 이 정보를 저장한다. 첫 번째 JAR 파일이 다운로드된 후에 애플릿 클래스 로더는 모아진 콘텐트 정보를 사용하여 JAR 파일을 효율적으로 다운로드한다. 이 디렉토리 정보는 INDEX.LIST라는 이름으로 간단한 텍스트 파일로 저장된다.(META-INF 디렉토리).

JarIndex 만들기


그림 2. JarIndex
JarIndex Demo

다음 명령어를 사용하여 JarIndex_Main.jar, JarIndex_test.jar, JarIndex_test1.jar용 인덱스 파일을 만든다:


jar -i JarIndex_Main.jar JarIndex_test.jar SampleDir/JarIndex_test1.jar 

INDEX.LIST 파일은 간단한 포맷을 갖고 있으며 색인된 JAR 파일에 저장된 패키지 또는 클래스 이름을 포함하고 있다.(Listing 2):


Listing 2. JarIndex INDEX.LIST 파일
JarIndex-Version: 1.0

JarIndex_Main.jar
sp

JarIndex_test.jar
Sample

SampleDir/JarIndex_test1.jar
org
org/apache
org/apache/xerces
org/apache/xerces/framework
org/apache/xerces/framework/xml4j



참고자료

출처 : http://www.ibm.com/developerworks/kr/library/j-jar/index.html



출처 : http://www.ibm.com/developerworks/kr/library/j-jar/index.html

Posted by 1010
반응형

그냥 간단하게 휴대폰 번호 검증하는 스크립트 하나 올려봅니다.

정규식을 너무 않쓰고 있는거 같아서...


// 휴대폰번호를 입력시 올바른 휴대폰 번호인지 체크 
  if(f.hphone1.value != "") {
   var rgEx = /(01[016789])[-](\d{4}|\d{3})[-]\d{4}$/g; 
   var strValue = f.hphone1.value+"-"+f.hphone2.value+"-"+f.hphone3.value;
   var chkFlg = rgEx.test(strValue);  
   if(!chkFlg){
    alert("올바른 휴대폰번호가 아닙니다.");
    f.uuser.focus();
    return false;
   }
  }
 

var rgEx = /[01](0|1|6|7|8|9)[-](\d{4}|\d{3})[-]\d{4}$/g;

굳이 풀이 하자면 [01] <- 01로 시작하고
 (0|1|6|7|8|9) <- 0 이거나 1이거나....
[-] <- - (하이폰)이고
(\d{4}|\d{3}) <- \d(숫자로 시작하는 자리수가 {4} 4자리이거나 3자리 이고
[-] < -(하이폰) 이고
\d{4} <- 숫자로 시작하는 자릿수가 4자리이여야 한다.


나머지는 뭐 설명할 필요 없겠죠....


 // 휴대폰번호 입력시 올바른 휴대폰 번호인지 체크  
  if(f.hphone1.value != "" || f.hphone2.value != "" || f.hphone3.value != "") {
   var rgEx = /[01](0|1|6|7|8|9)[-](\d{4}|\d{3})[-]\d{4}$/g; 
   var strValue = f.hphone1.value+"-"+f.hphone2.value+"-"+f.hphone3.value;
   var chkFlg = rgEx.test(strValue);   
   alert(chkFlg);
   if(!chkFlg){
    alert("올바른 휴대폰번호가 아닙니다.");
    f.hphone1.focus(); 
    return false;
   }
  }


Posted by 1010
반응형
<a href="javascript:window.external.AddFavorite('http://www.myeclipseide.com', 'J2EE IDE homepage')">Add to Favorites</a>
Posted by 1010
반응형
출처 : http://www.spoork.net/153

document.all 을 쓰지 맙시다!
document.all 을 안쓰는 것 많으로도 표준을 따르는 웹 페이지 디자인에 매우 큰 걸음을 내 딛는 것입니다.
단지 저 document.all 때문에 다른 안되는 홈페이지가 부지기수 입니다.
요즘에는 FireFox가 어쩔수 없이 지원해서 되긴합니다만, 그렇다고 그게 좋다는 것을 의미하지는 않습니다. FireFox 1.0 은 document.all 을 지원하긴 하지만 if 문으로 체크하면 지원하지 않는다고 표시합니다.
다음은 한국모질라 포럼에 올라온 글입니다.

<< 내용숨기기 >>



http://forums.mozilla.or.kr/viewtopic.php?t=580&highlight=document.all

웹사이트에서 버튼이 동작 되지 않는 경우 대부분 Javascript의 객체를 MSDOM에서 사용하는 document.all을 사용하기 때문에 그렇습니다. 자바스크립트 디버거를 통해 소스를 보았을 때 document.all 이 들어 있는 경우 document.all 대신 W3C DOM의 오브젝트 판별법을 사용하도록 웹사이트 관리자에게 알려주셔야 합니다.

document.all[objectID] -> document.getElementById("objectID")

혹시 거기에서 MS IE4 때문에 getElementById를 쓸 수 없다고 하면 getObject()를 아래처럼 정의한 후에 쓸 수 있다고 알려 주십시오.

function getObject(objectId) {
// checkW3C DOM, then MSIE 4, then NN 4.
//
if(document.getElementById && document.getElementById(objectId)) {
return document.getElementById(objectId);
}
else if (document.all && document.all(objectId)) {
return document.all(objectId);
}
else if (document.layers && document.layers[objectId]) {
return document.layers[objectId];
} else {
return false;
}
}

즉, 다음처럼 하면 됩니다.

getObject('sendbn').style.visibility="hidden";

getObject는 http://www.orient-express.com/js/layers.inc 에 있습니다.

혹은 다음에 있는 'x library'를 쓰는 것도 좋은 방법입니다. http://www.cross-browser.com
Posted by 1010
반응형

출처 : http://blog.daum.net/computercode/8281294

자바스크립트로 location.href 로 이동해야 하는 경우가 있는데 이때 새창을 띄워서 쓰는 방법이 필요한 경우가 있다. 그냥 프레임이나 브라우저 창간의 계층구조인 경우에는

opener.location!.href = "http://...";

혹은

frame1.location!.href = "http://...";

이런 방법으로 사용하면 된다.
이런것도 아니고 무조건 새창을 열고 띄우는 경우는 다음과 같다.

var openNewWindow = window.open("about:blank");
openNewWindow.
location.href = "http://...";


Posted by 1010
반응형

-----------test.jsp---------------------

<form name="frmHidden" method="post" action="counselingfaq_list.jsp">
 <input type="hidden" name="seq" value="<%=Seq%>">
 <input type="hidden" name="pageNo" value="<%=pageNo%>">
 <input type="hidden" name="pageVol" value="<%=pageVol%>">
</form>


<script>
alert('정상적으로 삭제  되었습니다.');
document.frmHidden.submit();
</script>


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


test.jsp 페이지가 EE에서는 잘 이동하는데 FF 에서는 안먹는다...

페이지에 구조가 만들어 지지 않아서 스크립트가 제대로 동작 하지 못한다.

다시 한번 웹표준을....맞춰야 겠다는 생각이 든다.

<html>

<head></head>

<body>

</body>

</html>

 

Posted by 1010
반응형
파이어폭스에서 javascript 시 this.value 가 않먹을때

onClick ="search(this.value)";

로 하면 EF 에서는 잘 먹는데 FF 에서는 잘 먹지 않는데..

this.value 는 document.all 로 찾는다

document.all 는 ms dom api 이기 때문에 FF에서는 지원하지 않고 표준도 아니기 때문에...

document.getElementsByName 형식으로 찾아줘야 함.

글구 return false 도 써주삼... 이미지 형식에 onClick 이벤트를 줄때..


 onclick="search(document.getElementsByName('sWord').item(0).value,1);return false;"

Posted by 1010
06.Ajax2009. 8. 26. 10:39
반응형
출처 : http://hmkang.com/v2.0/hmblog/web/1961

Ajax 한글 파라미터 보내기

XMLHttpRequest 는 전송시

[meta http-equiv="content-type" content="text/html; charset=euc-kr" /]

위에 처럼 euc-kr 이 지정되어 있더라도 설정된 인코딩을 사용하지 않는다
따라서 한글일경우 자바스크립트에서 직접 인코딩해주어야 한다 (불편하다! -0-)
자바스크립트에서 escape함수와 encodeURIComponent 함수를 지원해 주는데 escape은 유니코드로, encodeURIComponent는 utf-8로 인코딩 된다

고로 보내기전 인코딩하고 받는 쪽에서도 인코딩 하면 한글문제는 일어나지 않는다

보내는쪽
utf-8 'list.jsp?search='+encodeURIComponent('홍길동')

받는쪽
request.setCharacterEncoding("utf-8");
request.getParameter("search");

Ajax에서 전송시 GET, POST 방식 모두 동일하게 처리해 주면 된다

출처 : Tong - janus94님의 IT통
Posted by 1010
반응형
출처 : http://www.apache-korea.org/ant/external.html
외부의 도구과 태스크

이 페이지는, 아파치 앤트용 외부 자료의 목록입니다: 태스크, IDE 통합 도구, 로거 입니다. 앤트에 포함되었으면 하는 것을 작성하였다면, 메일 목록 중 하나에다가 관련 정보를 보내주세요.

여기 나오는 것은, 모두 앤트 개발자들이 직접 지원하고 있는 것이 아닙니다. 무엇인가 문제가 발생할 경우에는, 연락처의 정보를 이용해 주세요.

태스크
AJC

AspectJ 는 자바의 형태를 지향하는 확장모델입니다. 이 태스크는 AspectJ 컴파일러 -- AJC 를 사용하여 소스 트리를 컴파일합니다.

적합한 버전: 앤트 1.3
URL: http://aspectj.org/dl
연락처: support@aspectj.org
라이센스: Apache Software 라이센스
Anakia

확실히, Anakia 는, JDOM, Velocity 와 앤트에 기반을 둔 XML 변환도구로, 앤트 태스크보다 더 좋습니다.

적합한 버전: 앤트 1.2 이상
URL: http://jakarta.apache.org/velocity/anakia.html
연락처: Velocity mailing lists
라이센스: Apache Software 라이센스
Anteater

Anteater 는 웹사이트와 웹서비스를 기능면에서 테스트(기능면에서 테스트하는 것이란; URL에 접속하여 올바른 반응이 돌아오는지 점검한다)하는 앤트 태스크의 집합입니다. HTTP params, response codes, XPath, regexp 과 Relax NG 표현들을 테스트할 수 있습니다. HTML 보고서(junitreport에 기반을 둔)와, 대량의 테스트 스크립트를 재빨리 처리하기 위한 계층적인 그룹 체계를 제공합니다.

적합한 버전: 앤트 1.5 이상
URL: http://aft.sourceforge.net
연락처: developer mailing list
라이센스: Apache Software 라이센스
Checkstyle

Checkstyle 은 일반적인 코딩을 덧붙여, 자바 코드를 작성하는 프로그래머를 도와주는 개발 도구입니다. 이것은, 자바 코드를 점검하는 과정을 자동화하고, 따분한(하지만 중요한) 태스크를 사람이 편하게 다룰 수 있도록 하는 것이 목적입니다.

Checkstyle 은 앤트 태스크나 커맨드 라인 유틸리티를 통해 사용할수 있습니다.

적합한 버전: 앤트 1.2부터 1.4.1까지
URL: http://checkstyle.sourceforge.net/
연락처: Oliver Burn
라이센스: 2.0 배포시에는 GNU Lesser General Public 라이센스. 이전의 배포판은 GNU General Public 라이센스입니다.
CleanImports

필요없는 import들을 제거합니다. import 부분의 체계를 다시 잡습니다. 분명치 않은 import 들은 표시를 해둡니다.

적합한 버전: 앤트 1.3
URL: http://www.euronet.nl/users/tomb/cleanImports/index.html
연락처: Tom Brus
라이센스: Apache Software 라이센스
Clover

Clover 는 앤트-기반의 코드 보호 도구입니다. 이것은, 앤트-기반의 프로젝트로 잘 사용되고 있습니다. 이것은, 메소드, 문장, 그리고 브렌치(branch)보호 분석기 를 제공하고, XML, HTML 이나 Swing GUI 를 통한 보고서 기능를 가지고 있습니다.

적합한 버전: 앤트 1.4.1 이상
URL: http://www.thecortex.net/clover
연락처: clover-support@cortexebusiness.com.au
라이센스: 상업용, 오픈 소스 프로젝트로는 무료(free) 라이센스가 가능합니다.
Configure

소스와 출력을 분리시켜, 반복되는 빌드기능(모든 패키지 등급에 대해서 앤트를 호출하고, 그 패키지에 있는 파일만 빌드하거나, 그 패키지 하위의 모든 것을 빌드합니다)을 제공합니다.

이 태스크는 임의의 하위디렉토리(CVS-디렉토리를 제외하고)에 빌드 파일을 생성합니다. 최상위에 build.xml 파일 하나만 위치시키고, 'setup' 이나 'rescan' 타겟을 호출합니다.

적합한 버전: 앤트 1.2 과 1.3
URL: http://www.dsdelft.nl/~lemval/ant/
연락처: M.J.P. van Leeuwen
라이센스: Apache Software 라이센스에서 유래된 라이센스
CVSGrab

방화벽 아래의 지역에서 cvs 로 의사소통을 할 때, 유용하게 사용할 수 있는 작은 CVS client 입니다. 이것은, 표준 http 을 통해 CVS 저장소에 접근하는 ViewCVS 웹 인터페이스를 사용하고, 그 곳에 존재하는 모든 파일을 내려받기합니다.

커맨트 라인이나 앤트 태스크로 작동합니다.

적합한 버전: 앤트 1.3 이상
URL: http://cvsgrab.sourceforge.net/
연락처: CVSGrab user mailing list
라이센스: LGPL
Doxygen task

Doxygen 문서 체계를 작동하기 위한 2가지의 앤트 태스크가 있습니다.

적합한 버전: 앤트 1.1 이상
URL: http://www.bgw.org/projects/java/ant/
연락처: Kyle R. Burton
라이센스: Apache Software Foundation 라이센스

그리고

적합한 버전: 앤트 1.5 이상
URL: http://ant-doxygen.sourceforge.net
연락처: Karthik A Kumar
라이센스: Apache Software Foundation 라이센스
GenJar

단순한 디렉토리의 내용보다 좀 더 의존관계가 있는 클래스에 기반을 둔, JAR파일을 빌드합니다.

적합한 버전: 앤트 1.4 알파 (2001/08/04 후에 빌드된) 이상
URL: http://genjar.sourceforge.net/
연락처: Jesse Stockall
라이센스: Apache Software Foundation 라이센스
Importscrubber

자바 소스 코드 파일에서 불필요한 import 문장을 제거합니다.

적합한 버전: 앤트 1.3
URL: http://importscrubber.sourceforge.net/
연락처: Tom Copeland
라이센스: LGPL
IsDirValidator

주어진 디렉토리 구조가, 태스크의 내부 요소를 거쳐 정의된 특정한 법칙에 따르는지 검사합니다.

적합한 버전: 앤트 1.4
URL: http://isvalidator.sourceforge.net/en/isDirValidator.htm
연락처: I?igo Serrano
라이센스: GNU General Public 라이센스
Jalopy

낡은 자바 소스 코드 형식을 위한 앤트 플러그-인 입니다.

적합한 버전: 앤트 1.4 (또는 이상)
URL: http://jalopy.sourceforge.net
연락처: http://jalopy.sf.net/contact.html
라이센스: 1.0 베타 6 배포시에는 BSD 라이센스. 이전의 배포판은 GNU General Public 라이센스입니다.
Javamake

자바 소스를 컴파일하고 클래스 파일의 의존관계를 관리하는 태스크입니다. 기능적으로는, 평범한 Javac 와 의존하는 태스크를 합쳐 놓은 기능과, 향상된 의존관계 체크기능을 가지고 있습니다.

적합한 버전: 앤트 1.4.1
URL: http://www.experimentalstuff.com/Technologies/JavaMake/index.html
연락처: Mikhail Dmitriev
라이센스: BSD와 유사한 라이센스
J2ME Ant Tasks

Java 2 Platform, Micro Edition (J2ME) 애플리케이션의 빌드를 도와주는 2가지의 다른 태스크 집합입니다.

이 집합은 CLDC 와 K Virtual Machine (KVM)을 지원합니다:

적합한 버전: 앤트 1.3
URL: http://www.dribin.org/dave/j2me_ant/
연락처: Dave Dribin
라이센스: Apache Software 라이센스

그리고 이 집합은 J2ME Wireless Toolkit 과 PalmOS의 MIDP에서 작동합니다:

적합한 버전: 앤트 1.3
URL: http://www.stampysoft.com/ant/
연락처: Josh Eckels
라이센스: MIT 라이센스
javarec

코볼(cobol) 복사 도서의 자바를 위한 VisualAge에게, 기록(record) 클래스들을 생성하는 앤트 태스크입니다.

적합한 버전: 앤트 1.4
URL: http://glezen.org/javarec/
연락처: Paul Glezen
라이센스: Apache Software 라이센스
Jing Task

XML 파일을 RELAX NG 와 XML Schema로 둘로 나누어 구분합니다. 앤트의 Jing task 는, 여러 파일에서 여러 RELAX NG 패턴을 효과적으로 구분하는 것을 허락하고, 다른 XML 처리법을 가지고 RELAX NG 구분자를 통합시킵니다.

적합한 버전: 앤트 1.4 이상
URL: http://www.thaiopensource.com/relaxng/jing-ant.html
라이센스: BSD와 유사한
jMetra

jMetra 는, 프로젝트의 생명주기를 측정한 코드를 수집하고, 초과시간을 측정하는 프로젝트를 분석한 JavaDoc-형식의 문서 결과를 컴파일하는 도구입니다. jMetra 는 프로젝트의 빌드 처리를 계획을 통합하는 최고의 유틸리티입니다.

이것은, 커맨트라인이나 제공된 여러 앤트 태스크를 사용하여 작동합니다.

적합한 버전: 앤트 1.4 이상
URL: http://www.jmetra.com/
연락처: R Todd Newton
라이센스: 상업용, 오픈 소스 프로젝트나 개발용으로는 무료(free) 라이센스가 가능합니다
JNI

JNI 는, Java Native Interface (JNI)를 통해 자바와 C 를 통합하는 일을 쉽게 만드는, 무료 도구모음입니다. 이것은, 자바 "proxy" 클래스로 C "peer" 클래스에 접근하고, C "proxy" 클래스로 자바 "peer" 클래스나 인터페이스에 접근하도록 양쪽 모두를 생성하는 코드생성기를 포함하고 있습니다. 이것은 또한, JNI 데이터 형을 쉽게 작동할 수 있게 하는, "helper" 클래스와 같은 단순화된 JVM 인터페이스의 코어(core) 라이브러리도 포함하고 있습니다. 코드 생성기는, GUI 프로젝트 매니저의 보조로 생성할 수 있는 XML 프로젝트 파일로 운영됩니다. 코드 생성기는 앤트나 GUI 로 작동할 수 있습니다. 인쇄가능한 많은 PDF 사용자 가이드와 많은 수의 예제를 포함하고 있습니다.

적합한 버전: 앤트 1.4
URL: http://jnipp.sf.net/
연락처: Phillip E. Trewhella
라이센스: GNU LGPL
Macker

빌드-시간 을 체계적으로 테스트하는 도구로서, 깔끔한 layering / tiering / modularity 으로 설계되었습니다. Macker 는 컴파일된 클래스 파일들에 대하여, XML 규칙(rules) 파일에서 당신의 프로젝트를 지정한 패턴-기반의 접근 규칙의 집합에 관한, 클래스들의 의존관계를 검사합니다.

적합한 버전: 앤트 1.5 이상 (1.4 는 테스트되지 않았지만 작동할 것입니다.)
URL: http://innig.net/macker/
연락처: Paul Cantrell
라이센스: GNU GPL 2.0
PMD

PMD 는 사용되지 않는 변수, 필요없는 오브젝트 생성, 등을 자바 소스에서 검사합니다.

적합한 버전: 앤트 1.4 이상
URL: http://pmd.sf.net/
연락처: Tom Copeland
라이센스: Apache Software Foundation 라이센스
Styler

styler 태스크는, 지정한 앤트 빌드 파일을, 간단하게 유용한 XSLT 변형물(transformation)의 결합으로 만듭니다. 내장 앤트 태스크 스타일 같은 것들을, styler 는 하나의 XML 파일 집합의 변형물로 만들수 있습니다. 또한 다음과 같은 것들을 할수 있습니다:

  • parallel 과 pipeline 에서, 복수의 변형물을 취급합니다.
  • 분할 / 결합 파일들을 변형물로 만들 수 있습니다.
  • XML 파일이 아닌 것들을 처리합니다, 특히 HTML (JTidy 에 기반함)
  • XSLT 변형물이 아닌 것을 적용합니다, 특히 "평범한 fragmentations"
  • 새로운 파일 포맷과 변형물 기술을 취급하는, 사용자정의 XMLReader 나 XMLFilter 를 사용합니다.
적합한 버전: 앤트 1.4
URL: http://www.langdale.com.au/styler/
연락처: Arnold deVos
라이센스: LGPL
Tidy Imports (Tim)

Tim 은 import 선언문을 자동적으로 구성해 주는, 커맨드 라인이나 앤트를 거쳐 실행될 수 있는 유틸리티입니다. Tim 은, 사용되지 않는 import를 제거하고, import 를 늘리거나 합치고, 그것들을 미리-결정된(pre-determined) 그룹에 조직화 시킬 수 있습니다.

적합한 버전: 앤트 1.3 이상
URL: http://www.chive.com/tim.htm
연락처: support@chive.com
라이센스: 상업용
TiniAnt

TiniAnt 는, TINI를 위한 애플리케이션을 빌드하는 방법을 지원하는 앤트 태스크입니다.

적합한 버전: 앤트 1.2부터 1.4.1까지
URL: http://tiniant.sourceforge.net/
연락처: Sean Kelly
라이센스: BSD와 유사한 라이센스
Venus Application Publisher's (Vamp) Ant Task Suite

웹 서버를 한 번의 클릭으로 Java Web Start 를 가동시키고, 하나의 Java Archive installer로, 내장, 다중-쓰레드, 가벼운 웹서버에 대한 내용으로 서버를 업데이트 시키는 기능의, Web Archive 들을 당신의 애플리케이션에 표시하고 패키지할 수 있도록 지원합니다.

적합한 버전: 앤트 1.2 과 1.3
URL: http://www.geocities.com/vamp201/ant.html
연락처: Gerald Bauer
라이센스: GNU General Public 라이센스
WOProject

WOProject 는, 플랫폼과 IDE에 독립적인 WebObjects 5.1 과 함께 작동하는 도구 모음을 제공합니다. 이것의 주요 기능은, 개발자의 생산성을 증가시키고, 전통적인 Makefile-기반의 접근법(approach)와 비교하여 복잡한 프로젝트 구조를 좀 더 유연하게 만드는 것입니다.

적합한 버전: 앤트 1.4
URL: http://objectstyle.org/woproject/
연락처: Andrus Adamchik
라이센스: Apache 라이센스
XDoclet

XDoclet 은 Javadoc Doclet 엔진을 앤트에서 사용하기 위해서, Javadoc Doclet 엔진을 확장시킵니다. 이것은, 사용자정의 Javadoc @tags 를 작성하고, 그 tags에 기반하여 소스 코드나 다른 파일들을 생성합니다(xml틱한 배치(deployment ) 설명자같은 것들). 템플릿과 적합한 태스크들은, EJB 과 웹 애플리케이션 배치 설명자를 생성하는 것을 제공합니다.

적합한 버전: 앤트 1.4
URL: http://sourceforge.net/projects/xdoclet/
라이센스: BSD 라이센스
XmlTask

XmlTask 는, XSLT를 배울 필요없이 XML 문서를 수정하는 단순한 방법을 제공합니다. 경로는 단순하게 변경하길 원하는 노드(node)를 지정한 XML 노드를 참조하고, XML 삽입이나 제거, 또는 속성 변경을 허락하는 방법을 당신에게 알려줍니다. 강조합니다만, 이것은 일반적인 XML 변경을 수행하는 지극히 단순한 방법을 제공합니다.

적합한 버전: 앤트 1.4 이상
URL: http://www.oopsconsultancy.com/software/xmltask.html
연락처: xmltask@oopsconsultancy.com
라이센스: GNU General Public 라이센스
컴파일러 계승체(Implementations)
miniRMI <rmic> implementation

miniRMI 는, java.rmi 원본 패키지를 경량으로 대체하는, 특히 애플릿에 적합한 무료 공개소스 라이브러리입니다. 앤트 1.4+ <rmic> 어댑터에 포함되어 있습니다.

적합한 버전: 앤트 1.4 이상
URL: http://dione.zcu.cz/~toman40/miniRMI/
연락처: Petr Toman
라이센스: Gnu Lesser Public 라이센스
IDE 나 에디터와의 통합
AntFarm

jEdit 에디터에 앤트를 통합시키는 플러그인입니다.

적합한 버전: 앤트 1.3 때 나옴
URL: http://plugins.jedit.org/plugins/AntFarm
연락처: jEdit developers mailinglist
라이센스: Apache Software 라이센스
AntMan

JDeveloper IDE와 앤트를 통합시키는 AddIn 입니다.

적합한 버전: 앤트 1.4.1
URL: http://www.erudra.com/antman/index.html
연락처: Ashok Sridhar
라이센스: GNU General Public 라이센스
AntRunner

JBuilder IDE에 앤트를 통합시키는 공개도구입니다.

적합한 버전: 앤트 1.2 과 1.3
URL: http://www.dieter-bogdoll.de/java/AntRunner/
연락처: Dieter Bogdoll
라이센스: GNU General Public 라이센스
AntWork

Jext 에디터에 앤트를 통합시키는 플러그인입니다.

적합한 버전: 앤트 1.2 과 1.3
URL: ftp://jext.sourceforge.net/pub/jext/plugins/AntWork.zip
연락처: Klaus Hartlage
라이센스: GNU General Public 라이센스
Eclipse

Eclipse 는 앤트와 통합한 세계적인 도구 플랫폼입니다.

적합한 버전: 앤트 1.3 - 1.4.1
URL: http://www.eclipse.org
연락처: news://news.eclipse.org/eclipse.tools
라이센스: Common Public 라이센스 버전 1.0
IntelliJ IDEA 2.0

Java IDE 는 리팩토링(refactoring) 지원과 앤트 통합기능을 가지고 있습니다.

적합한 버전: Ant 1.3 때 나옴
URL: http://www.intellij.com/idea/
연락처: support@intellij.com
라이센스: 상업용
JDE(E) 2.2.8

Emac 을 위한 자바 개발 환경(JDEE)은 애플리케이션을 빌드하기 위한 세가지 내장 방법 중 하나로 아파치 앤트를 지원합니다.

적합한 버전: 앤트 1.2 이상
URL: http://jde.sunsite.dk/
연락처: JDEE Mailing list.
라이센스: GNU General Public 라이센스
NetBeans / Sun ONE Studio

NetBeans 나 Sun ONE Studio (이전에는 Forte for Java) IDE 에 앤트를 통합하는 모듈입니다.

적합한 버전: Ant 1.4.1 때 나옴
URL: http://ant.netbeans.org/
연락처: nbdev@netbeans.org
라이센스: Sun Public 라이센스
HP RadPak

RadPak 는 (무료) HP Bluestone HPAS J2EE 서버에서, 자바 웹과 EJB애플리케이션을 WAR나 EAR파일들처럼 패키지화하고 배치시키는 것을 주목적으로하는 GUI 도구입니다. 이 도구는 앤트 기반으로, 보통 앤트의 개발, 태스크 속성의 입력(entry)을 형식에 맞추기, 태스크가 실행되는 모습을 애니메이션화하여 보여주기 를, GUI 처럼 사용할 수 있습니다.

적합한 버전: 앤트 1.3 과 docs 때 나옴; 앤트가 설치된 ANT_HOME 아래에 부가적인 태스크들의 jar를 추가하세요.
URL: http://www.bluestone.com/products/hp-as/
라이센스: 특허가 있음, 그러나 내려받기는 무료
WebSphere Studio Application Developer

WSAD 는, Eclipse 도구 플랫폼상에서 빌드하는 능력으로 앤트와 통합하는 기능입니다.

적합한 버전: 앤트 1.4.1 때 나옴
기사: Ant Integration Part1
라이센스:
Posted by 1010
56. Eclipse Etc.../Eclipse2009. 8. 25. 17:34
반응형

Overview

The source code beautifier originally built by Marco Hunsicker and enhanced for Java 5 by Steve Heyns.

This version is NOT the same as the version at TRIEMAX. For information about the commercial version click here

An updated manual will (hopefully) be available soon

Please refer to this documentfor a complete list of features.

Versions

Latest version available for download is 0.3.1. It works with Eclipse 3.0, and should also with 2.x stream builds. Also please note that the PDE Plugin doesnot support OSGI Bundles yet.

Installing

Download the appropiate plugins for installing the code from the sub-projects listed on the menu to the left

Posted by 1010
56. Eclipse Etc.../Eclipse2009. 8. 25. 17:34
반응형

Overview

The source code beautifier originally built by Marco Hunsicker and enhanced for Java 5 by Steve Heyns.

This version is NOT the same as the version at TRIEMAX. For information about the commercial version click here

An updated manual will (hopefully) be available soon

Please refer to this documentfor a complete list of features.

Versions

Latest version available for download is 0.3.1. It works with Eclipse 3.0, and should also with 2.x stream builds. Also please note that the PDE Plugin doesnot support OSGI Bundles yet.

Installing

Download the appropiate plugins for installing the code from the sub-projects listed on the menu to the left

Posted by 1010
56. Eclipse Etc.../Eclipse2009. 8. 25. 17:21
반응형

이 글에서는 "5대" 코드 분석 영역에 대해 설명하겠다.

  • 코딩 표준
  • 코드 중복
  • 코드 커버리지
  • 의존성 분석
  • 복잡성 모니터링

이러한 분석 영역들은 다음과 같은 Eclipse 플러그인을 사용한다.

  • CheckStyle: 코딩 표준
  • PMD의 CPD: 코드 중복 발견
  • Coverlipse: 코드 커버리지 측정
  • JDepend: 의존성 분석 제공
  • Eclipse Metrics 플러그인: 복잡성 탐지


표 1. 코드 향상 플러그인과 설치 URL 리스트
목적 Eclipse 플러그인 URL
CheckStyle 코딩 표준 분석 http://eclipse-cs.sourceforge.net/update/
Coverlipse 코드 커버리지 테스트 http://coverlipse.sf.net/update
CPD Copy/Paste 탐지 http://pmd.sourceforge.net/eclipse/
JDepend 패키지 의존성 분석 http://andrei.gmxhome.de/eclipse/
Metrics Complexity monitoring http://metrics.sourceforge.net/update

Posted by 1010
01.JAVA/Java2009. 8. 25. 09:58
반응형

출처 : http://fendee.egloos.com/8682738

윤년이 되려면,

1.연도가 4 로 나누어 떨어질것
2.단, 100으로 나누어 떨어지는 해는 제외한다.
3.400으로 나누어 떨어지는 해는 윤년이다.

이것을 공식으로 처리하면,(변수 year 는 연도)

(year % 4 == 0 && year % 100 !=0) || (year % 400 == 0)

현재 년도를 year 에 대입한후, 위 식의 값이 true 이면 윤년이고, false 이면 윤년이 아니다.


java.util.Calendar 를 이용한, 날짜 출력 및 윤년계산

<a.java>


import java.io.*;
import java.util.*;
import java.util.Calendar;

public class a
{
  public static void main(String [] args)
  {
    Date today = new Date();
    System.out.println(today);

    Calendar cal = Calendar.getInstance();
   
    int year = cal.get(cal.YEAR);  //YEAR 는 모두 대문자로 써야한다.
    // 또는 cal.get(Calendar.YEAR);
    int year2 = cal.get(Calendar.YEAR);
    System.out.println("다른 방식:" + year2);
   
    System.out.println(year);
    int mont = cal.get(cal.MONTH) + 1;  //MONTH 는 모두 대문자로 써야한다.(월에는 1을 더해줘야 한다.)
    System.out.println(mont);
    int dat = cal.get(cal.DATE); //DATE 는 모두 대문자로 써야한다.
    System.out.println(dat);
           
    System.out.println("오늘은 " + year + "년 " + mont + "월 " + dat + "일 입니다");
   
    int weeknum = cal.get(cal.DAY_OF_WEEK);
    String weekstr = "00";
    switch(weeknum){
      case 1 : weekstr = "일"; break;
      case 2 : weekstr = "월"; break;
      case 3 : weekstr = "화"; break;
      case 4 : weekstr = "수"; break;
      case 5 : weekstr = "목"; break;
      case 6 : weekstr = "금"; break;
      case 7 : weekstr = "토"; break;
    }
    System.out.println(weekstr + "요일");
   
    int hour = cal.get(cal.HOUR);
    int min = cal.get(cal.MINUTE);
    int sec = cal.get(cal.SECOND);
    String thistime = hour + ":" + min + ":" + sec;
   
    System.out.println("현재시각은 " + thistime + " 입니다");
   
   
    //(year % 4 == 0 && year % 100 !=0) || (year % 400 == 0)
    if((year % 4 == 0 && year % 100 !=0) || (year % 400 == 0)){
      System.out.println("올해는 윤년입니다");
    }else{
      System.out.println("올해는 윤년이 아닙니다");
    }
  }
}



첨부파일: 20090303(tue)-calendar_util.zip
Posted by 1010