캠핑과 개발

메일 발송이나 초대장 발송등의 경우 내용은 동일하지만 몇가지의 정보만 변경되는 경우가 많다.
이런 경우에 MessageFormat 을 사용하면 괜찮겠다.

/**
 *
 */
package kr.pe.anaconda.test;

import java.io.File;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Scanner;

/**
 * @author diem
 *
 */
public class MessageFormatTest {
 
 /**
  * msg 문자열에  {숫자}로 지정된 영역을 arguments 배열에 담긴 값으로 채워준다. 
  */
 private static void exam1(){
  String msg = "Name: {0} \nTel: {1} \nAge: {2} \nBirthday: {3}. ";
  Object[] arguments = {"홍길동", "123-1234-1234", "31", "06-22"};
  String result = MessageFormat.format(msg, arguments);
  System.out.println(result);
 }
 
 /**
  * 일정한 형식의 문자열에 패턴에 지정된 문자열을 입력한다.
  */
 private static void exam2(){
  String tableName = "USER";
  String msg = "INSERT INTO " +
    tableName +
    " VALUES (''{0}'', ''{1}'', ''{2}'', ''{3}'');";
  
  Object[][] arguments = {
    {"홍길동", "02-123-1234", "19", "10-11"},
    {"전우치", "02-123-1235", "520", "10-15"}    
  };
  
  for(int i = 0; i < arguments.length; i++){
   String result = MessageFormat.format(msg, arguments[i]);
   System.out.println(result);
  }
 }
 
 /**
  * 문자열에서 지정된 패턴으로 데이터를 추출한다.
  * @throws ParseException
  */
 private static void exam3() throws ParseException{
  String[] data = {
   "INSERT INTO USER VALUES ('홍길동', '02-123-1234', '19', '10-11');",
   "INSERT INTO USER VALUES ('전우치', '02-123-1235', '520', '10-15');"
  };
  
  String pattern = "INSERT INTO USER VALUES ({0}, {1}, {2}, {3});";
  MessageFormat mf = new MessageFormat(pattern);
  
  for(int i = 0; i < data.length; i++){
   Object[] objs = mf.parse(data[i]);
   for(int j = 0; j < objs.length; j++ ){
    System.out.println(objs[j]);
   }
  }
 }
 
 
 /**
  * 지정된 문자열에 정해진 패턴에 맞게 파일에서 정보를 읽어와서 데이타를 채운다.
  * user.text
  * '홍길동', '02-123-1234', '19', '10-11'
  * '전우치', '02-123-1235', '520', '10-15'  
  * @throws Exception
  */
 private static void exam4() throws Exception{
  String tableName = "USER";
  String fileName = "c:\\Noname2.txt";
  String msg = "INSERT INTO " +
   tableName +
   " VALUES (''{0}'', ''{1}'', ''{2}'', ''{3}'');";
  File file = new File(fileName);
  if(file.exists()){
   Scanner s = new Scanner(file);
   String pattern = "{0},{1},{2},{3}";
   MessageFormat mf = new MessageFormat(pattern);
   while(s.hasNextLine()){
    String line = s.nextLine();
    Object[] objs = mf.parse(line);
    System.out.println(MessageFormat.format(msg, objs));
   } 
   
   //작업이 완료 되면 파일을 닫아준다.
   s.close();
  }  
 }

 /**
  * @param args
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  //exam1();
  //exam2();
  //exam3();
  exam4();
 }

}



java.util.Properties 파일 사용 예제

package kr.pe.anaconda.test.io.file;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author diem
 * 
 */
public class PropertiesSample {

	private static String defaultPropertiesPath = "c:\\example.properties";

	public static String getDefaultPropertiesPath() {
		return defaultPropertiesPath;
	}

	public static void setDefaultPropertiesPath(String defaultPropertiesPath) {
		PropertiesSample.defaultPropertiesPath = defaultPropertiesPath;
	}

	public static String getKey(String key) throws Exception {

		// ClassLoader.getResourceAsStream("some/pkg/resource.properties");
		// Class.getResourceAsStream("/some/pkg/resource.properties");
		// ResourceBundle.getBundle("some.pkg.resource");
		String value = null;
		InputStream is = new FileInputStream(defaultPropertiesPath);
		Properties p = null;
		try {
			p = new Properties();
			p.load(is);
			value = p.getProperty(key);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {is.close();} catch (IOException e) {}
		}
		return value;
	}

	/**
	 * 프로퍼티 파일에 사용자 값을 넣는다.
	 */
	public static void putPropertie(Map paramMap)
			throws FileNotFoundException, IOException {
		// 프로퍼티 파일 경로 key
		String propertiesKey = "properties.file.path";
		Properties proper = null;
		FileOutputStream output = null;
		try {
			String comment = paramMap.get("properties.comment");
			// 사용자가 프로퍼티 파일 경로를 넘기지 않을 경우 default properties로 셋팅하다.
			if (!paramMap.containsKey(propertiesKey)) {
				paramMap.put(propertiesKey, defaultPropertiesPath);
			}
			output = new FileOutputStream(paramMap.get(propertiesKey));
			// paramMap.remove(propertiesKey);
			proper = new Properties();
			proper.putAll(paramMap);
			proper.store(output, comment);
		} catch (FileNotFoundException fnfe) {
			throw new FileNotFoundException("properties 파일을 찾을수 없습니다.");
		} catch (IOException ioe) {
			throw new IOException("putPropertie Exception!", ioe);
		} finally {
			try {
				output.close();
			} catch (IOException e) {
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Map paramMap = new HashMap();
		paramMap.put("properties.file.path", "c:\\example12.properties");
		paramMap.put("name", "홍길동");
		paramMap.put("age", "31");
		paramMap.put("phone", "0111234567");
		PropertiesSample.putPropertie(paramMap);

		PropertiesSample.setDefaultPropertiesPath(paramMap
				.get("properties.file.path"));

		System.out.println(PropertiesSample.getDefaultPropertiesPath());
		System.out.println(PropertiesSample.getKey("name"));
	}
}


날씨가 조금 추워지네요..
요즘 아이폰 만지는 재미에 아침이 밝아 오는지도 모르고 유용한 어플을 찾아서 헤매고 있습니다. 이제 좀 정신좀 차려야 되는데 말이죠.. ㅜㅜ

간단하게 ResourceBundle을 사용하는 법을 올려봅니다.
좀 더 사용하기 쉽게 만들수도 있겠지만 그건 개인에 따라서 수정하면 될테고 어떻게 사용되는지만 알면 수정은 쉬우니까요^^


package pe.kr.anaconda.hmjkor.util;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * @author diem
 *
 */
public class ResourceUtil {
	
	
	/*
	 * url.properties
	 * url = http://hmjkor.tistory.com
	 */
	private static final String CONF_PATH = "config.url";	
	private static ResourceBundle resource = ResourceBundle.getBundle(CONF_PATH);
	private static HashMap sourceMap = new HashMap();
	
	static{
		Enumeration enu = resource.getKeys();
		String key = null;
		while(enu.hasMoreElements()){
			key = enu.nextElement();
			sourceMap.put(key, resource.getString(key));
		}		
	}	
	public static String getKey(String key){
		return sourceMap.get(key);
	}
	
	public static Map getSourceMap(){
		return sourceMap;
	}
	
	public static void main(String args){
		System.out.println(ResourceUtil.getKey("url"));
	}
}

 파일 클래스 속성 및 사용법

1. File 클래스 및 속성
package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.io.IOException;

/**
 * File 클래스 사용법 및 속성
 * @author diem
 *
 */
public class FileEx1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		File f = new File("c:\\logs\\123.txt");
		
		String fileName = f.getName();
		int pos = fileName.lastIndexOf(".");
		
		System.out.println("경로를 제외한 파일 이름 : " + f.getName());
		System.out.println("확장자를 제외한 파일 이름 : " + fileName.substring(0, pos));
		System.out.println("확장자 : " + fileName.substring(pos + 1));
		System.out.println("경로를 포함한 파일이름 : " + f.getPath());
		System.out.println("파일의 절대경로 : " + f.getAbsolutePath());
		System.out.println("파일이 속해 있는 경로 : " + f.getParent());
		System.out.println();
		System.out.println("File.pathSeparator : " + File.pathSeparator);
		System.out.println("File.pathSeparatorChar : " + File.pathSeparatorChar);
		System.out.println("File.separator : " + File.separator);
		System.out.println("File.separatorChar : " + File.separatorChar);
		System.out.println();
		System.out.println("user.dir : " + System.getProperty("user.dir"));
		System.out.println("sun.boot.class.path : " + System.getProperty("sun.boot.class.path"));
	}
}


2. 파일 리스트
package kr.pe.anaconda.test.io.file;

import java.io.File;

/**
 * 디렉터리 리스트
 * @author diem
 *
 */
public class FileEx2 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		if(args.length != 1){
			System.out.println("USAGE : java FileEx2 DIRECTORY");
			System.exit(0);
		}
		File f = new File("c:\\log");
		//File f = new File(args[0]);
		
		if(!f.exists() || !f.isDirectory()){
			System.out.println("유효하지 않은 디렉토리입니다.");
			System.exit(0);
		}
		
		File[] files = f.listFiles();
		
		for(int i = 0; i < files.length; i++){
			String fileName = files[i].getName();
			System.out.println(files[i].isDirectory() ? "["+ fileName +"]" : fileName);
		}
	}
}

3. 파일 디렉터리의 파일 갯수와 디렉터리 숫자 보여주기
package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.util.ArrayList;

/**
 * 특정 디렉터리의 파일의 갯수와 디렉터리의 숫자를 보여준다.
 * @author diem
 *
 */
public class FileEx3 {

	static int totalFiles = 0;
	static int totalDirs = 0;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub	
		
		if(args == null || args.length == 0){
			args = new String[1];
		}
		
		System.out.println(args.length);
		
		args[0] = "c:\\logs";
		
		if(args.length != 1){
			System.out.println("USAGE : java FileEx3 DIRECTORY");
			System.exit(0);
		}
		
		File dir = new File(args[0]);
		if(!dir.exists() || !dir.isDirectory()){
			System.out.println("유효하지 않은 디렉토리입니다.");
			System.exit(0);
		}
		
		printFileList(dir);
		System.out.println();
		System.out.println("총 " + totalFiles + "개의 파일");
		System.out.println("총 " + totalDirs + "개의 디렉터리");
		
	}

	public static void printFileList(File dir) {
		System.out.println(dir.getAbsolutePath() + " 디렉터리");
		File[] files = dir.listFiles();
		
		ArrayList subDir = new ArrayList();
				
		for(int i = 0; i < files.length; i++){
			String fileName = files[i].getName();
			if(files[i].isDirectory()){
				fileName = "["+ fileName +"]";
				subDir.add(i+"");
			}
			System.out.println(fileName);
		}
		
		int dirNum = subDir.size();
		int fileNum = files.length - dirNum;
		
		totalFiles += fileNum;
		totalDirs += dirNum;
		
		System.out.println(fileNum + "개의 파일, " + dirNum + "개의 디렉터리");
		System.out.println();
		
		for(int i = 0; i < subDir.size(); i++){
			int index = Integer.parseInt((String)subDir.get(i));
			printFileList(files[index]);
		}
	}
}

4. 파일 리스트를 출력

package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.text.SimpleDateFormat;

/**
 * 파일 리스트를 출력한다.
 * 출력시 파일의 속성과 수정일을 함께 출력한다.
 * @author diem
 *
 */
public class FileEx4 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub	
		String currDir = System.getProperty("user.dir");
		File dir = new File(currDir);
		
		File[] files = dir.listFiles();
		
		for(int i = 0; i < files.length; i++){
			File f = files[i];
			String name = f.getName();
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mma");
			String attribute = "";
			String size = "";
			
			if(files[i].isDirectory()){
				attribute = "DIR";
			}else{
				size = f.length() + "";
				attribute = f.canRead() ? "R" : "";
				attribute += f.canWrite() ? "W" : "";
				attribute += f.isHidden() ? "H" : "";
			}
			
			System.out.printf("%s %3s %6s %s\n", df.format(f.lastModified()), attribute, size, name);
		}
	}
}

5. 파일 정렬
package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;

/**
 * 파일 정렬을 한다.
 * @author diem
 *
 */
public class FileEx5 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		if (args.length != 1 || args[0].length() != 1
				|| "tTlLnN".indexOf(args[0]) == -1) {
			System.out.println("USAGE : java FileEx5 SORT_OPTION ");
			System.out.println("	SORT_OPTION : 				");
			System.out.println(" 	t Time asending sort.		");
			System.out.println("	T Time descending sort.		");
			System.out.println("	l Length ascending sort.	");
			System.out.println("	L Length descending sort.	");
			System.out.println("	n Name asending sort.		");
			System.out.println("	N Name descending sort.		");
		}

		final char option = args[0].charAt(0);

		String currDir = System.getProperty("user.dir");
		File dir = new File(currDir);

		File[] files = dir.listFiles();

		Comparator comp = new Comparator() {
			public int compare(Object o1, Object o2) {
				long time1 = ((File) o1).lastModified();
				long time2 = ((File) o2).lastModified();

				long length1 = ((File) o1).length();
				long length2 = ((File) o2).length();

				String name1 = ((File) o1).getName().toLowerCase();
				String name2 = ((File) o2).getName().toLowerCase();

				int result = 0;

				switch (option) {
				case 't':
					if (time1 - time2 > 0)
						result = 1;
					else if (time1 - time2 == 0)
						result = 0;
					else if (time1 - time2 < 0)
						result = -1;
					break;
				case 'T':
					if (time1 - time2 > 0)
						result = -1;
					else if (time1 - time2 == 0)
						result = 0;
					else if (time1 - time2 < 0)
						result = 1;
					break;
				case 'l':
					if (length1 - length2 > 0)
						result = -1;
					else if (length1 - length2 == 0)
						result = 0;
					else if (length1 - length2 < 0)
						result = 1;
					break;
				case 'L':
					if (length1 - length2 > 0)
						result = 1;
					else if (length1 - length2 == 0)
						result = 0;
					else if (length1 - length2 < 0)
						result = -1;
					break;
				case 'n':
					result = name1.compareTo(name2);
					break;
				case 'N':
					result = name2.compareTo(name1);
					break;
				}
				return result;
			}

			public boolean equals(Object o) {
				return false;
			}
		};

		Arrays.sort(files, comp);

		for (int i = 0; i < files.length; i++) {
			File f = files[i];
			String name = f.getName();
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mma");
			String attribute = "";
			String size = "";

			if (files[i].isDirectory()) {
				attribute = "DIR";
			} else {
				size = f.length() + "";
				attribute = f.canRead() ? "R" : "";
				attribute += f.canWrite() ? "W" : "";
				attribute += f.isHidden() ? "H" : "";
			}

			System.out.printf("%s %3s %6s %s\n", df.format(f.lastModified()),
					attribute, size, name);
		}
	}
}


6. 특정 확장자를 가진 파일 출력
package kr.pe.anaconda.test.io.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * 특정 확장자를 가진 파일을 출력한다.
 * @author diem
 *
 */
public class FileEx6 {

	static int found = 0;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 2) {
			System.out.println("USAGE : java FileEx6 DIRECTORY KEYWORD");
			System.exit(0);
		}

		File dir = new File(args[0]);
		String keyword = args[1];

		if (!dir.exists() || !dir.isDirectory()) {
			System.out.println("유효하지 않은 디렉터리 입니다.");
			System.exit(0);
		}

		try {
			findInFiles(dir, keyword);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void findInFiles(File dir, String keyword) throws IOException {
		// TODO Auto-generated method stub
		File[] files = dir.listFiles();

		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				findInFiles(files[i], keyword);
			} else {
				//파일이름
				String filename = files[i].getName();
				//파일 확장자
				String extension = filename
						.substring(filename.lastIndexOf(".") + 1);
				extension = "," + extension + ",";
				
				if(",java,txt,bak,".indexOf(extension) == -1) continue;
				
				filename = dir.getAbsolutePath() + File.separator + filename;
				
				FileReader fr = new FileReader(files[i]);
				BufferedReader br = new BufferedReader(fr);
				
				String data = "";
				int lineNum = 0;
				
				while((data = br.readLine()) != null){
					lineNum++;
					if(data.indexOf(keyword) != -1){
						found++;
						System.out.println("["+filename+"("+lineNum+") ]" + data);
					}					
				}
				br.close();
			}
		}
	}
}

7. 특정한 이름을 포함한 파일의 목록을 출력

package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.io.FilenameFilter;

/**
 * 특정한 이름을 포함한 파일의 목록을 보여준다.
 * @author diem
 *
 */
public class FileEx7 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 1) {
			System.out.println("USAGE : java FileEx7 pattern");
			System.exit(0);
		}
		
		String currDir = System.getProperty("user.dir");
		//currDir = "c:\\logs";

		File dir = new File(currDir);
		final String pattern = args[0];
		
		
		//String[] list = (FilenameFilter filter)
		String[] files = dir.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				// TODO Auto-generated method stub
				return name.indexOf(pattern) != -1;
			}
		});
		
		for(int i = 0; i < files.length; i++){
			System.out.println(files[i]);
		}		
	}
}

8. 지정된 디렉터리에 정의한 확장자를 가진 파일을 삭제
package kr.pe.anaconda.test.io.file;

import java.io.File;
import java.io.FilenameFilter;

/**
 * 지정된 디렉터리에 정의한 확장자를 가진 파일을 삭제한다.
 * @author diem
 *
 */
public class FileEx8 {
	
	static int deleteFiles = 0;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 1) {
			System.out.println("USAGE : java FileEx8 Extension");
			System.exit(0);
		}
		
		String currDir = System.getProperty("user.dir");
		currDir = "c:\\logs";

		File dir = new File(currDir);
		//final String ext = "." + args[0];
		final String ext = ".bak";
		delete(dir, ext);
		System.out.println(deleteFiles + " 개의 파일이 삭제 되었습니다.");
	}

	private static void delete(File dir, String ext) {
		// TODO Auto-generated method stub
		
		File[] files = dir.listFiles();
		
		for(int i = 0; i < files.length; i++){
			if(files[i].isDirectory()){
				delete(files[i], ext);
			}else{
				String filename = files[i].getAbsolutePath();
				
				if(filename.endsWith(ext)){
					System.out.print(filename);
					if(files[i].delete()){
						System.out.println("-삭제 성공");
						deleteFiles++;
					}else{
						System.out.println("-삭제 실패");
					}
				}				
			}
		}		
	}		
}

9. 지정된 디렉터리에 파일명이 숫자인 경우 파일명을 변경
package kr.pe.anaconda.test.io.file;

import java.io.File;

/**
 * 지정된 디렉터리에 파일명이 숫자인 경우 파일명을 변경한다.
 * ex) 1.gif -> 00001.gif
 * @author diem
 *
 */
public class FileEx9 {	

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		if (args.length != 0) {
			System.out.println("USAGE : java FileEx9 DIRECTORY");
			System.exit(0);
		}
		
		//File dir = new File(args[0]);
		File dir = new File("c:\\logs");
		if(!dir.exists() || !dir.isDirectory()){
			System.out.println("유효하지 않은 디렉토리입니다.");
			System.exit(0);
		}
		
		File[] files = dir.listFiles();
		for(int i = 0; i < files.length; i++){
			String fileName = files[i].getName();
			//파일명
			System.out.println("파일이름 :" + fileName);
			String newFileName = "0000" + fileName;
			newFileName = newFileName.substring(newFileName.length() - 7);
			System.out.println("변경된 파일 이름 : " + newFileName );
			files[i].renameTo(new File(dir, newFileName));
		}
	}		
}

java에서 파일에 추가 라인을 입력하고 싶을때 옵션입니다. 15라인 참고하면 됩니다.

  1. package kr.pe.anaconda.test;
  2.  
  3. import java.io.FileNotFoundException;
  4. import java.io.FileWriter;
  5. import java.io.IOException;
  6. import java.io.PrintWriter;
  7.  
  8. public class Test {
  9.  
  10.     public static void main(String[] args) {       
  11.        
  12.         String file = "C:/logs/log.log";
  13.         PrintWriter pw = null;
  14.         try {
  15.             pw = new PrintWriter(new FileWriter(file, true));
  16.             pw.write(String.valueOf(System.currentTimeMillis()));
  17.             pw.write("\n");
  18.         } catch (FileNotFoundException e) {        
  19.             e.printStackTrace();
  20.         } catch (IOException e) {          
  21.             e.printStackTrace();
  22.         }finally{
  23.             if(pw != null) pw.close();
  24.         }
  25.     }
  26. }


JDBC 커넥션 풀을 지원하는 대표적인 오픈소스 중에 아파치 DBCPC3P0가 있다. 이들은 Spring, Hibernate 등과 통합되어 DB 커넥션 풀을 제공하는 DataSource를 구성하여 자주 쓰인다.

오라클이나 MySQL 등 DBMS들은 기본적으로 특정 시간동안 실행이 없으면 해당 세션을 종료하게 된다. 이렇게 종료된 커넥션은 어플리케이션에서 오류를 발생시키게 되므로 커넥션을 유지하기 위한 별도 설정을 필요로 하게 된다. 커넥션을 얻어올 때 커넥션 테스트를 수행하고 실패하면 새로운 커넥션을 생성할 수 있다. 또한 idle 타임에 주기적으로 커넥션 테스트를 수행할 수도 있다.

아래는 dbcp를 이용하여 구성한 스프링 DataSource 설정의 예이다.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
    <property name="driverClassName" 
value="oracle.jdbc.driver.OracleDriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="defaultAutoCommit" value="true"/> <property name="initialSize" value="5"/> <property name="maxActive" value="30"/> <property name="maxIdle" value="5"/> <property name="maxWait" value="30000"/> <property name="validationQuery" value="SELECT 1 FROM DUAL"/> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="false"/> <property name="testWhileIdle" value="true"/> <property name="timeBetweenEvictionRunsMillis" value="60000"/> </bean>


아래는 c3p0를 이용하여 구성한 스프링 DataSource 설정의 예이다.

<bean id="dataSource" 
class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
    <property name="driverClass" value="org.gjt.mm.mysql.Driver" />
    <property name="jdbcUrl" value="jdbc:mysql://localhost/testdb" />
    <property name="user" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="initialPoolSize" value="5" />
    <property name="maxPoolSize" value="30" />
    <property name="minPoolSize" value="5" />
    <property name="acquireIncrement" value="3" />
    <property name="acquireRetryAttempts" value="30" />
    <property name="acquireRetryDelay" value="1000" />
    <property name="idleConnectionTestPeriod" value="60" />
    <property name="preferredTestQuery" value="SELECT 1" />
    <property name="testConnectionOnCheckin" value="true" />
    <property name="testConnectionOnCheckout" value="false" />
</bean>


참조:
  - DBCP Configuration: http://commons.apache.org/dbcp/configuration.html
  - C3P0 Configuraion: http://www.mchange.com/projects/c3p0/index.html

출처 : http://www.java2go.net/blog/117


하드디스크 정보를 확인하는 코드
FIle 클래스에 요런게 있는지는 오늘 알았네요 ^^;;
기초 공부 좀 많이 해야겠습니다.

package test;
import java.io.File;
public class Test {
	public static void main(String[] args) {
		File[] roots = File.listRoots();
		for(File root: roots){
			System.out.println("드라이브명  " + root.getAbsolutePath());
			System.out.println("HDD 남은 공간 : " + root.getFreeSpace());
			System.out.println("HDD 사용 가능 공간 : " + root.getUsableSpace());
			System.out.println("HDD 사용 공간 : " + (root.getTotalSpace() - root.getFreeSpace()));
		}
	}
}

매번 찾기는 귀찮고 소스 뒤지기도 귀찮은 것들을 정리함.

#자바소스 설정

1
2
3
<build>
    <sourceDirectory>src/main/java</sourceDirectory>
</build>
cs


#자바소스 여러 개  설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.2</version>
    <executions>
        <execution>
            <id>add-source-dir</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>another/src/main/java</source>
                    <source>others/src</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>
cs




#저장소 추가

1
2
3
4
5
6
7
<repositories>
    <repository>
        <id>저장소 ID</id>
        <url>저장소 URL</url>
    </repository>
</repositories> 
cs


개인적으로만 저장소를 쓴다면 .m2\settings.xml에서
profiles > profile > repositories 밑에 repository 설정을 넣으면 됨.

#컴파일러 소스 및 타겟 버전 설정, UTF-8 인코딩 지정 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.0.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build> 
cs

#클래스패스 설정과 -jar 옵션으로 시작할 때 사용할 메인 클래스 지정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                        <manifestEntries>
                            <Main-Class>org.krakenapps.main.Kraken</Main-Class>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
cs

#의존하는 라이브러리를 포함하여 하나의 JAR 파일로 패키징
POM에 아래 설정해놓고 콘솔에서 mvn assembly:assembly 명령
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <Main-Class>org.krakenapps.main.Kraken</Main-Class>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
        </plugins>
    </build>
 
<!--//-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
        <warSourceDirectory>src/main/webapp</warSourceDirectory>    
          <!--<warSourceExcludes>common/**</warSourceExcludes> warSourceExcludes는 warSourceDirectory를 기준 특정 폴더 제외-->
       </configuration>
</plugin> 
cs
    

#기본 디렉토리 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- 변경전 --> 
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
    <wb-module deploy-name="questionbox">
        <wb-resource deploy-path="/" source-path="/src/main/webapp" />
        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources" />
        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java" />
        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java" />
        <property name="context-root" value="questionbox" />
        <property name="java-output-path" />
    </wb-module>
</project-modules>
<!-- 변경후 -->
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
    <wb-module deploy-name="questionbox">
        <wb-resource deploy-path="/" source-path="webapp" />
        <wb-resource deploy-path="/WEB-INF/classes" source-path="/src" />
        <property name="context-root" value="questionbox" />
        <property name="java-output-path" />
    </wb-module>
</project-modules>
cs

# 메이븐 /src/main/java에 java 외에 파일도 target/classes로 이동

#레포팅 관련
<reporting>
<plugins>
<!-- FindBugs 리포트 생성 플러그인 -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<forceEncoding>UTF-8</forceEncoding>
<findbugsXmlOutput>true</findbugsXmlOutput>
<findbugsXmlWithMessages>true</findbugsXmlWithMessages>
<xmlOutput>true</xmlOutput>
<xmlOutputDirectory>${basedir}/target/site</xmlOutputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>javancss-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<forceEncoding>UTF-8</forceEncoding>
<lineThreshold>30</lineThreshold>
<xmlOutputDirectory>${basedir}/target/site</xmlOutputDirectory>
<failOnViolation>true</failOnViolation>
<ccnLimit>10</ccnLimit>
<ncssLimit>100</ncssLimit>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jdepend-maven-plugin</artifactId>
<version>2.0-beta-2</version>
</plugin>
<!-- PMD 리포트 생성 플러그인 -->
<plugin>
<artifactId>maven-pmd-plugin</artifactId>
<configuration>
<rulesets>
<ruleset>/rulesets/basic.xml</ruleset>
<ruleset>/rulesets/unusedcode.xml</ruleset>
</rulesets>
<sourceEncoding>UTF-8</sourceEncoding>
<targetJdk>1.5</targetJdk>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</reporting>

#maven-jar-plugin 으로 배포시 특정파일 제외하기
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<excludes>
<exclude>*.properties</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>


#source도 depoly하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.1.2</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
cs


# 의존관계이 있는 jar파일을 특정 폴더로 복사

메이븐에서는 war이 아닌 jar 패키징일 경우 의존하는 라이브러리는 함께 패키징 되지 않는다.

이럴 경우 maven-dependency-plugin을 사용하여 의존 관계에 있는 jar 파일을 복사해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
 
 
cs


#MANIFEST.MF 파일을 만들때 사용

MANIFEST.MF 파일을 만들고 싶을 때 사용하는 플러그으로 jar 실행 파일을 만들고 싶다면 간단하게 maven-jar-plugin으로

만들수가 있다. 현재 경로에서의 lib 폴더의 jar파일들을 classpath로 추가 시키며, test.Main 클래스는 test 패키지의 Main 클래스 이다.

실행은 java -jar jar명.jar 을 할 수 있다 

1
2
3
4
5
6
7
8
9
10
11
12
13
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>test.Main</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>
cs


#특정 경로를 리소스를 지정된 경로로 복사

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<plugin>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>validate</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.basedir}/target/classes/resources</outputDirectory>
                <resources>
                    <resource>
                        <directory>${project.basedir}/resources</directory>
                        <filtering>false</filtering>
                        <includes>
                            <include>map/**</include>
                            <include>properties/**</include>
                        </includes>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>
cs


이번에 프로젝트를 하면서 동일한 성격의 테이블이 여러개라 하나의 쿼리를 두고 테이블 명과 몇가지 다른 컬럼에 대해서는 동적으로 생성해서 가져오게 했다..
하지만 몇번 재대로 실행이 되는가 싶더니 테스트 진행 과정에서 컬럼을 가져오지 못하는 현상이 발생했다. 

일단은 혹시나 모를 문제가 있지 않을까 해서 쿼리를 분리하고 동적으로 생성되어야 되는 부분은 쿼리를 따로 작성해서 select 하도록 하였다.

후에 이 문제에 대해서 살펴봤더니 원인은 ibatis가 매핑 정보를 캐싱하기 때문이라고 한다.

이문제를 해결하려면 다음과 같이 사용할수가 있다.

<select id="select" remapResults="true" parameterClass="dataMap" resultClass="dataMap">
 SELECT  
     bbs_seq
    ,title
    ,contents
    ,register_date
   <isEqual property="table" compareValue="photo_gallery">
       ,image_name
       ,image_path
       ,image_size
  </isEqual>      
FROM $table$
<include refid="globalWhere" />
</select>

다음 코드는 일반적으로 같은 내용을 담고 있지만 photo_gallery 테이블인 경우는 image_name, image_path, image_size 컬럼을 동적으로 생성해서 가져오는 쿼리이다.
일반적으로는 파일 테이블을 따로 두겠지만 예제를 설명하기 위해서 위와 같이 하였다..

위에 테이블에서 remapResults="true" 부분이 없을 경우 위에서 설명한 에러가 발생할수가 있다 하지만 이부분을 넣어 주면서 쿼리를 가져올때 매번 새로 생성한 쿼리를 가져오기 때문에 다음부터는 동적으로 컬럼을 가져오면서 발생한 에러를 해결 할 수가 있다. 


Ajax를 사용하다 보면 서버로부터 객체를 가져와 브라우저에 보여 줘야 하는 경우가 있다.
예전에는 이를 xml 형태로 많이 했지만 최근에는 json 형식으로 가져와서 보여주는 경우가 많은데 이는 json형식이 핸들링 하기도 더 쉽고 여러가지로 작업하기가 편하기 때문이다.
하지만 이런 xml도 마찬가지겠지만 json 형식도 알맞은 형태로 가공을 해서 보내주려면 여러모로 불편한 사항이 많이 있다 하나의 유틸성 메소드를 많들어서 사용해도 되지만 편하게 사용할수 있도록 많은 라이브러리도 제공을 해준다 그중에 하나가 JSONObject를 이용하는 방법인데 사용법이 간단하다.
    
import org.json.simple.JSONObject;
/**
 * @author diem
 *
 */
public class JSONObjectTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JSONObject obj = new JSONObject();
		obj.put("param1", "1");
		obj.put("param2", "2");
		obj.put("param3", "3");		
		System.out.println(obj.toString());
		
		JSONObject subObj = new JSONObject();
		subObj.put("subParam1", "sub1");
		subObj.put("subParam2", "sub2");
		subObj.put("subParam3", "sub3");
		subObj.put("subParam4", "sub4");
		System.out.println(subObj.toString());
		
		obj.put("param4", subObj);
		System.out.println(obj.toString());		
	}
}