레이블이 java인 게시물을 표시합니다. 모든 게시물 표시
레이블이 java인 게시물을 표시합니다. 모든 게시물 표시

2012-10-31

java Framework/java]Bean to XML



package org.kodejava.example.bean;

import java.beans.XMLEncoder;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;

public class BeanToXML {
    private Long id;
    private String itemName;
    private String itemColour;
    private Integer itemQuantities;

    public static void main(String[] args) {
        BeanToXML bean = new BeanToXML();
        bean.setId(new Long(1));
        bean.setItemName("T-Shirt");
        bean.setItemColour("Dark Red");
        bean.setItemQuantities(new Integer(100));
       
        try {
            XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
                    new FileOutputStream("Bean.xml")));

            //
            // Write an XML representation of the specified object to the output.
            //
            encoder.writeObject(bean);
            encoder.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public String getItemColour() {
        return itemColour;
    }

    public void setItemColour(String itemColour) {
        this.itemColour = itemColour;
    }

    public Integer getItemQuantities() {
        return itemQuantities;
    }

    public void setItemQuantities(Integer itemQuantities) {
        this.itemQuantities = itemQuantities;
    }
}


The XML persistence will be like:
<?xml version="1.0" encoding="UTF-8"?> 

<java version="1.6.0_02" class="java.beans.XMLDecoder"> 

 <object class="org.kodejava.example.bean.BeanToXML"> 

  <void property="id"> 

   <long>1</long> 

  </void> 

  <void property="itemColour"> 

   <string>Dark Red</string> 

  </void> 

  <void property="itemName"> 

   <string>T-Shirt</string> 

  </void> 

  <void property="itemQuantities"> 

   <int>100</int> 

  </void> 

 </object> 

</java>

java Framework/java] 파일 이어받기 기능 구현



출처 :http://webprogrammer.tistory.com/tag/%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C%20%ED%8C%8C%EC%9D%BC%20%EC%9D%B4%EC%96%B4%EB%B0%9B%EA%B8%B0%20%EA%B8%B0%EB%8A%A5


자바에서 파일 쓰기 할 때
          BufferedWriter file = new BufferedWriter(new FileWriter("filename"));
대개의 경우 이런식으로 코딩을 했었는데, 이 코드는 파일을 덮어쓴다.
파일을 덮어쓰지 않고 이어쓰기하는 방법이 없을까 하고 고민하고 찾아봤다.
RandomAccessFile 클래스를 사용하는 방법도 있었고
그리고 파일을 쭉 읽어서 변수에 저장을 한 뒤 새로 추가할 내용을 덧붙여서 파일에 쓰는 방법도 있었다.
하지만 뭔가 더 간편한게 있을 것 같아서 찾아봤더니
이 한문장이면 파일 이어쓰기가 가능하다.

        BufferedWriter file = new BufferedWriter(new FileWriter("filename", true));

이 코드는 파일이 없으면 새로 만들고 있다면 덮어쓰지 않고 이어서 쓰게한다.

그리고 파일에서 개행문자를 쓰려고할 때
C나 C++에서처럼 당연히 ""이 먹힐거라 생각을 하고
          str = str + "";
          file.write(str, 0, str.length());
이렇게 썼는데 파일에는 줄바꿈이 되어있지 않았다.
알아본 결과 저 위에서 사용한 FileWriter가 가독성때문에 ""을 지원하지 않기 때문이었다.
BufferedWriter를 통해서 개행문자를 쓸 수 있다.
바로 이렇게..

        file.write(str, 0, str.length());
        file.newLine();

간단하다. 하하하;;;
이 사실을 난... 어제 알았다. 쿨럭 -_-;;;
까먹을까봐...

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

기존파일에 덧붙여서 내용을 저장하려면, RandomAccessFile 클래스를 사용해야 합니다.
아래는 간단한 예제 입니다.

출처 : http://finetia.egloos.com/1422965
—————————————————————————
import java.io.IOException;
import java.io.RandomAccessFile;
public class UsingFile {
  public UsingFile() {
  }
  public static void main(String[] args) {
    try {
      String name = “c:\\tmpfile.txt”;
      RandomAccessFile raf = new RandomAccessFile(name, “rw”);
      raf.seek(raf.length());
      raf.writeBytes(“\r\n append”);
    }
    catch (IOException e) {
      System.out.println(“Error opening file: ” + e);
    }
  }
}


출처 : http://rothmans.wordpress.com/2006/07/12/%EC%86%8C%EC%8A%A4%ED%8C%8C%EC%9D%BC-%EC%9D%B4%EC%96%B4-%EC%93%B0%EA%B8%B0/

java] SimpleDateFormate 예제



출처 : http://www.ssial.com/141


import java.text.SimpleDateFormat;

.
.
.


Format formatter;
 
    // The year
    formatter = new SimpleDateFormat("yy");    // 02
    formatter = new SimpleDateFormat("yyyy");  // 2002
 
    // The month
    formatter = new SimpleDateFormat("M");     // 1
    formatter = new SimpleDateFormat("MM");    // 01
    formatter = new SimpleDateFormat("MMM");   // Jan
    formatter = new SimpleDateFormat("MMMM");  // January
 
    // The day
    formatter = new SimpleDateFormat("d");     // 9
    formatter = new SimpleDateFormat("dd");    // 09
 
    // The day in week
    formatter = new SimpleDateFormat("E");     // Wed
    formatter = new SimpleDateFormat("EEEE");  // Wednesday
 
    // Get today's date
    Date date = new Date();
 
    // Some examples
    formatter = new SimpleDateFormat("MM/dd/yy");
    String s = formatter.format(date);
    // 01/09/02
 
    formatter = new SimpleDateFormat("dd-MMM-yy");
    s = formatter.format(date);
    // 29-Jan-02
 
    // Examples with date and time; see also
    // e316 Formatting the Time Using a Custom Format
    formatter = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss");
    s = formatter.format(date);
    // 2002.01.29.08.36.33
 
    formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z");
    s = formatter.format(date);
    // Tue, 09 Jan 2002 22:14:02 -0500

    // The hour (1-12)
    formatter = new SimpleDateFormat("h");     // 8
    formatter = new SimpleDateFormat("hh");    // 08
 
    // The hour (0-23)
    formatter = new SimpleDateFormat("H");     // 8
    formatter = new SimpleDateFormat("HH");    // 08
 
    // The minutes
    formatter = new SimpleDateFormat("m");     // 7
    formatter = new SimpleDateFormat("mm");    // 07
 
    // The seconds
    formatter = new SimpleDateFormat("s");     // 3
    formatter = new SimpleDateFormat("ss");    // 03
 
    // The am/pm marker
    formatter = new SimpleDateFormat("a");     // AM
 
    // The time zone
    formatter = new SimpleDateFormat("z");     // PST
    formatter = new SimpleDateFormat("zzzz");  // Pacific Standard Time
    formatter = new SimpleDateFormat("Z");     // -0800
 
    // Get today's date
    Date date = new Date();
 
    // Some examples
    formatter = new SimpleDateFormat("hh:mm:ss a");
    String s = formatter.format(date);
    // 01:12:53 AM
 
    formatter = new SimpleDateFormat("HH.mm.ss");
    s = formatter.format(date);
    // 14.36.33



출처: http://www.exampledepot.com/egs/java.text/pkg.html#Times

JAVA] RSS Reader 만들기


** java]Http 통신 의 예제 파일 참조

javascript를 이용한 초간단 Rss Reader 구현하기 : javascript 를 이용한 초간단 Rss Reader 구현하기
참조사이트 : http://blog.naver.com/sullim75?Redirect=Log&logNo=140028752352


춣처 : http://poolpiri.egloos.com/7021118


간단한 Rss Reader 만들기...


블로그를 만들어보다가 Rss를 읽어서 웹상에서 보여주는 RssReader가 필요할꺼 같아서...
간단하게 만들어봅니다.
자카르타 오픈 컴포넌트중에 하나인 commons.digester를 이용한겁니다...그래서 간단허져...
일단 아래와 같이 간단한 메서드를 만들어봅니다.
/**
* RSSDigester를 이용해서 링크의 스트림(xml)을 파싱해서 Channel객체를 리턴한다.
*
* @param xmlLink
* @param response
* @return org.apache.commons.digester.rss.Channel
* @throws Exception
*/


private Channel getChannel(String xmlLink)
      throws Exception {
    Channel chan = null;
    try {
       RSSDigester digester = new RSSDigester();
      // 방법 1. Rss Link를 이용한 파싱...
       //chan = (Channel) digester.parse(xmlLink);
       // 방법 2. Rss Link를 URL로 연결해서 얻은 스트림으로 파싱...
       //chan = (Channel) digester.parse(new URL(xmlLink).openStream());
       // 방법 3. 국내 사이트 Character Encoding문제 때문에...추가...

       chan = (Channel) digester.parse(getEncodedReader(xmlLink));
    } catch (java.io.IOException ioe) {
       chan = new Channel();
       chan.setTitle("ERROR");
       StringBuffer sb = new StringBuffer("<span class="error">");
       sb.append("IOException parsing RSS XML LINK : " + xmlLink);
       sb.append("</span>n<p>");
       sb.append(ioe.toString());
       chan.setDescription(sb.toString());
    } catch (org.xml.sax.SAXException se) {
       chan = new Channel();
       chan.setTitle("ERROR");
       StringBuffer sb = new StringBuffer("<span class="error">");
       sb.append("SAXException parsing RSS XML LINK : " + xmlLink);
       sb.append("</span>n<p>");
       sb.append(se.toString());
       chan.setDescription(sb.toString());
    }
return chan;
}
파라미터로 와야하는 String xmlLink은 본 엠파스 블로그에 있는거같은 RSS링크 유알엘을 넣어주심 됩니다. 제 블로그를 예를 들면..."http://blog.empas.com/poolpiri3/rss.xml" 이게 들어오면 되는겁니다.
여기 예제는 엠파스에서 제공하는 rss.2.0 버전에만 잘돌아갑니당...이 버전은 웬만한 국내 RSS가 지원하는 버전입니다...

소스 중간에 있는 주석을 보시면 몇가지 방법이 있습니다만...국내 사이트의 경우 한글 인코딩 문제로 파싱이 제대로 안됩니다. 여기 엠파스도 마찬가지구여... 이럴줄 알았으면 굳이 digester를 쓰지 않고 방법을 생각했으면 더 쉬워질 수 도 있었습니다만...제가 무지한지라...하여 아래와 같은 메서드를 무식하게 추가했습니다.
/**
* xml파일의 encoding타입을 읽어서 그 타입대로 컨버전후 InputStreamReader를 리턴한다.
*
* @param xmlLink
* @return InputStreamReader
*/


private InputStreamReader getEncodedReader(String xmlLink) {
   URL url = null;
    InputStreamReader reader = null;
    BufferedReader br = null;
    try {
       url = new URL(xmlLink);
       reader = new InputStreamReader(url.openStream());
       byte b[] = new byte[1024];
       br = new BufferedReader(reader);
       String line = br.readLine();
       while (line != null) {
          if (!(line.trim().equals(""))) {
             int index = line.toLowerCase().indexOf("encoding");
             String prefix = """;
             String encoding = "";
             if (index != -1) {
                int start = line.indexOf(prefix, index) + 1;
                if (start == -1) {
                   prefix = "'";
                   start = line.indexOf(prefix, index) + 1;
                   if (start == -1) {
                     start = line.indexOf("=", index) + 1;
                     prefix = "?";
                   }
                }
             encoding = line.substring(start, line.indexOf(prefix, start));
             if (encoding != null && !("".equals(encoding))) {
                reader =  new InputStreamReader( url.openStream(),  encoding.trim());
             } else {
                reader = new InputStreamReader(url.openStream());
             }
       } else {
          reader = new InputStreamReader(url.openStream());
       }
    break;
   }
   line = br.readLine();
   }
   } catch (MalformedURLException e) {
       e.printStackTrace();
    } catch (IOException e) {
       e.printStackTrace();
    } finally {
       if (br != null) {
          try {
             br.close();
          } catch (IOException e1) {
             e1.printStackTrace();
          }
       }
    }
    return reader;
}
하여튼 이렇게 얻어진 channel를 객체를 통해서 아래와 같이 jsp에서 뿌려주심 됩니다.
<% int maxItems = 10;
if (channel != null) {
if ("ERROR".equals(channel.getTitle())) {%>

<tr bgcolor="#FFCCFF">
<td width="100" bgcolor="#CCCCFF">블로그 이름</td>
<td bgcolor="#CCFFCC"><%=channel.getDescription()%></td>
</tr>
<%return;
}%>
<% String divId = Utility.replace(channel.getTitle(), " ", "_");
divId = Utility.replace(channel.getTitle(), "'", "_");%>
<!--<%=channel.getLastBuildDate()%><%=channel.getCopyright()%><%=channel.getDocs()%><%=channel.getLanguage()%>-->

<tr bgcolor="#FFCCFF">
<td bgcolor="#CCFFCC" width="500" colspan="2" valign="bottom"><a href="<%=channel.getLink()%>" target="_blank"><h3><%=channel.getTitle()%></h3></a><br>
<%=channel.getDescription()%></td>
</tr>
<% Image image = channel.getImage();
if (image != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2" height="50"><img src="<%=image.getURL()%>" alt="<%=image.getTitle()%>" > <!--width="<%=image.getWidth()%>" height="<%=image.getHeight()%>"-->
</td>
</tr>
<% }
Item[] items = channel.getItems();
for (int j = 0; j < items.length; j++) {
if (items[j].getTitle() != null && items[j].getLink() != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2"><a href="<%=items[j].getLink()%>" target="_blank" class="RssLink"><%=items[j].getTitle()%></a></td>
</tr>
<% } else if (items[j].getTitle() != null) {%><tr bgcolor="#FFFFFF">
<td colspan="2"><div class="RssTitle"><%=items[j].getTitle()%></div></td>
</tr>
<% }
if (items[j].getDescription() != null) {%>
<tr bgcolor="#FFFFFF">
<td colspan="2"><div class="RssDesc"><%=items[j].getDescription()%>...</div></td>
</tr>
<% }
if (maxItems != -1 && j >= maxItems)
break;
}
} else {%>
<tr bgcolor="#FFFFFF">
<td colspan="2">블로그 리스트가 하나도 없습니다. -_-</td>
</tr>
<% }%>
흠흠...제가 봐도 어설프네여...
이렇게 하면 자기 홈페이지나 특정사이트에 기존에 IFRAME같은 방법으로 넣어줬던 다른 사이트의 특정 게시물 리스트를 RSS와 RSS Reader를 통해서 출력해줄 수 있습니다.
물론 항상 신규 리스트겠죠 또한 해당 사이트에서 RSS를 지원해야만 가능한거구여...요샌 상당수 사이트들이 지원을 하구여...
그럼...
위의 소스는 commons.digester 1.5/1.6 을 기준으로 작성 되어서 2.x에서는 RSSDigester()를 찾을 수 없었다...(2010.07.06 기준)
그래서 아래의 소스로 rss reader를 구현하게 되었다...



RssReader.java
=================================

package rss;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Scanner;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class RssReader {

    private static RssReader instance = null;
    private static String ENCODING = "UTF-8";
    static String NL = System.getProperty("line.separator");
  
    private RssReader() {
    }
  
    public static RssReader getInstance() {
        if(instance == null) {
            instance = new RssReader();  
        }
        return instance;
    }
  
    public void writeNews() {
        try {

            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
//            URL u = new URL("http://mutasyon.net/cs/blogs/hakkiocal/rss.aspx");
//            URL u = new URL("http://rss.joins.com/joins_news_list.xml");
//            URL u = new URL("http://feeds.feedburner.com/afriken");
            URL u = new URL("http://blog.rss.naver.com/jeffyang.xml");
          
            Document doc = builder.parse(u.openStream());
          
            NodeList nodes = doc.getElementsByTagName("item");
            NodeList nodeChannel = doc.getElementsByTagName("channel");
          
            for(int i=0;i<nodes.getLength();i++) {
              
                Element element = (Element)nodes.item(i);
              
                System.out.println("Title: " + getElementValue(element,"title"));
                System.out.println("Category: " + getElementValue(element,"category"));
                System.out.println("Link: " + getElementValue(element,"link"));
                System.out.println("Publish Date: " + getElementValue(element,"pubDate"));
                System.out.println("author: " + getElementValue(element,"author"));
                System.out.println("comment: " + getElementValue(element,"comments"));
                System.out.println("guid: " + getElementValue(element,"guid"));
                System.out.println("language: " + getElementValue(element,"language"));
                System.out.println("description: " + getElementValue(element,"description"));
                System.out.println();
            }//for          
        }//try
        catch(Exception ex) {
        ex.printStackTrace();  
        }
      
    }
  
    public void writeNews(String url) {
        try {
          
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

            URL u = new URL(url);
          
            Document doc = builder.parse(u.openStream());
          
            NodeList nodes = doc.getElementsByTagName("item");
          
            for(int i=0;i<nodes.getLength();i++) {
              
                Element element = (Element)nodes.item(i);
              
                System.out.println("Title: " + getElementValue(element,"title"));
                System.out.println("Category: " + getElementValue(element,"category"));
                System.out.println("Link: " + getElementValue(element,"link"));
                System.out.println("Publish Date: " + getElementValue(element,"pubDate"));
                System.out.println("author: " + getElementValue(element,"author"));
                System.out.println("comment: " + getElementValue(element,"comments"));
                System.out.println("guid: " + getElementValue(element,"guid"));
                System.out.println("language: " + getElementValue(element,"language"));
                System.out.println("description: " + getElementValue(element,"description"));
                System.out.println();
            }//for          
        }//try
        catch(Exception ex) {
            ex.printStackTrace();  
        }
      
    }
      
      
    private String getCharacterDataFromElement(Element e) {
        try {
            Node child = e.getFirstChild();
            if(child instanceof CharacterData) {
                CharacterData cd = (CharacterData) child;
                return cd.getData();
            }
        }
        catch(Exception ex) {
          
        }
        return "";          
    } //private String getCharacterDataFromElement
  
    protected float getFloat(String value) {
        if(value != null && !value.equals("")) {
            return Float.parseFloat(value);  
        }
        return 0;
    }
  
    protected String getElementValue(Element parent,String label) {
        return getCharacterDataFromElement((Element)parent.getElementsByTagName(label).item(0));  
    }
  
    /**
     * 파일 읽기
     * @param ctx
     * @param fileName
     * @return
     * @throws FileNotFoundException
     */
    public static StringBuffer readFile(String fileName, String fEncoding) throws FileNotFoundException {
        StringBuffer result = new StringBuffer();
//        Scanner scanner = new Scanner(new File(fileName), fEncoding);
        try {
            BufferedReader in = new BufferedReader(new FileReader(fileName));
            try {
                String line = null;
              
                while ((line=in.readLine()) != null) {
                    result.append(line+NL);
                }
            } finally {
                in.close();
            }
//            while (scanner.hasNextLine()) {
//                result.append(scanner.nextLine()+NL);
//            }
        }catch(IOException ex ) {
            ex.printStackTrace();
        }
      
        return result;
    }
  
    public static StringBuffer readFileScanner(String fileName, String fEncoding) throws FileNotFoundException {
        StringBuffer result = new StringBuffer();
        Scanner scanner = new Scanner(new File(fileName), fEncoding);
        try {
            while (scanner.hasNextLine()) {
                result.append(scanner.nextLine()+NL);
            }
        } finally {
                scanner.close();
        }
      
        return result;
    }
  
    public static void main(String[] args) {
        try {
//            StringBuffer strUrl = readFile(args[0],  ENCODING);
            StringBuffer strUrl = readFileScanner(args[0],  ENCODING);
            if(strUrl != null ){
                String[] urls = strUrl.toString().split(NL);
                for(int i=0; i < urls.length;i++) {
                    RssReader reader = RssReader.getInstance();
                    reader.writeNews(urls[i]);  
                }
            }

            RssReader reader = RssReader.getInstance();
            reader.writeNews();  
                      
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
//            e.printStackTrace();
            System.out.println("지정된 파일을 찾을 수 없습니다. 파일을 확인하시기 바랍니다.");
        }

    }
}

java] random 사용하여 난수 구하기.



    // 1 ~ 10  사이의 정수 난수
    for (int i = 1; i <= 20; i++) {
      int n = (int) (Math.random() * 10) + 1;   <== *10 부분을 100, 1000 으로 늘리면 1-100, 1-1000 까지의 난수를 구할 수 있다.
      System.out.println(n);
    }

    // 0.0 ~ 1.0    사이의 실수 난수
    for (int i = 1; i <= 20; i++)
      System.out.println(Math.random());

java] Quartz를 사용하여 동적으로 Job 등록하기




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


Quartz는 작업을 일정 지정한 시간에 Class기능을 수행하도록 만드는 스케쥴러이다.
이를 위해서는  Schduler가 있어야 하며 또 수행할 작업들의 Class가 있어야 한다.

나는 Quartz를 사용하기 위해서 우선 다음과 같이 분류하였다.



분류
 기능
 Quartz Scheduler Main
 실질적인 Scheduler가 Job을 수행시키는 Class
 Quartz Job Class
 수행할 작업의 내용이 담겨있는 Class
 Quartz PropertyLoader
 Properties에 Job정보를 Main Class에서 읽어 드리도록만든 Loader Class(정해진 규칙에 따라서 등록해야 함)
각 분류별 Class의 코드의 내용을 확인해보자.
1.Scheduler Class(THJobMain.class)
  - Main에서는 Properties파일에서 등록한 Job내용을 읽어드려 수행하는 작업만 수행한다.
  - Scheduler는 StdSchedulerFactory에 스케쥴생성을 통하여 스케쥴러를 시작할수 있다. 단순히 스케쥴러는 시작만한다.
  - 스케쥴러 에서 Start후에는 스케쥴러에 등록된 Job Class가 동작하게 되는것이다.
  - JobRegist에서 Job을 등록해준다.
  - JobRegist에서는 CronTrigger를 사용하여 스케쥴에 등록하여준다.
  - JobDetail은 "Name" , "Group" , "Class" 형태로 등록하고
    CronTrigger는 "Name" , "Group" , "CronExpression"으로 등록한다.
  - 해당 Job을 scheduler.scheduleJob(jobDetail, trigger); 를 사용하여 스케쥴러에 등록해준다.
package tahoe.core.job;import java.text.ParseException;
import org.apache.log4j.PropertyConfigurator;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class THJobMain
{
    private SchedulerFactory schedulFactoty = null;
    private Scheduler scheduler = null;
    private JobDetail jobDetail = null;
    private CronTrigger trigger = null;
    private String className = null;
    private String expression = null;
    THPropertyLoader ThProp = new THPropertyLoader();
  
    public THJobMain()
    {
        JobInit();
    }
 
    private void JobInit()
    {
        try
        {
            schedulFactoty = new StdSchedulerFactory();
            scheduler = schedulFactoty.getScheduler();
            scheduler.start();
            JobRegist();
        }
        catch (SchedulerException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void JobRegist()
    {
        String taskGroups = ThProp.read("TaskGroups");
        String taskList = ThProp.read( taskGroups + ".TaskNames");
        String[] arTaskGroups = taskList.split(",");
     
        for ( int i = 0; i < arTaskGroups.length; i++ )
        {
            Class c = null;
            className = ThProp.read( arTaskGroups[i] + ".class" );
            expression = ThProp.read( arTaskGroups[i] + ".Expression" );

            try
            {
                c = Class.forName( className );
            }
            catch (ClassNotFoundException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            jobDetail = new JobDetail( arTaskGroups[i], arTaskGroups[i], c );
            trigger = new CronTrigger( arTaskGroups[i], arTaskGroups[i] );
            try
            {
                trigger.setCronExpression( expression );
                scheduler.scheduleJob(jobDetail, trigger);
            }
            catch (SchedulerException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch ( ParseException e2 )
            {
                e2.printStackTrace();
            }
        }
    }
 
 
    public static void main(String[] args)
    {
        PropertyConfigurator.configure("WEB-INF/conf/log4j.properties");
        new THJobMain();
    }
}


2.PropertyLoader Class(THPropertyLoader.class)
  - Param으로 받은 string Value를 사용하여 Properties파일의 해당 내용을 찾는다.
  - String으로 값을 Return해준다.
package tahoe.core.job

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class THPropertyLoader
{
 
    public THPropertyLoader()
    {}
 
    /**
     * properties 파일 읽기
     */
     public String read(String propKey)
     {
         Properties  pp  = new Properties();
         try
         {
              FileInputStream fis  = new FileInputStream("WEB-INF/conf/quartz.properties");
              pp.load(fis);
         }
         catch (IOException ioe)
         {
              ioe.printStackTrace();
              System.exit(-1);
         }
        return pp.getProperty(propKey);
     }
}


3.Job Class(THJobTest1.class,THJobTest2.class,THJobTest3.class)
  - 실재 스케쥴이 시작될때 작업을 해야할 기능이 있는 Class이다.
  - Job Class는 Quartz의 Job class를 필수적으로 구현해서 사용해야한다.(implement Job)
  - Job 수행은 execute를 통해서 실행된다.(로직을 사용시에 이부분에서 로직을 구현하면 된다.)
  - Test를 위해 sysout메세지 출력으로 Test해본다.
public class THJobTest1 implements Job
{
    public void execute(JobExecutionContext context)
    {
        System.out.println("Test Job1 = " + new Date());
    }
}
public class THJobTest2 implements Job
{
    public void execute(JobExecutionContext context)
    {
        System.out.println("Test Job2 = " + new Date());
    }
public class THJobTest3 implements Job
{
    public void execute(JobExecutionContext context)
    {
        System.out.println("Test Job3 = " + new Date());
    }
}


이제 Properties파일에 설정한후 실행을 해보자.
현재 Property에 Expression 설정을 매 5초 마다 실행 하도록 설정하였다.
각각 등록후 에 Main에서 수행시킬 경우 다음과 같이 내용이 출력되었다.
이로써 Job Class를 작성한후 매번 Main에서 Job을 등록하지 않아도 Properties파일을 사용하여 작업스케쥴러를
등록하여 편리하게 사용할 수 있다.
[2010:06:15 11:06:58][INFO][org.quartz.simpl.SimpleThreadPool][0(ms)][Tahoe]-Job execution threads will use class loader of thread: main
[2010:06:15 11:06:58][INFO][org.quartz.core.SchedulerSignalerImpl][0(ms)][Tahoe]-Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[2010:06:15 11:06:58][INFO][org.quartz.core.QuartzScheduler][0(ms)][Tahoe]-Quartz Scheduler v.1.7.3 created.
[2010:06:15 11:06:58][DEBUG][org.quartz.utils.UpdateChecker][0(ms)][Tahoe]-Checking for update...
[2010:06:15 11:06:58][INFO][org.quartz.simpl.RAMJobStore][0(ms)][Tahoe]-RAMJobStore initialized.
[2010:06:15 11:06:58][INFO][org.quartz.impl.StdSchedulerFactory][0(ms)][Tahoe]-Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties'
[2010:06:15 11:06:58][INFO][org.quartz.impl.StdSchedulerFactory][0(ms)][Tahoe]-Quartz scheduler version: 1.7.3
[2010:06:15 11:06:58][INFO][org.quartz.core.QuartzScheduler][0(ms)][Tahoe]-Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
[2010:07:15 11:07:00][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest1.THJobTest1', class=tahoe.core.job.THJobTest1
[2010:07:15 11:07:00][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest1.THJobTest1
[2010:07:15 11:07:00][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest2.THJobTest2', class=tahoe.core.job.THJobTest2
[2010:07:15 11:07:00][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest2.THJobTest2
[2010:07:15 11:07:00][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest3.THJobTest3', class=tahoe.core.job.THJobTest3
[2010:07:15 11:07:00][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest3.THJobTest3
Test Job3 = Mon Mar 15 11:07:00 KST 2010
Test Job1 = Mon Mar 15 11:07:00 KST 2010
Test Job2 = Mon Mar 15 11:07:00 KST 2010
[2010:07:15 11:07:01][DEBUG][org.quartz.utils.UpdateChecker][0(ms)][Tahoe]-No update found.
[2010:07:15 11:07:05][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest1.THJobTest1', class=tahoe.core.job.THJobTest1
[2010:07:15 11:07:05][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest1.THJobTest1
Test Job1 = Mon Mar 15 11:07:05 KST 2010
[2010:07:15 11:07:05][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest2.THJobTest2', class=tahoe.core.job.THJobTest2
[2010:07:15 11:07:05][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest2.THJobTest2
Test Job2 = Mon Mar 15 11:07:05 KST 2010
[2010:07:15 11:07:05][DEBUG][org.quartz.simpl.SimpleJobFactory][0(ms)][Tahoe]-Producing instance of Job 'THJobTest3.THJobTest3', class=tahoe.core.job.THJobTest3
[2010:07:15 11:07:05][DEBUG][org.quartz.core.JobRunShell][0(ms)][Tahoe]-Calling execute on job THJobTest3.THJobTest3
Test Job3 = Mon Mar 15 11:07:05 KST 2010

java Framework/java] PDF 작업 관련 url





  •   iText 에서 장평 처리 
    • iText의 예제 소스 중 part/chapter14/TextStateOperateors.java 의 59-62 줄 사이의 canvas.setHorizontalScaling(50) 으로 조정 가능(이미지로 처리하는 듯 함) 
  • 거니네(iText관련 문서/강좌??) http://guni.loveyust.net/tag/itext


      iText.jar :    iText-5.0.5.jar



pdfContentByte 에서 bold 를 사용할 수 있는 방법??
.
// first define a standard font for our text
Font helvetica8BoldBlue = FontFactory.getFont(FontFactory.HELVETICA, 8, Font.BOLD, Color.blue);

// create a column object
ColumnText ct = new ColumnText(cb);

// define the text to print in the column
Phrase myText = new Phrase("Lorem ipsum dolor sit amet, ...", helvetica8BoldBlue);
ct.setSimpleColumn(myText, 72, 600, 355, 317, 10, Element.ALIGN_LEFT);
ct.go();

java Framework/java] Object와 JSONObject


[다운]
Java에서 Json 객체로 변환할 때, json-lib라는 오픈 소스를 이용한다.
http://json-lib.sourceforge.net

json-lib에서 array를 변환할 때는 EZMorph 라이브러리가 필요하다.
http://ezmorph.sourceforge.net

자바스크리브에서 객체를 json 객체로 변환시에는 json.js를 이용한다.
http://json.org

[사용법]
Java에서 Json-lib를 사용하기 위해서 필요한 라이브러리는 다음과 같고, eclipse 사용시 Build Path -> Add Exeternal Archives 에 추가한다.
json-lib-2.1-jdk15.jar
jakarta commons-lang 2.3
 
jakarta commons-beanutils 1.7.0  

jakarta commons-collections 3.2  

jakarta commons-logging 1.1

ezmorph 1.0.4

[예제]
   1. 자바스크립트에서
      object.toJSONString();

   2. 자바에서
      JSONObject oJSONObject = JSONObject.fromObject( object );
      JSONArray = JSONArray.fromObject( retlist );

json형식 ==>{"jsontest":[{"name":"Mr.Cho","location":"Seoul"}]}

import java.util.Iterator;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class JSONParse {
   public static void main(String[] ar) {
      String s = "{\"jsontest\":[{\"name\":\"Mr.Cho\",\"location\":\"Seoul\"}]}";
      JSONObject jo = JSONObject.fromObject(s);
      JSONArray ja = jo.getJSONArray("jsontest");
      for (Iterator i = ja.iterator(); i.hasNext();) {
          JSONObject ob = (JSONObject) i.next();
          String a = ob.getString("name");
          String b = ob.getString("location");
          System.out.println(a);
          System.out.println(b);
      }
   }
}



아래 fromObject를 사용할 수 있어서 json.jar (org.json.JSONObject) 보다는 json-lib.jar (net.sf.json.JSONObject) 이 더 편한 것 같다.
JSONObject.fromObject( obj )
obj에 문자열도 가능하며, 이것이 JSONText 규칙에 맞을 경우 적절한 JSON 객체를 만들어준다.
이때, obj에 있는 문자열은 작은따옴표(')도 문자열로 간주한다.

   Map states = JSONObject.fromObject("{'':'선택안함','1':'신청','2':'완료','3':'보류'}")

위와 같이 하면 꽤 깔쌈하게 Map 객체를 만들 수 있으며, 이를 Velocity에서도 #set 구문을 이용해서 똑같이 쓸 수도 있다.

java] jsp jdbc 연결 예제




출처  : http://allinfo.tistory.com/14


파일명 : jdbctest.jsp

<%@ page contentType="text/html;charset=euc-kr" import="java.sql.*" %>
<% request.setCharacterEncoding("euc-kr"); %>
<%
 // 데이터베이스 연결관련 변수 선언
 Connection conn = null;
 Statement stmt = null;
 // 데이터베이스 연결관련정보를 문자열로 선언
 String jdbc_driver = "oracle.jdbc.driver.OracleDriver";
 String jdbc_url = "jdbc:oracle:thin:@localhost:1521:ORCL";

 try{
  // JDBC 드라이버 로드
  Class.forName(jdbc_driver);
  // 데이터베이스 연결정보를 이용해 Connection 인스턴스 확보
  conn = DriverManager.getConnection(jdbc_url,"scott","tiger");
  // Connection 클래스의 인스턴스로 부터 SQL  문 작성을 위한 Statement 준비
  stmt = conn.createStatement();
  // username 값을 입력한 경우 sql 문장을 수행.
if(request.getParameter("username") != null) {
   String sql = "insert into jdbc_test values('"+request.getParameter("username")+"','"+request.getParameter("email")+"')";
   stmt.executeUpdate(sql);
  }
 }
 catch(Exception e) {
  System.out.println(e);
 }
%>
<HTML>
<HEAD><TITLE>JDBC 테스트 </TITLE></HEAD>
<BODY>
<center>
<H2>이벤트 등록</H2>
<HR>
<form name=form1 method=post action=jdbctest.jsp>
등록이름 : <input type=text name=username>
email주소 : <input type=text name=email size=20>
<input type=submit value="등록">
</form>
<HR>
</center>
# 등록 목록<P>
<%
 try{
  // select 문장을 문자열 형태로 구성한다.  String sql = "select username, email from jdbc_test";
  // select 를 수행하면 데이터정보가 ResultSet 클래스의 인스턴스로 리턴됨.  ResultSet rs = stmt.executeQuery(sql);
  int i=1;
  // 마지막 데이터까지 반복함.  while(rs.next()) {
   out.println(i+" : "+rs.getString(1)+" , "+rs.getString("email")+"<BR>");
   i++;
  }
  // 사용한 자원의 반납.
  rs.close();
  stmt.close();
  conn.close();
 }
 catch(Exception e) {
  System.out.println(e);
 }
%>
</BODY>
</HTML>

JAVA] Java.util.HashMap() 분석



원본 출처 : http://iilii.egloos.com/4457500


HashMap은 Object.hashCode()를 이용하는 java.util.Map 인터페이스의 구현체입니다. 대표적인 Map의 구현체입니다. Map의 주요 구현체는 이 외에 Hashtable과 TreeMap이 있습니다. Hashtable은 이 글에서 함께 설명할 것이고, TreeMap의 구현에 대해서는 따로 정리를 하겠습니다.

일단 Map의 기본 컨셉은 Key-Value입니다. 주민등록번호와 개인 정보같은 경우를 생각하시면 됩니다. 어떤 주민등록번호를 입력하면, 그 사람의 개인정보를 볼 수 있도록 하겠다는 겁니다. 맵에 정보를 추가하는 것은 put(K key, V value)로 정의됩니다. K는 Key의 타입이고 V는 Value의 타입입니다. 주민번호의 예를 들자면, K는 주민등록번호 객체가 될 것이고, V는 개인정보 객체가 될 것입니다. 그리고, 맵에서 정보를 조회하는 것은 get(K key)입니다. put(key, value)로 저장이 된 value는 get(key)를 하면 가져올 수 있다는 겁니다.

간단한 코들를 보여드리자면, 아래와 같습니다.

Map<String, String> map = new HashMap<String, String>();
map.put("key", "value");
String b = map.get("key");

위의 코드에서 b는 "value"라는 String을 가집니다.

HashMap과 Hashtable의 큰 차이는 두 가지입니다.
첫째, HashMap은 null키와 null값을 허용합니다. 허나, Hashtable은 허용하지 않습니다.
둘째, HashMap은 synchronized가 없습니다. 하지만 Hashtable은 대부분의 method가 synchronized로 처리가 됩니다.

이제부터는 HashMap을 중심으로 얘기할 것이며, 위에서 얘기한 두 가지 차이점을 제외하고는 Hashtable도 거의 유사하다고 보시면 됩니다.

1. 순서 보장하지 않음

Map 에 보면, keySet()이라는 메쏘드가 있습니다. 어떤 키값들이 들어있는지 알려주는 겁니다. HashMap의 경우 keySet()으로 받아온 데이터는 입력한 순서와 무관하며, 호출할 때마다 순서가 달라질 수도 있습니다. 따라서 어떠한 순서에도 의존해서는 안 됩니다. 입력한 순서대로 데이터를 받아오고자 한다면, LinkedHashMap을 사용하셔야 하며, 정렬된 순서대로 쓰고자 한다면 TreeMap을 써야 합니다.

2. hashCode()와 equals()

put, get에 있어서 모두 hashCode()와 == 연산 및 equals()를 사용합니다. value와는 전혀 상관없고, key에 대해서만 이런 방식을 씁니다. hashCode()를 사용하는 것은 두 가지 의미가 있는데, 첫째는 equals()에 비해 부하가 적다는 것입니다. 두번째는 hashCode() 값을 기준으로 분류가 가능하다는 것입니다. 두번째의 의미가 훨씬 큽니다. 잠시 후 자세히 설명하겠습니다.
일단 hashCode()를 가지고 비교를 하고 == 로 비교해서 true를 리턴하거나 equals()로 비교해서 true를 리턴하는 지 체크해서 기존 element를 덮어 쓸 것인지를 결정합니다.
hashCode()는 java.lang.Object에 정의가 되어 있으며, 여기에 정리가 되어있습니다.

3. bucket

HashMap은 내부적으로 bucket을 사용합니다. bucket은 Map이 가지는 element들을 적당히 분산시켜 놓는 것입니다. Map이 서랍장이라면, bucket은 각각의 서랍이 라고 생각하시면 됩니다. 첫번째 서랍에는 양말이 두번째 서랍에는 티셔츠가 세번째 서랍에는 바지가 있다면 서랍장 전체를 뒤지지 않아도 찾고자하는 것을 찾을 수 있을 겁니다. 즉, "파란 양말"을 찾기 위해서는 양말 서랍만 찾으면 됩니다.
element가 어떤 bucket에 들어가게 될지는 그 element의 hashCode()값에 의해 결정됩니다. bucket이 n개가 있다면, element는 그 hashCode()%n 번째 bucket에 들어갑니다.(대략적으로 그렇단 얘기고, 정확히 얘기하면 비트연산으로 처리됩니다.) element를 가져올 때 입력되는 키는 같은 bucket에 있는 element 들만 비교를 하게 됩니다. bucket 수가 많으면 한 bucket에 들어가는 element의 수가 적을 것이고, 이는 속도를 향상시키는 길이 됩니다.
데 이터를 이래저래 추가하고 한 번에 뽑아서 따로 저장하는 로직을 생각해봅시다. 데이터를 추가하는 부분에 비해 뽑아쓰는 부분이 적기 때문에 bucket을 작게 유지하는 게 유리해 보이지만 그렇지 않습니다. 왜냐하면, get()이 호출될 때 뿐만 아니라 put()이 호출될 때도 기존에 데이터가 있는 지 확인하는 작업이 다시 한번 실행된다는 것입니다. 키값이 기존에 있던 것과 동일하면, 새로운 입력되는 값이 기존 값을 덮어쓰게 됩니다. 따라서 새로운 element가 추가될 때 그 버킷 안의 모든 element에 대해 새로 추가될 element와 같은 것인지 검사를 합니다. 다시 말해 그 bucket의 모든 element에 대해 hashCode()가 호출되고, 추가될 element와는 == 연산이나 equals()를 통해 비교를 하게 됩니다.

4. 용량과 load factor

용량은 bucket의 수입니다. element의 수가 아닙니다. 기본값은 16입니다. 만약에 한 16만개 정도의 데이터를 16개의 bucket에 담는다면, get을 할 때 평균 1만개의 element와 비교를 해야 합니다. 굉장히 비효율적이죠. 그래서 상황에 따라 bucket의 수가 확장되어야 할 경우가 있습니다. 총 element의 수와 용량간에 어떤 연관성이 있어야 하는데, 그게 바로 load factor입니다. load factor= 총 수용가능한 element의 수 / 용량  으로 정의 됩니다.
HashMap 에는 총 수용가능 element의 수를 늘이는 메쏘드가 없습니다. put() 메쏘드 즉, element의 수를 증가시킬 수 있는 메쏘드가 실행될 때 알아서 수용가능 용량을 계산해서 이 값이 (load factor * 용량)을 넘어서게 되면, bucket 수를 대략 2배로 늘이고(즉, 용량이 2배로 늘어납니다.) 모든 element에 대해 다시 hashCode를 호출하여 어느 bucket으로 들어갈 것인지 다시 계산을 합니다. 이 과정을 rehashing이라 하며 부하가 굉장히 큽니다. element수를 감소 시키는 remove() 메쏘드는 rehashing을 하지 않습니다.
따라서 처음에 어느정도 용량이 들어갈 것인지 예측할 수 있다면, 처음부터 크기를 적절히 해서 rehashing이 가능한 한 적게 일어나도록 해야 합니다. HashMap(int initialCapacity) 생성자를 사용하면, 초기 용량이 16이 아닌 다른 값을 쓸 수 있습니다.

그 렇다고 초기 용량을 무조건 크게 잡는 것은 능사가 아닙니다. 지나치게 크게 잡을 경우 다음과 같은 문제가 생길 수 있습니다. 첫째, 메모리 낭비가 발생합니다. 둘째, key에 대한 iteration을 돌 때 부하가 커집니다. iteration의 부하는 (bucket의 수 + 실제 인스턴스의 크기) 에 비례합니다.

load factor가 크면  (즉, 한 bucket에 많은 element를 넣게 되면) 메모리 절약은 할 수 있으나, 검색이 힘들어 집니다. 반대로 너무 작으면(bucket의 수가 너무 많으면,) 검색은 빠르겠지만, 메모리 상의 낭비가 일어나게 됩니다. 그래서 가장 최적의 값은 일반적으로 0.75라고 합니다. HashMap은 load factor의 기본값을 이 값으로 하고 있지만,  HashMap(int initialCapacity, float loadFactor) 생성자를 통해 load factor를 변경시킬 수 있습니다. 메모리 좀 낭비해도 속도가 중요하다고 생각하면 load factor를 낮추면 됩니다.

5. 동기화되지 않음

처음에 말씀드렸다시피 HashMap은 동기화가 되지 않습니다. Hashtable과의 큰 차이점이죠. 단지 put, get에 대한 문제만은 아닙니다. 학생번호-몸무게 를 key-value로 가지는 HashMap 객체에 대해 학생의 몸무게 평균을 구하려고 하면, 학생의 리스트 즉, HashMap 객체의 keySet을 뽑아와야 합니다. 열심히 루프 돌면서 계산하는 와중에 다른 쓰레드에서 어떤 요소를 추가하거나 삭제하게 되면, 일이 난감해집니다. HashMap은 이런 상황에서 fail-fast 방식으로 처리합니다. (fail-fast: 어떤 에러나 또는 에러를 발생시킬 만한 상황에서 더 이상 정상적인 작업을 진행하지 않도록 해주는 거)
만약 동기화 과정이 필요하다면, Map m= Collections.synchronizedMap(new HashMap(...)); 와 같이 Collections.synchronizedMap() 을 이용하는 것이 좋습니다.

사족으로 알아도 몰라도 별로 달라질 게 없는 HashMap관련 지식 하나!

HashMap은 순서를 보장하지 않는다고 했습니다. 보장되지 않는 순서의 비밀을 파헤쳐봅시다!!
bucket은 Entry라는 내부 클래스의 array로 정의 됩니다.
각 bucket은 처음에 null로 세팅이 되어있고, 어떤 element가 들어오면 Entry 객체를 생성해서 대입합니다. bucket이 서랍이라고 설명한 것은 이해를 돕기 위한 것이고, 코드 상 정확히 말하면 bucket은 어떤 Entry를 말하는 겁니다. Entry는 key와 value 그리고 next 3가지의 멤버 변수로 구성이 됩니다. 여기서 next는 다음 Entry를 가질 수 있는 구조입니다. Linked List라는 거죠.
null이 아닌 bucket에 대해 어떤 element가 추가될 때는 그 bucket의 Entry 객체를 next로 세팅한 새로운 Entry 객체를 생성해서 bucket의 자리를 넣습니다. 뒤에 붙이는 것이 아니라 앞에 붙이는 구조가 되지요. (일반적인 Linked List는 뒤에 붙입니다.)

keySet() 얘기를 해보죠. bucket을 0번째부터 끝까지 루프를 돕니다. 즉, bucket 수만큼 루프를 돕니다. 어떤 bucket에 entry가 있으면, 그 entry의 key를 뽑아냅니다. 그리고그 entry의 next에 대해서 같은 작업을 합니다. next가 null일 때까지 루프돌고 null이면 다음 버킷으로 넘어갑니다. 즉,모든 bucket에 대해서 같은 작업을 하면 element의 수만큼 루프를 돌게 되겠지요. 결과적으로 keySet()의 비용은 (bucket의 수 + element의 수) 가 됩니다. 그리고 뽑히는 순서는 bucket 번호가 작은 놈이 먼저 나오고, 그 중에서는 나중에 들어간 놈이 먼저 나옵니다. 즉, 넣는 순서에 따라 순서가 달라질 수도 있다는 겁니다.

JAVA] java properties 사용법



출처 : http://umzzil.egloos.com/2175356


java.util.Properties 클래스를 사용하여 설정 파일을 제어하는 샘플이다.
import java.util.*;
import java.io.*;

public class PropertyTest {
    private String PROPERTIES_FILE = "C:\\globals.properties";
   

    /**
     * 특정 키값을 반환한다.
     */

    private String getProperty(String keyName) {
        String value = null;
 
        try {
            Properties props = new Properties();
            FileInputStream fis = new FileInputStream(PROPERTIES_FILE);
            props.load(new java.io.BufferedInputStream(fis));
            value = props.getProperty(keyName).trim();
            fis.close();
        } catch (java.lang.Exception e) {
            System.out.println(e.toString());
        }
            return value;
    }


    /**
     * 특정 키 이름으로 값을 설정한다.
     */

    private void setProperty(String keyName, String value) {
        try {
            Properties props = new Properties();
            FileInputStream fis  = new FileInputStream(PROPERTIES_FILE);
            props.load(new java.io.BufferedInputStream(fis));
            props.setProperty(keyName, value);
            props.store(new FileOutputStream(GLOBALS_PROPERTIES_FILE), "");
            fis.close();

        } catch(java.lang.Exception e) {
            System.out.println(e.toString());
        }
    }
 


    public static void main(String args[]) {
        PropertyTest o = null;
        if (args.length == 1) {
            o = new PropertyTest();
            System.out.println(args[0] + ":[" + o.getProperty(args[0]) + "]");
        } else if (args.length == 2) {
            o = new PropertyTest();
            o.setProperty(args[0], args[1]);
            System.out.println(args[0] + ":[" + o.getProperty(args[0]) + "]");
        } else {
            System.out.println("wrong argument");
        }
    }
}



======================================================================================================================
====================================      properties 파일 경로 쉽게 찾기     =======================================

java로 프로그래밍을 하다가 보면 몇가지 설정값을 외부에서 받아야 하는 경우가 있는데 이때 사용하는 것이 property 파일이다.

jdk에도 이 프로퍼티 파일을 다룰 수 있는 클래스가 마련되어 있다. java.util.Properties 클래스가 그 용도이다.

이 클래스를 사용하려면 load라는 메소드를 통해서 프로퍼티 파일일 읽어 와야 하는데 이때 전달되는 인자는 InputStream이다.

문제는 이 InputStream을 전달하려면 FileInputStream을 만들어서 전달해야 하는데 이 FileInputStream을 생성하려면 그 프로퍼티 파일의 경로를 알아야 한다는 것이다.



프로퍼티 파일의 경로를 알아오는 방법에 대해서 몇가지 생각해 보자

1. 프로그램 코드에 상수로 프로터피 파일의 경로를 둔다.

예를들면,

public staitc final String PATH = "/app/myapp/myprop.properties";

라고 두는 것이다. 뭐 이건 말 안해도 알겠지만 별로 좋지 않은 방법이다. 경로나 이름이 바뀌면 새로 컴파일 해야 하고, 뭐 이래저래 좋지 않은거 같다.


2. java 실행 옵션으로 세팅해서 프로그램에서 사용한다.

java 프로그램을 실행시킬 때 실행 옵션으로 프로퍼티 파일의 경로를 줘서 그 옵션값을 읽어서 경로로 사용하도록 하는 것이다.

String path = System.getProperty( "path" );

라는 형태로 사용하면 실행시 준 옵션값을 가져올 수 있다.

이 방법도 많이 사용하는 방법으로 나름대로 쓸만하다. 그렇지만 실행시 옵션을 설정한다는 것이 별로 마음에 안든다.


3. ClassLoader를 사용하여 가져온다.

혹 시 이거 신기하게 생각해 본 사람이 있을지 모르겠는데, log4j를 사용하다 보면 log4j.properties라는 파일을 생성해 두면 내가 특별히 경로를 세팅하지 않았는데도 log4j가 알아서 log4j.properties를 읽어서 사용한다. 나는 처음에 이게 무지 신기했다. log4j가 어떻게 알고 그 위치의 log4j.properties를 읽어 들이는 걸까?

해답은 ClassLoader 였다.

classloader의 주요 기능은 클래스를 로딩하는 것이다.(이름에서 알 수 있는 너무 당연한 이야긴가? ^^;)

하지만 기능이 한가지 더 있는데 바로 클래스 파일 뿐아니라 다른 리소스 파일도 읽어 주는 역할이다.
ClassLoader.getResource( String name )이 그 역할을 하는 메소드다(이 메소드 외에도 getResource... 메소드들이 몇가지 더 있다. 알아서 찾아 보시길...)

이 getResource는 클래스 패스내에서 해당 이름으로 된 파일을 찾아서 그 URL을 넘겨준다. 중요한 포인트는 바로 클래스 패스 내에 있는 파일이라는 것이다.

java 를 실행시킬때 -classpath라고 주는 바로 그 클래스 패스 말이다. 즉 classpath에 설정한 클래스 패스내에 프로퍼티 파일을 두면 ClassLoader를 통해서 프로퍼티 파일을 가져올 수 있는 것이다. 별거 아닌 기능 같지만 쓰다보면 상당히 편리하다.

실제 구현 내용을 간단히 살펴보면 다음과 같다.

        ClassLoader cl;
        cl = Thread.currentThread().getContextClassLoader();
        if( cl == null )
            cl = ClassLoader.getSystemClassLoader();
               
        URL url = cl.getResource( "myprop.properties" );

위 내용은 log4j의 소스에서 일부 참조한 것이다.

위 소스를 참조해서 쉽게 프로퍼티 파일을 다룰 수 있는 클래스를 만들어 보는 것도 좋을 듯 하다.

Java] InputStream 을 String으로 변환하기


 InputStream 을  String으로 변환하는 방법


 춮처 : http://www.kodejava.org/examples/266.html

package org.kodejava.example.io;

import java.io.InputStream;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class StreamToString {

    public static void main(String[] args) throws Exception {
        StreamToString sts = new StreamToString();

        /*
         * Get input stream of our data file. This file can be in the root of
         * you application folder or inside a jar file if the program is packed
         * as a jar.
         */
        InputStream is = sts.getClass().getResourceAsStream("/data.txt");

        /*
         * Call the method to convert the stream to string
         */
        System.out.println(sts.convertStreamToString(is));
    }

    public String convertStreamToString(InputStream is) throws IOException {
        /*
         * To convert the InputStream to String we use the BufferedReader.readLine()
         * method. We iterate until the BufferedReader return null which means
         * there's no more data to read. Each line will appended to a StringBuilder
         * and returned as String.
         */
        if (is != null) {
            StringBuilder sb = new StringBuilder();
            String line;

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } finally {
                is.close();
            }
            return sb.toString();
        } else {      
            return "";
        }
    }
}

Java] Ibatis 다중링크 사용



출처 : http://mimul.com/pebble/default/2008/02/24/1203779580000.html



웹 어플리케이션에서 하나 이상의 데이터 베이스에 접근하여 어플리케이션이 실행되는 환경들이 많을 것입니다.
iBatis에서 어떻게 활용되는 지 사용방법을 공유합니다.
사용환경은 iBatis와 DBCP입니다.
  1. database.properties

    driver=oracle.jdbc.driver.OracleDriver
    jdbc.url1=jdbc:oracle:thin:@mimuluserdb:1521:mimuluser
    username1=mimuluser
    password1=mimuluser

    jdbc.url2=jdbc:oracle:thin:@pepsiuserdb:1521:pepsiuser
    username2=pepsiuser
    password2=pepsiuser
  2. sqlmap1.xml 
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE sqlMapConfig
            PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
            "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
    <sqlMapConfig>
        <properties resource="com/mimul/dwr/app/
                   resource/database.properties"/>
        <settings
                cacheModelsEnabled="true"
                enhancementEnabled="true"
                lazyLoadingEnabled="true"
                maxRequests="40"
                maxSessions="20"
                maxTransactions="5"
                useStatementNamespaces="false"
                />
        <transactionManager type="JDBC">
            <dataSource type="DBCP">
                <property name="driverClassName" value="${driver}"/>
                <property name="url" value="${jdbc.url1}"/>
                <property name="username" value="${username1}"/>
                <property name="password" value="${password1}"/>

                <!-- OPTIONAL PROPERTIES BELOW -->
                <property name="initialSize" value="5"/>
                <property name="maxActive" value="30"/>
                <property name="maxIdle" value="20"/>
                <property name="maxWait" value="60000"/>
                <property name="poolPreparedStatements" value="true"/>
                <property name="validationQuery" value="select 0 from dual"/>
                <property name="testOnBorrow" value="true"/>
                <property name="maximumActiveConnections" value="10"/>
                <property name="maximumIdleConnections" value="5"/>
                <property name="maximumWait" value="60000"/>
                <property name="logAbandoned" value="false"/>
                <property name="removeAbandoned" value="false"/>
                <property name="removeAbandonedTimeout" value="50000"/>
            </dataSource>
        </transactionManager>
        <sqlMap resource="com/mimul/dwr/app/sql/Mimul.xml"/>
    </sqlMapConfig>
  3. sqlmap2.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE sqlMapConfig
            PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
            "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
    <sqlMapConfig>
        <properties resource="com/mimul/dwr/app/resource/database.properties"/>
        <settings
                cacheModelsEnabled="true"
                enhancementEnabled="true"
                lazyLoadingEnabled="true"
                maxRequests="40"
                maxSessions="20"
                maxTransactions="5"
                useStatementNamespaces="false"
                />
        <transactionManager type="JDBC">
            <dataSource type="DBCP">
                <property name="driverClassName" value="${driver}"/>
                <property name="url" value="${jdbc.url2}"/>
                <property name="username" value="${username2}"/>
                <property name="password" value="${password2}"/>

                <!-- OPTIONAL PROPERTIES BELOW -->
                <property name="initialSize" value="5"/>
                <property name="maxActive" value="30"/>
                <property name="maxIdle" value="20"/>
                <property name="maxWait" value="60000"/>
                <property name="poolPreparedStatements" value="true"/>
                <property name="validationQuery" value="select 0 from dual"/>
                <property name="testOnBorrow" value="true"/>
                <property name="maximumActiveConnections" value="10"/>
                <property name="maximumIdleConnections" value="5"/>
                <property name="maximumWait" value="60000"/>
                <property name="logAbandoned" value="false"/>
                <property name="removeAbandoned" value="false"/>
                <property name="removeAbandonedTimeout" value="50000"/>
            </dataSource>
        </transactionManager>
        <sqlMap resource="com/mimul/dwr/app/sql/Pepsi.xml"/>
    </sqlMapConfig>
  4. SqlConfig.java
    import java.io.File;
    import java.io.Reader;

    import com.ibatis.common.resources.Resources;
    import com.ibatis.sqlmap.client.SqlMapClient;
    import com.ibatis.sqlmap.client.SqlMapClientBuilder;
    import com.jaeminara.common.log.LogPool;

    public class SqlConfig {
        private static SqlMapClient sqlMap1 = null;
        private static SqlMapClient sqlMap2 = null;
        private static SqlConfig instance_ = null;
      
        private SqlConfig() throws Exception
        {
            Reader reader = null;
            String resource = null;
            try {
                if (sqlMap == null) {
                    resource = "sqlmap1.xml";
                     reader = Resources.getResourceAsReader(resource);
                     sqlMap1 = SqlMapClientBuilder.buildSqlMapClient(reader);
                    resource = "sqlmap2.xml";
                     reader = Resources.getResourceAsReader(resource);
                     sqlMap2 = SqlMapClientBuilder.buildSqlMapClient(reader);
                     reader.close();
                }
            } catch (Exception e) {
                System.out.println(e);
                throw e;
            } finally {
                if (reader != null)
                    reader.close();
                reader = null;
                rsc = null;
            }
        }
      
        public static SqlConfig instance()
        {
            try {
                if (instance_ == null) {
                    synchronized (SqlConfig.class) {
                        if (instance_ == null)
                            instance_ = new SqlConfig();
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
            return instance_;
        }

        /**
         * Return SqlMapClient for SDP schema
         *
         * @return
         */
        public static SqlMapClient getSqlMap1Instance()
        {
            return sqlMap1;
        }

        /**
         * Return SqlMapClient for SDP schema
         *
         * @return
         */
        public static SqlMapClient getSqlMap2Instance()
        {
            return sqlMap2;
        }
    }