프로그램의 세계에서도 이미 제공되어 있는 것을 그대로 사용할 수 없을 때, 필요한 형태로 교환하고 사용하는 일이 자주 있습니다. '이미 제공되어 있는 것'과 '필요한 것' 사이에 '차이를 없애주는 디자인 패턴이 Adapter 패턴 입니다.

 

Adapter 패턴은 Wrapper 패턴으로 불리기도 합니다. wrapper는 '감싸는 것'이라는 의미를 가지며, 무엇인가를 한번 포장해서 다른 용도로 사용할 수 있게 교환해 주는 것이 wrapper 이며 adapter입니다.

 

Adapter 패턴에는 두 가지 종류가 있다.

  • 클래스에 의한 Adapter 패턴(상속을 사용한 Adapter 패턴)
  • 인스턴스에 의한 Adapter 패턴(위임을 사용한 Adapter 패턴)

 

예제 프로그램 (1) : 상속을 사용한 Adapter 패턴

지금 Banner 클래스에는 문자열을 괄호로 묶어서 표시하는 showWithParen 메소드와 문자열 전후에 *를 붙여 표시하는 showWithAster 메소드가 준비되어 있습니다. 이 Banner 클래스를 '이미 제공되어 있는 것'이라고 가정합니다.

 

한편 Print 인터페이스에서는 문자열을 느슨하게(괄호 사용) 표시하기 위한 printWeak 메소드와 문자열을 강하게 (* 표시를 앞뒤에 붙여 강조) 표시하기 위한 printString 메소드가 선언되어 있다고 가정합니다.  지금 하고 싶은 일은 Banner 클래스를 사용해서 Print 인터페이스를 충족시키는 클래스를 만드는 일입니다.

 

PrintBanner 클래스가 어댑터의 역할을 담당합니다. 이 클래스는 제공되어 있는 Banner 클래스를 상속해서, 필요로 하는 Print 인터페이스를 구현합니다. PrintBanner 클래스는 showWithParen 메소드를 사용해서 printWeak를 구현하고, showWithAster 메소드를 이용해서 printString 메소드를 구현합니다. 이것으로 PrintBanner 클래스는 어댑터의 기능을 완수하게 됩니다.

 

예제 1.  Banner 클래스(Banner.java)

  1. package Adapter;

    public class Banner {
        // Banner 클래스는 미리 제공되는 클래스라고 가정.
        private String string;
        public Banner(String string){
            this.string = string;
        }

        public void showWithParen(){
            System.out.println("(" + string + ")");
        }
       
        public void showWithAster(){
            System.out.println("*" + string + "*");
        }
    }

 

예제 2. Print 인터페이스(Print.java)

  1. package Adapter;

    public interface Print {
        public abstract void printWeak();
        public abstract void printStrong();
    }

 

예제 3. PrintBaner 클래스(PrintBanner.java)

  1. package Adapter;

    public class PrintBanner extends Banner implements Print {
       
        public PrintBanner(String string){
            super(string);
        }
       
        public void printWeak(){ // 인터페이스 Print.printWeak() 구현
            showWithParen();
        }
       
        public void printStrong(){ // 인터페이스 Print.printString() 구현
            showWithAster();
        }

    }

 

예제 4. PrintBannerMain 클래스(PrintBannerMain.java)

  1. package Adapter;

    public class PrintBannerMain {
        public static void main(String[] args){
            Print p = new PrintBanner("Hello");
            p.printWeak();
            p.printStrong();
        }
    }

 

실행결과

PrintBannerMain.JPG

 

PrintBannerMain 클래스 내에서 PrintBanner의 인스턴스를 Print 인터페이스형의 변수로 대입하는 것에 주의해야 한다. 이 PrintBannerMain는 어디까지나 Print라는 인터페이스를 사용해서 프로그래밍을 하고 있다. Banner 클래스나 showWithParen 메소드나 showWithAster 메소드는 Main 클래스의 소스 코드상에서는 완전히 감추어져 있다.

 

PrintBannerMain는 PrintBanner 클래스가 어떻게 실현되고 있는지를 모른다. 실행되는 것을 모른다는 것은 PrintBannerMain 클래스를 전혀 변경하지 않고 PrintBanner 클래스의 구현을 바꿀 수 있다는 것이다.

 

예제 프로그램 (2) : 위임을 사용한 Adapter 패턴

이전 예제 프로그램(1)은 '클래스에 의한' Adapter 패턴이었습니다. 이번에는 '인스턴스에 의한' Adapter 패턴을 살표봅시다. 예제 프로그램 (1)에서는 '상속'을 사용했지만, 이번에는 '위임'을 사용한다. (위임과 관련된 내용 링크)

 

PrintBannerMain 클래스, Banner 클래스는 예제 프로그램(1)과 동일합니다. 그러나 Print2는 인터페이스가 아니고 클래스라고 가정합니다. 즉, Banner 클래스를 이용해서 Print2 클래스와 동일한 메소드를 갖는 클래스를 실현하려는 것입니다. Java 에서는 2 개의 클래스를 동시에 상속할 수 없기 때문에(단일 상속), PrintBanner2 클래스를 Print와 Banner 모두의 하위 클래스로 정의할 수 없습니다.

 

PrintBanner2 클래스는 banner 필드에서 Banner 클래스의 인스턴스를 가집니다. 이 인스턴스는 PrintBanner2 클래스의 생성자에서 생성합니다. 그리고 printWeak 및 printStrong 메소드에서는 banner 필드를 매개로 showWithParen, showWithAster 메소드를 호출합니다.

 

이전 예에서는 자신의 상위 클래스에서 상속한 showWithParen, showWithAster 메소드를 호출하고 있지만, 이번에는 필드를 경유해서 호출하고 있습니다.

 

PrintBanner2 클래스의 printWeak 메소드가 호출되었을 떄, 자신이 처리하는 것이 아니라 별도의 인스턴스인 showWithParen 메소드에게 위임하고 있습니다.

 

예제 4. Print2 클래스(Print2.java)

  1. package Adapter;

    public abstract class Print2 {
        public abstract void printWeak();
        public abstract void printStrong();
    }

 

예제 5. PrintBanner2 클래스(PrintBanner2.java)

  1. package Adapter;

    public class PrintBanner2 extends Print2 {
        private Banner banner; // Banner 를 위임하여 받음
       
        public PrintBanner2(String string){
            this.banner = new Banner(string);
        }

        public void printWeak(){
            banner.showWithParen();
        }
       
        public void printStrong(){
            banner.showWithAster();
        }
    }

 

예제 6. PrintBannerMain2 클래스(PrintBannerMain2.java)

  1. package Adapter;

    public class PrintBannerMain2 {
        public static void main(String[] args){
            Print2 p = new PrintBanner2("Hello");
            p.printWeak();
            p.printStrong();
        }
    }

 

Adapter 패턴의 등장인물

  • Target(대상)의 역할
    지금 필요한 메소드를 결정합니다. 노트북을 작동시키기 위한 직류 12볼트에 해당합니다. 예제 프로그램에서는 Print 인터페이스(상속)나 Print 클래스(위임)가 이 역할을 합니다.

 

  • Client(의뢰자)의 역할
    Target 역할의 메소드를 사용해서 일을 합니다. 직류 12볼트로 움직이는 노트북에 해당합니다. 예제 프로그램에서는 PrintBannerMain 클래스가 이 역할을 수행합니다.

 

  • Adaptee(개조되는 쪽)의 역할
    Adapt-er(개조하는 쪽)가 아니고 Adapt-ee(개조되는 쪽)입니다. Adaptee는 이미 준비되어 있는 메소드를 가지고 있는 역할입니다. 교류 100볼트의 AC 전원에 해당되며, 예제 프로그램에서는 Banner 클래스가 이 역할을 합니다. 이 Adaptee역의 메소드가 Target 역할의 메소드와 일치하면(노트북 사용 전압과 가정에 공급되는 전압이 같다면 어답터가 필요 없음) 다음 Adapter의 역할은 필요없습니다.

 

  • Adapter 의 역할
    Adapter 패턴의 주인공이니다. Adaptee 역할의 메소드를 사용해서 어떻게든 Target 역할을 만족시키기 위한 것이 Adapter 패턴의 목적이며, Adapter 역할의 임무입니다. 예제 프로그램에서는 PrintBanner 클래스가 Adapter의 역할을 합니다.

    클래스에 의한 Adapter 패턴의 경우에는 Adapter의 역할은 '상속'을 사용한 Adaptee의 역할을 이용하지만, 인스턴스에 의한 Adapter 패턴의 경우에는 '위임'을 사용한 Adaptee의 역할을 이용합니다.

 

버전 업과 호환성

소프트웨어는 버전 업이 필요합니다. 소프트웨어를 버전 업할 때는 '구 버전과 호환성'이 문제가 됩니다. 구 버전을 버리면 소프트웨어의 유지와 보수는 편하지만 항상 그것이 가능할 순 없습니다. 구 버전을 버리면 소프트웨어의 유지와 보수는 편하지만 항상 그것이 가능할 순 없습니다. 구 버전과 신 버전을 공존시키고, 유지와 보수도 편하게 하기 위해서 Adapter 패턴이 도움이 되는 경우가 있습니다. 예를 들어 앞으로는 신 버전만 유지와 보수를 하고 싶을 때 신 버전을 Adaptee 역할로 하고, 구 버전을 Target 역할로 합니다. 그리고 신 버전의 클래스를 사용해서 구 버전의 메소드를 구현하는 Adpater 역할의 클래스를 만듭니다. 

 

관련 패턴

  • Bridge 패턴
    Adapter 패턴은 인터페이스(API)가 서로 다른 클래스를 연결하는 패턴입니다. Bridge 패턴은 기능의 계층과 구현의 계층을 연결시키는 패턴입니다.
  • Decorator 패턴
    Adapter 패턴은 인터페이스(API)의 차이를 조정하기 위한 패턴입니다. Decorator 패턴은 인터페이스(API)를 수정하지 않고 기능을 추가하는 패턴입니다.

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

기본적인 암호화 처리를 해주는 메소드를 살짝 변경하였습니다.  암호화키를 저장해주지 못하기 때문에 별도의 페이지에서는 사용이 어려웠음.

 

필요하시면, 가져다 쓰셔도 됩니다. ^^ 암호화된 코드에다가 자기만의 암호화 처리 방법을 넣어서 해주시면 좋습니다. +_+)b

returnEncryptCode(String str)  메소드는 입력받은 문자열을 암호화 한 다음, 암호화에 사용한 암호키와 암호화된 문자열을 합쳐서 반환합니다.
public String returnDecryptCode(String str)  메소드는 returnEncryptCode(String str) 메소드에서 처리한 암호화된 코드를 받으면, 특정 부분에서 잘라서 암호키를 키로 생성하고, 암호화된 코드를 넣어서 해독하여 해독된 문자열을 반환합니다.

 

JSP에서 처리할 경우에는 returnEncryptCode(String str)에서 반환된 문자열을 저장하는 문자열 혹은 객체를 저장하는 방법만 고려하면 되겠다.

 

  1. package encrypt;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.security.InvalidKeyException;
    import java.security.Key;

    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.KeyGenerator;

    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
     
    public class LocalEncrypter{
        //DESede 는 암호화시 사용되는 최대 키 사이즈를 지정하는 키워드임 : 관련페이지 내용 링크
  2.     private static String algorithm = "DESede";
        private static Key    key       = null;
        private static Cipher cipher    = null;
     
       
        // 암호화 키를 발생시키는 메소드입니다.
        // com.sun.crypto.provider.DESedeKey@ + 16진수 8자리
        public LocalEncrypter() throws Exception {
            key = KeyGenerator.getInstance( algorithm ).generateKey();
           
    //        private static String keystr = String.valueOf(key);
    //        System.out.println(key);
    //        System.out.println("암호화 키의 형태 :"+ keystr);
    //        System.out.println(keystr.length());
           
            cipher = Cipher.getInstance( algorithm );   
        }
       
       
        //1. str 을 입력 받아서 이를 암호한다.    //2. 암호화 하는데 사용한 암호키를 encKey 로 문자열화 한다.
        //3. encKey + str 값을 반환한다. 크기는 408 byte
        public  static String returnEncryptCode(String str) throws Exception {
            byte [] encryptionBytes = null;
     

            // 입력받은 문자열을 암호화 하는 부분
            encryptionBytes = encrypt( str );
            BASE64Encoder encoder = new BASE64Encoder();

            //encoder.encode(encryptionBytes) 으로 encrypt 된 값 출력
            String encodeString = encoder.encode(encryptionBytes);
           
            // 키를 문자열로 바꿔주는 곳.
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(key);
            oos.close();
            BASE64Encoder b64enc = new BASE64Encoder();
            byte[] keyArr = bos.toByteArray();
            String encKey = b64enc.encode(keyArr);   
           
    //        System.out.println("문자열이 되어 저장된 키 : " + encKey);
    //        System.out.println("저장된 키의 길이 : " + encKey.length());
    //        System.out.println("암호화된 비밀번호 : " + encodeString);


    /*                // 암호화에 사용된 키값을 뽑아낸 수
             String keycode = keystr.substring(34,42);
             System.out.println("암호화에 사용된 키 : " + keycode);
             String randomcode = returnRandomCode();
             System.out.println("암호화된 코드 : " + encodeString);*/
            
            return encKey + encodeString;
        }

       
        //1. DB에 저장되어 있는 408 byte 길이의 str을 받는다.
        //2. 그중 0~384 까지의 암호화키(encKey)부분을 keycode로 뽑아낸다.
        //3. keycode를 Key에 대입한다.
        //4. 384~408 까지의 암호화된 문자열을 code로 뽑아낸다.
        //5. code를 해독한다.
        //6. 해독된 값을 반환한다.
        public String returnDecryptCode(String str) throws Exception {
            //복호화 하기 위해서는 암호화 키가 필요하다. ㅡㅅ-);;
            // 그래서 생각해낸 것이, DB에 저장될 때, 암호화키를 한번에 집어넣고....
            //substring 으로 잘라서 쓰는 것.
            int strLength = str.length();
           
            //암호화된 비밀번호에 저장되어 있는 암호화키를 추출.
               String keycode = str.substring(0,384);
              
              
               // 추출한 암호키를 KEY 형태로 다시 복구
               BASE64Decoder b64dec = new BASE64Decoder();
               byte[] b = b64dec.decodeBuffer(keycode);
               ByteArrayInputStream bis = new ByteArrayInputStream(b);
               ObjectInputStream ois = new ObjectInputStream(bis);
               key = (Key) ois.readObject();
               ois.close();
              
            String code = str.substring(384, strLength);
           
              
    //        System.out.println("저장된 코드 길이 : " + strLength);
    //           System.out.println("암호화 사용키 : " + keycode);
    //        System.out.println("암호화된 코드: " + code);
           
            BASE64Decoder decoder = new BASE64Decoder();
            String decode = decrypt( decoder.decodeBuffer(code));
           
    //        System.out.println("Ecrypt 에서 해독한 것 : " + decode);
            return decode;
        }
       
     
       
        // encryptionBytes = encrypt( input ), input을 변조하여 encryptionBytes에 대입함.
        private static byte [] encrypt(String input) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException  {
            cipher.init( Cipher.ENCRYPT_MODE, key );
            byte [] inputBytes = input.getBytes();
            return cipher.doFinal( inputBytes );
        }
     
       
       
        //decrypt( decoder.decodeBuffer(encodeString) ) 처리부분.
        private static String decrypt(byte [] encryptionBytes) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException{
            cipher.init( Cipher.DECRYPT_MODE, key);
            byte [] recoveredBytes = cipher.doFinal( encryptionBytes );
            String recovered = new String( recoveredBytes );
            return recovered;
        }
     
    }

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

인터넷 검색을 통하여 찾아본 구현 방법들은 서블릿에서 저장된 것들을 처리하는 방법들 뿐이었음.

나름 독자적인(?!) 해석을 통하여 JSP로만 구현하는 방법을 터득했다. 이를 이용할 예정임.

현재 진행중인 프로젝트가 완료되면 특별한 기능이 있을 경우, 기재를 하여 설명드리도록 하겠음.

 

JFeeChart 구현과 관련된 JAR 파일들

1) jfreechart-1.0.0-pre2.jar

2) jcommon-1.0.0-pre2.jar

메뉴얼 API : http://www.jfree.org/jfreechart/api/javadoc/index.html

 

  1. <%@ page language="java" contentType="text/html; charset=EUC-KR"  pageEncoding="EUC-KR"%>
    <%@ page import="java.io.*" %>
    <%@ page import="org.jfree.data.general.DefaultPieDataset"%>
    <%@ page import="org.jfree.chart.JFreeChart"%>
    <%@ page import="org.jfree.chart.plot.PiePlot"%>
    <%@ page import="org.jfree.chart.ChartRenderingInfo"%>
    <%@ page import="org.jfree.chart.servlet.ServletUtilities"%>
    <%@ page import="org.jfree.chart.urls.StandardPieURLGenerator"%>
    <%@ page import="org.jfree.chart.entity.StandardEntityCollection"%>
    <%@ page import="org.jfree.chart.ChartFactory"%>
    <%@ page import="org.jfree.chart.ChartUtilities"%>
    <%@ page import="org.jfree.data.general.PieDataset"%>
    <%@ page import="org.jfree.data.category.DefaultCategoryDataset"%>
    <%@ page import="org.jfree.chart.plot.PlotOrientation"%>
    <%@ page import="org.jfree.chart.servlet.*"%>
    <%@ page import="com.oreilly.servlet.*" %>
    <%@ page import="com.oreilly.servlet.multipart.*" %>


    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
    <title>JChart 연습하기</title>
    </head>
    <body>
        <%
            DefaultPieDataset ds = new DefaultPieDataset();
            ds.setValue("홍길동", new Double(40.0));
            ds.setValue("홍길숙", new Double(25.0));
            ds.setValue("기타", new Double(15.0));
           
            JFreeChart chart = ChartFactory.createPieChart("득점분포", ds, true, true, false);
            chart.setBackgroundPaint(java.awt.Color.white);
             chart.setTitle("JChart 연습하기");
             
             ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
           
             
            //PNG 파일명을 만들어내기
             String fileName = ServletUtilities.saveChartAsPNG(chart, 600, 300, info, session);           
           
             System.out.println("파일명 : " +fileName);
             
            //특정 임시 폴더에 이미지 파일을 만들어냄.
             String dir = application.getRealPath("/upload/"); // 파일경로 지정
             dir = "D:\\" + dir.substring(3) + "/";
             String filepath = dir + fileName;
             //System.out.println("File path = "+ filepath);
       
             FileOutputStream fos = new FileOutputStream(new File(filepath));
             File f = new File(filepath);
             ChartUtilities.writeChartAsPNG(fos, chart, 600, 300);
             
             String graphURL = request.getContextPath() + "/upload/" + fileName;
             //System.out.println(graphURL);
            %>
            <img src="<%=graphURL%>"/> <!--//파일 경로와 파일명을 받아서 차트를 보여줌-->

    </body>
    </html>

● 파일명 : jfreechart-2348981821190451270.png (파일명은 ServletUtilities.saveChartAsPNG(chart, 600, 300, info, session); 에 의해서 임의 지정됨)
● File path = D:\workspace\project\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\WomanHappy\upload/jfreechart-2348981821190451270.png  // 웹 서버에 저장된 실제 주소
● /WomanHappy/upload/jfreechart-2348981821190451270.png // 서버에 저장된 주소

JFreeChart.JPG <결과물>

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

1). Struts download : 1.3.10

 http://struts.apache.org

압축해제

strutsunzip.JPG

2). 작업 폴더 생성

strutsworkFoldermake.JPG

 

3). 이클립스 작업폴더를 변경한다(2에서 생성한 작업폴더)

eclipseSwitchingWorkspace.JPG

4) 편하게, 스트럿츠에서 제공하는 템플릿 파일을 사용하자.

strutsWarimport.JPG

5) 설치가 완료된 후, 스트럿츠를 실행한 화면

struts-blink-index.JPG

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

미투데이 따라집기!!!

me2daytest(1).JPG

 

테이블 생성 SQL

  1. create table me2daytest(
        pid number primary key,
        pname varchar2(20),
        particle varchar2(150),
        pwdate date );

 

index2.jsp

  1. <%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
    <html>
    <head>
    <script language="javascript" src="jslb_ajax.js" >
    </script> 
    <script language="javascript">
    <!--
        //콜백함수(수신시에 실행된다)
        function on_loaded(oj){
            //응답을 취득
            var res = oj.responseText

            //응답된 문자열을 DIV로 출력
            document.getElementById("list").innerHTML = res
        }

        function result(oj){
            //응답을 취득
            var res = oj.responseText
       
            //응답된 문자열을 DIV로 출력
            document.getElementById("result").innerHTML = res
    }

        //입력한 내용을 바로 업데이트 시킴.
        function input(oj){
            if (oj.form.article.value.length === 0) return
            sendRequest(result, '&name='+oj.form.name.value+'&article='+oj.form.article.value, 'POST', 'input.jsp', true, true)
            sendRequest(on_loaded, '', 'POST', 'list.jsp', true, true)
            oj.form.article.value='';
        }

        function on_formLoad(oj){
            sendRequest(on_loaded, '', 'POST', 'list.jsp', true, true)
        }


    //-->
    </script>
    <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
    <title>허니몬의 me2day 떼쳇 따라잡기</title>
    </head>
        <body>
        <h3>사용법 : 이름 입력하고 내용 입력하고 Enter 혹은 글올리기 클릭하면 됨!!</h3>
        <h3>여러분은 낙장불입의 세계에 한발 들어섰습니다.</h3>
        <hr>
        <form>
        <table>
        <tr>
        <th>이름</th><th>내용</th><th><!-- 스크립트 값이 들어가야하려나? document.write(var); -->
        <div id='result'></div>
        </th>
        </tr>
        <tr>
       
        <td><input type='text' name='name' /></td><td><input type='text' name='article' size='50' maxlength='50' onkeyup='on_formLoad(this)'/></td><td><input type='button' value='글 올리기' onclick='input(this)' /></td>
       
        </tr>
        </table>
        </form>
        화면출력!!
        <div id='list'></div>
        </body>
    </html>

 

input.jsp

  1. <%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
    <jsp:useBean id="data" class="data.DataProc" scope="page"/>
    <%
        String name = request.getParameter("name");
        String article = request.getParameter("article");
       
        data.insertData(name,article);
        out.println("처리완료");
    %>

 

list.jsp

  1. <%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
    <%@ page import='java.util.*, data.*' %>
    <jsp:useBean id='data' class='data.DataProc' scope='page' />
    <%
        Vector result = data.list();

        if( result.isEmpty() == true) {
            out.println("입력된 데이터가 없습니다.");
        } else {
    %>
        <table border='1'>
    <%
            //vector는 0부터 시작하는 거였구나... 그걸 몰랐다!!
            for( int i = 0; i < result.size(); i++){
                DataBean b = (DataBean)result.elementAt(i);
                String name = b.getPname();
                String article = b.getParticle();
                String wdate = b.getPwdate();
    %>
            <tr>
            <td><%= name %></td><td><%= article %></td><td><%= wdate %></td>
            </tr>
    <%
            }
    %>
        </table>
    <%
           
        }
    %>

 

DataBean.jsp

  1. package data;

    public class DataBean {
        private String pname="";
        private String particle="";
        private String pwdate="";
       
        public DataBean(){}
       
        public DataBean(String pname, String particle, String pwdate){
            this.pname = pname;
            this.particle = particle;
            this.pwdate = pwdate;
        }

        public String getPname() {
            return pname;
        }

        public void setPname(String pname) {
            this.pname = pname;
        }

        public String getParticle() {
            return particle;
        }

        public void setParticle(String particle) {
            this.particle = particle;
        }

        public String getPwdate() {
            return pwdate;
        }

        public void setPwdate(String pwdate) {
            this.pwdate = pwdate;
        }
       
    }

 

DataProc.java

  1. package data;

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

    import javax.naming.InitialContext;
    import javax.sql.DataSource;

    public class DataProc {
        DataSource ds;
       
        public DataProc(){
            try {
                InitialContext context = new InitialContext();
                ds = (DataSource)context.lookup("java:comp/env/jdbc/oracle");
            } catch(Exception e){
                e.printStackTrace();
            }
        }
       
        public void insertData(String name, String article){
            Statement stat;
            Connection con;
            int pid = checkpid();
           
            String sql = "INSERT INTO me2daytest values(" + pid + ",'" + name + "', '"+ article +"', sysdate)";
            try{
                con = ds.getConnection();
                stat = con.createStatement();
                stat.executeUpdate(sql);
                stat.close();
                con.close();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
       
        public Vector list(){
            Connection con;
            Statement stat;
            Vector result = new Vector();
           
            String sql = "SELECT pname, particle, pwdate FROM me2daytest ORDER BY pwdate desc";
            try {
                con = ds.getConnection();
                stat = con.createStatement();
                ResultSet rs = stat.executeQuery(sql);
                while( rs.next() ){
                    String name = rs.getString(1);
                    String article = rs.getString(2);
                    String wdate = rs.getString(3);
                    DataBean bean = new DataBean(name, article, wdate);
                    result.add(bean);
                }
                rs.close();
                stat.close();
                con.close();
            } catch(Exception e){
                e.printStackTrace();
            }
            return result;   
        }
       
        public int checkpid(){
            Connection con;
            Statement stat;
            int pid=0;
           
            String sql = "SELECT max(pid) FROM me2daytest";
            try {
                con = ds.getConnection();
                stat = con.createStatement();
                ResultSet rs = stat.executeQuery(sql);
                while( rs.next() ){
                    pid = rs.getInt(1);
                }
                rs.close();
                stat.close();
                con.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return pid+1;
        }
    }

 

문제점 :

  • 다른 사람이 입력한 뒤에 Reload가 되지 않는다. 이건 어떻게 해야하지? ㅡㅅ-)? 원격인터페이스를 써줘야할까? EJB 무상태 세션빈?
  • 본문 입력시 입력하지 않고 입력했을 때 javascript로 거절하도록 한다.
  • 페이지 나누기 기능이 필요할 듯 하다.
  • 미관상 이쁘지 않다.

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

+ Recent posts