WAS 기동 시 시스템 프로퍼티에 아래와 같이 등록한다.
-Dlog4j.configuration=log4j 설정 파일.xml
WAS 기동 시 시스템 프로퍼티에 아래와 같이 등록한다.
-Dlog4j.configuration=log4j 설정 파일.xml
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import com.ibm.icu.util.Calendar;
public class DateUtil {
/**
* 월의 해당 주의 날짜 배열을 얻어온다.
* @param yyyymm
* @param weekSeq
* @return
*/
public static int[] getRangeDateOfWeek(String yyyymm, int weekSeq) {
int rangeDateOfWeek [] = new int[7];
int startDayOfWeek = dayOfWeek(yyyymm.substring(0, 4), yyyymm.substring(4, 6), "1");
if( startDayOfWeek == 0 || weekSeq > 1 ){
Calendar cal = converterDate(yyyymm+"01");
int lastDateOfMonth = getLastDateOfMonth(new SimpleDateFormat("yyyyMM").format(cal.getTime()));
int startDate = 1 + ((weekSeq-1)*7) - startDayOfWeek;
for( int i=0; i<7; i++ ){
if( startDate > lastDateOfMonth ){
startDate = 1;
}
rangeDateOfWeek[i] = startDate++;
}
}else{
Calendar cal = converterDate(yyyymm+"01");
cal.add(Calendar.MONTH, -1);
int lastDateOfBeforeMonth = getLastDateOfMonth(new SimpleDateFormat("yyyyMM").format(cal.getTime()));
int startDate = (lastDateOfBeforeMonth + 1) - startDayOfWeek;
for( int i=0; i<7; i++ ){
if( startDate > lastDateOfBeforeMonth ){
startDate = 1;
}
rangeDateOfWeek[i] = startDate++;
}
}
return rangeDateOfWeek;
}
/**
* 특정날짜의 요일의 숫자를 리턴
* 0:일요일 ~ 6:토요일
* @return
*/
public static int dayOfWeek(String sYear, String sMonth, String sDay) {
int iYear = Integer.parseInt(sYear);
int iMonth = Integer.parseInt(sMonth) - 1;
int isDay = Integer.parseInt(sDay);
GregorianCalendar gc = new GregorianCalendar(iYear, iMonth, isDay);
return gc.get(gc.DAY_OF_WEEK) - 1;
}
/**
* String 형식의 날자를 Calendar 로 변환 해준다.
*
* @param yyyymmdd
* @return
*/
public static Calendar converterDate(String yyyymmdd) {
Calendar cal = Calendar.getInstance(); // 양력 달력
if (yyyymmdd == null)
return cal;
String date = yyyymmdd.trim();
if (date.length() != 8) {
if (date.length() == 4)
date = date + "0101";
else if (date.length() == 6)
date = date + "01";
else if (date.length() > 8)
date = date.substring(0, 8);
else
return cal;
}
cal.set(Calendar.YEAR, Integer.parseInt(date.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(date.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(date.substring(6)));
return cal;
}
/**
* 해당 월의 마지막일을 구한다.
* @return
*/
public static int getLastDateOfMonth() {
return getLastDateOfMonth(new Date());
}
public static int getLastDateOfMonth(Date date) {
return getLastDateOfMonth(new SimpleDateFormat("yyyyMM").format(date));
}
public static int getLastDateOfMonth(String yyyymm) {
int year = Integer.parseInt(yyyymm.substring(0, 4));
int month = Integer.parseInt(yyyymm.substring(4, 6)) - 1;
Calendar destDate = Calendar.getInstance();
destDate.set(year, month, 1);
return destDate.getActualMaximum(Calendar.DATE);
}
}
import java.io.File;
import java.io.FileInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;
/**
* Excel Read 한다. xls, xlsx 가능
* ex) ExcelGenerator.excelToList(new File("path..xls,xlsx");
* ExcelGenerator.excelToList(new File("path..xls,xlsx", new Integer[]{x, y, width, height});
* ExcelGenerator.excelToList(new File("path..xls,xlsx", x, y, width, height);
* java.awt.Rectangle(int x, int y, int width, int height) 와 같은 형태로 왼쪽 위 모서리 좌표와, 오른쪽 아래 모서리 좌표 정보
* @author ddakker
* @version 1.0
* @date 2012.05.04
*
*/
public class ExcelGenerator {
private static final Log logger = LogFactory.getLog(ExcelGenerator.class);
public static Object[][] excelToList(File file ) throws Exception {
return excelToList(file, 0, null);
}
/**
* 엑셀 데이터를 Object[colunm][row] 형태로 변환한다.
* @param file 엑셀 파일(xls, xlsx)
* @param x 왼쪽 위 모서리 x
* @param y 왼쪽 위 모서리 y
* @param width 오른쪽 아래 모서리 x
* @param height 오른쪽 아래 모서리 y
* @return
* @throws Exception
*/
public static Object[][] excelToList(File file, int x, int y, int width, int height) throws Exception {
Integer [] colRow = {x, y, width, height};
return excelToList(file, 0, colRow);
}
/**
* 엑셀 데이터를 Object[colunm][row] 형태로 변환한다.
* @param file 엑셀 파일(xls, xlsx)
* @param colRow 범위 지정 new Integer[]{왼쪽 위 모서리 x, 왼쪽 위 모서리 y, 오른쪽 아래 모서리 x, 오른쪽 아래 모서리 y}
* @return
* @throws Exception
*/
public static Object[][] excelToList(File file, Integer [] colRow) throws Exception {
return excelToList(file, 0, colRow);
}
/**
* 엑셀 데이터를 Object[colunm][row] 형태로 변환한다.
* @param file 엑셀 파일(xls, xlsx)
* @param sheetIndex 시트 번호
* @return
* @throws Exception
*/
public static Object[][] excelToList(File file, int sheetIndex) throws Exception {
return excelToList(file, sheetIndex, null);
}
/**
* 엑셀 데이터를 Object[colunm][row] 형태로 변환한다.
* @param file 엑셀 파일(xls, xlsx)
* @param sheetIndex 시트 번호
* @param colRow 범위 지정 new Integer[]{왼쪽 위 모서리 x, 왼쪽 위 모서리 y, 오른쪽 아래 모서리 x, 오른쪽 아래 모서리 y}
* @return
*/
public static Object[][] excelToList(File file, int sheetIndex, Integer [] colRow) throws Exception {
Object [][] contentData = null;
FileInputStream fis = null;
Workbook workBook = null;
Sheet sheet = null;
try {
if( colRow != null ){
if( colRow.length != 4 ) throw new Exception("colRow[] 무조껀 셋팅 해야 합니다. ex) new Integer[]{0,0,6,2}");
if( !(colRow[0] >= 0 && colRow[1] >= 0) ) throw new Exception("colRow[] 0 이상 입력 하시요. ex) new Integer[]{1,1,6,2}");
if( !(colRow[2] >= 0 && colRow[3] >= 0) ) throw new Exception("colRow[] 0 이상 입력 하시요. ex) new Integer[]{1,1,6,2}");
}
fis = new FileInputStream(file);
workBook = WorkbookFactory.create(fis);
sheet = workBook.getSheetAt(sheetIndex);
int minCol = colRow==null?0:colRow[0];
int maxCol = colRow==null?-1:colRow[2]+1;
int minRow = colRow==null?0:colRow[1];
int maxRow = colRow==null?sheet.getPhysicalNumberOfRows():colRow[3]+1;
FormulaEvaluator evaluator = workBook.getCreationHelper().createFormulaEvaluator();
for( int i=minRow; i<maxRow; i++ ) {
Row row = sheet.getRow(i);
if( i-minRow == 0 ){
if( maxCol == -1 ){
maxCol = row.getPhysicalNumberOfCells();
}
contentData = new Object[maxRow-minRow][maxCol-minCol];
}
for( int j=minCol; j<maxCol; j++ ) {
Cell cell = row.getCell(j)==null?row.createCell(j):row.getCell(j);
Object value = null;
switch( cell.getCellType() ) {
case XSSFCell.CELL_TYPE_FORMULA :
if( !(cell.toString() == "") ){
if(evaluator.evaluateFormulaCell(cell)==XSSFCell.CELL_TYPE_NUMERIC){
//value = cell.getNumericCellValue();
value = String.valueOf(new Double(cell.getNumericCellValue()).intValue());
}else if(evaluator.evaluateFormulaCell(cell)==XSSFCell.CELL_TYPE_STRING){
value = cell.getStringCellValue();
}else if(evaluator.evaluateFormulaCell(cell)==XSSFCell.CELL_TYPE_BOOLEAN){
value = String.valueOf(cell.getBooleanCellValue());
}
}
break;
case XSSFCell.CELL_TYPE_NUMERIC :
//value = cell.getNumericCellValue();
value = String.valueOf(new Double(cell.getNumericCellValue()).intValue());
break;
case XSSFCell.CELL_TYPE_STRING :
value = cell.getStringCellValue()==null?new String(""):cell.getStringCellValue();
break;
case XSSFCell.CELL_TYPE_BOOLEAN :
value = Boolean.toString(cell.getBooleanCellValue()); //boolean
break;
default :
}
logger.debug("xlsx ["+i+"]["+j+"]=" + ((cell==null || value==null)?"":value));
contentData[i-minRow][j-minCol] = (value==null)?new String(""):value;
}
}
} catch (Exception e) {
logger.error(e);
throw new Exception("POI Excel Read 중 오류가 발생하였습니다.");
} finally {
if( fis != null ) fis.close();
}
return contentData;
}
/**
* List
--------------
dom4j-1.6.1.jar
poi-3.6-20091214.jar
poi-ooxml-3.6-20091214.jar
poi-ooxml-schemas-3.6-20091214.jar
xmlbeans-2.3.0.jar
등
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.betwixt.io.BeanWriter;
public class WriteExampleApp {
public static final void main(String [] args) throws Exception {
StringWriter outputWriter = new StringWriter();
outputWriter.write("");
BeanWriter beanWriter = new BeanWriter(outputWriter);
// Bean 속성 으로 값 출력 여부
beanWriter.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
// 아이디 출력 여부
beanWriter.getBindingConfiguration().setMapIDs(false);
// 정렬
beanWriter.enablePrettyPrint();
List list1 = new ArrayList();
list1.add(new PersonBean("hk", 20));
list1.add(new PersonBean("dk", 20));
Map map = null;
List list2 = new ArrayList();
map = new HashMap();
map.put("name", "hk");
map.put("age", "20");
list2.add( map );
map = new HashMap();
map.put("name", "dk");
map.put("age", "20");
list2.add( map );
beanWriter.write("list1", list1);
beanWriter.write("list2", list2);
System.out.println(outputWriter.toString());
outputWriter.close();
}
}
public String convertorChar(String value) {
// \(역슬레쉬) 맨 처음 치환
return value==null?"":value.replace("\\", "\\\\")
.replace("+", "\\+")
.replace("[", "\\[")
.replace("]","\\]")
.replace("(", "\\(")
.replace(")", "\\)")
.replace("{", "\\{")
.replace("}", "\\}")
.replace("\'", "\\\'")
.replace("\"", "\\\"");
}
환경 : Struts2 + Spring + Sitemesh 등
기존 개발된 환경에서 Source 는 그대로 유지하면서 MVC Action 단 Result View를 XML, JSON 등의 형태로 받고 싶었다.
아래 아키텍처를 보고 고민하던 중 Result 단을 좀 꺽으면 될듯 싶어 작업해 보았다.
우선 Default Result 인 org.apache.struts2.dispatcher.ServletDispatcherResult 를 상속받아서 doExecute 함수를 재정의 해서 호출확장자가 .action 일때는 기존과 그대로 처리 하고, action.xml, action.json 일때는 request.getAttributeNames() 배열에 있는 데이터를 xml, json 문자열로 만들어서 response.getWriter() 이용해서 출력하면 되겠네요.
(해당 정보를 파라미터로 해도 될듯하고, Request Header 정보를 활용해도 되겠습니닷.)
신경써야 할 점은 getAttribute 배열에 들어있는 불필요한 데이터는 무시합니다.
또한 Struts2 가 POJO 기반이여서 Action 단의 데이터들도 뽑아와야 하는데 파마리터 ActionInvocation 객체에 getAction() 함수를 통해서 얻을 수 있습니다.
(getAttribute에 "struts.valueStack" 에 OgnlValueStack 객체에도 Action 정보가 담겨 있습니다. OgnlValueStack 는 배열로서 해당 Action 객체 일때 필요한 getter 메소드 호출해서 사용하면 되겠습니다.
ActionInvocation 에서 뽑아 올 경우 getAttributeNames() 이용 시
"struts.valueStack" 정보는 제외 시켜야 합니다.)
필요에 따라 다른 ResultType 들도 수정하시면 되겠습니다.
수정 하시고, struts 설정파일 package 하위 result-type 에 등록하시면 되겠습니다.
또한 super.doExceute() 함수에 try ~ catch 거시면 JSP Runtime Exception 에 대한 처리도 할 수 있겠네요.
JSON, XML 변환은 아래 package를 사용했습니다.
ezmorph-1.0.4.jar
json-lib-2.2.1-jdk15.jar
xom-1.1.jar
* 위 jar 최신버전으로 하면 오류나네요...
* 또한 XML Element Name이 숫자로 생성되면 파싱 오류납니다.
데이터 건수 : 130,268건
패스트캣 indexer 소요시간 : 약 45초
루씬 2.3 indexer 소요시간 : 약 2분
패스트캣과 약 2배
루씬 3.5 indexer 소요시간 : 약
2.1분 패스트캣과 약 3배
Solr 3.5 indexer 소요시간 : 약 1.3분 패스트캣과 약 2배
패스트캣 sercher 소요시간 : 약 7밀리초
루씬 2.3
sercher 소요시간: 약 700밀리초 패스트캣과 약 100배
루씬 3.5
sercher 소요시간: 약 187밀리초 패스트캣과 약 26배
Solr 3.5 sercher 소요시간: 약 23밀리초 패스트캣과
약 8배
너무 작은 차이로 의미 없음
데이터 검수 : 529,188건
패스트캣 indexer 소요시간 : 1분 26초
Solr
3.5 indexer 소요시간 : 5분 30초
패스트캣 sercher 소요시간 : 48밀리초
oracle jdbc/name_test oracle.jdbc.pool.OracleConnectionPoolDataSource ConnectionPoolDataSource oracle sid This is a sample for database setting. 아이디 아이디 1521 아이피 driverType java.lang.String thin true Warning 2 30 4 3600000 true 10000
jdbc/name_test
jdbc/name_test
jdbc/name_test
javax.sql.DataSource
public class CipherUtil {
private Log LOG = LogFactory.getLog(this.getClass());
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CipherUtil cu = new CipherUtil();
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssss");
String key = sdf.format(cal.getTime());
System.out.println("key: " + key);
String text = "가나다라마바사@★아&자@12!@#$%";
String encryptText = null;
String decryptText = null;
try {
encryptText = cu.encryptAES(text, key);
decryptText = cu.decryptAES(encryptText, key);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("encryptText: " + encryptText);
System.out.println("beforeText : " + text);
System.out.println("decryptText: " + decryptText);
// 2011051813190051
// abcdefgh01234567
}
// key는 16바이트로 구성 되어야 한다.
private String encryptAES(String s, String key) throws Exception {
String encrypted = null;
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = byteArrayToHex(cipher.doFinal(s.getBytes()));
return encrypted;
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e.getMessage(), e);
}
throw e;
}
}
// key는 16 바이트로 구성 되어야 한다.
private String decryptAES(String s, String key) throws Exception {
String decrypted = null;
try {
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted = new String(cipher.doFinal(hexToByteArray(s)));
return decrypted;
} catch (Exception e) {
if (LOG.isErrorEnabled()) {
LOG.error(e.getMessage(), e);
}
throw e;
}
}
private byte[] hexToByteArray(String s) {
byte[] retValue = null;
if (s != null && s.length() != 0) {
retValue = new byte[s.length() / 2];
for (int i = 0; i < retValue.length; i++) {
retValue[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16);
}
}
return retValue;
}
private String byteArrayToHex(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
for (int i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
}