|
Language/JAVA 2013. 11. 13. 17:27
import java.text.NumberFormat;
public class numberFormat {
public static void main(String[] args) { // TODO Auto-generated method stub double num = 1.2345E2; NumberFormat f = NumberFormat.getInstance(); f.setGroupingUsed(false); String val = f.format(num); System.out.println(val); }
}
Language/JAVASCRIPT 2013. 11. 13. 17:16
Language/JAVA 2013. 11. 13. 17:13
excel.zip
apache poi site : http://poi.apache.org/
필요 Libraries
-- *.xls 을 위한 library
poi-3.7-20101029.jar
-- *.xlsx를 위한 libraries
poi-ooxml-3.7-20101029.jar xmlbeans-2.3.0.jar poi-ooxml-schemas-3.7-20101029.jar ooxml-lib\dom4j-1.6.1.jar
-- 사용 ( Map 에 Data 저장 .. sample )
*.xls 의 경우 excel 파일 읽어오는 방법
POIFSFileSystem fileSystem = new POIFSFileSystem(new FileInputStream(new File(excelFile)));
SSFWorkbook work = new HSSFWorkbook(fileSystem);
int sheetNum = work.getNumberOfSheets(); log.error("\n# sheet num : " + sheetNum); for( int loop = 0; loop < sheetNum; loop++){ HSSFSheet sheet = work.getSheetAt(loop); int rows = sheet.getPhysicalNumberOfRows(); log.error("\n# sheet rows num : " + rows); for( int rownum = 0; rownum < rows; rownum++){ HSSFRow row = sheet.getRow(rownum); if(row != null){ int cells = row.getPhysicalNumberOfCells(); log.error("\n# row = " + row.getRowNum() + " / cells = " + cells); for(int cellnum =0; cellnum < cells; cellnum++){ HSSFCell cell = row.getCell(cellnum); if(cell != null){ switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_FORMULA: params.put("CELL_TYPE_FORMULA"+cellnum, cell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING: params.put("CELL_TYPE_STRING"+cellnum, cell.getStringCellValue()); break; case HSSFCell.CELL_TYPE_BLANK: params.put("CELL_TYPE_BLANK"+cellnum, cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_ERROR : params.put("CELL_TYPE_ERROR"+cellnum, cell.getErrorCellValue()); break; ...... default: break; } } log.error("\n CELL __ [params ] => " + params.toString()); } } } }
*.xlsx 의 경우 excel 파일 읽어오는 방법
XSSFWorkbook work = new XSSFWorkbook(new FileInputStream(new File(excelFile)));
int sheetNum = work.getNumberOfSheets(); log.error("\n# sheet num : " + sheetNum); for( int loop = 0; loop < sheetNum; loop++){ XSSFSheet sheet = work.getSheetAt(loop); int rows = sheet.getPhysicalNumberOfRows(); log.error("\n# sheet rows num : " + rows); for( int rownum = 0; rownum < rows; rownum++){ XSSFRow row = sheet.getRow(rownum); if(row != null){ int cells = row.getPhysicalNumberOfCells(); log.error("\n# row = " + row.getRowNum() + " / cells = " + cells); for(int cellnum =0; cellnum < cells; cellnum++){ XSSFCell cell = row.getCell(cellnum); if(cell != null){ switch (cell.getCellType()) { case XSSFCell.CELL_TYPE_FORMULA: params.put("CELL_TYPE_FORMULA"+cellnum, cell.getNumericCellValue()); break; case XSSFCell.CELL_TYPE_STRING: params.put("CELL_TYPE_STRING"+cellnum, cell.getStringCellValue()); break; case HSSFCell.CELL_TYPE_BLANK: params.put("CELL_TYPE_BLANK"+cellnum, cell.getBooleanCellValue()); break; case XSSFCell.CELL_TYPE_ERROR : params.put("CELL_TYPE_ERROR"+cellnum, cell.getErrorCellValue()); break; ...... default: break; } } log.error("\n CELL __ [params ] => " + params.toString()); } } } }
출처 - http://enosent.tistory.com/30
Language/JSP 2013. 11. 11. 15:15
<%@ page language="java" contentType="text/html;charset=euc-kr" import="java.util.*,java.io.*,java.sql.*" %>
<% // 드라이버를 위해 웹서버 lib에 sqljdbc4.jar 저장 필요
String strDriver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; String strDBConn = "jdbc:sqlserver://IP ADDRESS:1433;DatabaseName=DBNAME"; String strUserID = "USERID"; String strUserPW = "USERPASSWORD"; Class.forName(strDriver); Connection objConn = DriverManager.getConnection(strDBConn, strUserID, strUserPW);
// Statement
Statement objStmt = objConn.createStatement(); ResultSet objRS = objStmt.executeQuery("SELECT TOP 5 * FROM TADMIN WITH (NOLOCK)"); while(objRS.next()) {
out.println(objRS.getString("AdminName") + "<BR>"); }
objRS.close(); objStmt.close();
// PreparedStatement // 쿼리 시 PreparedStatement를 쓰는 것이 좋은데, 이유는 쿼리가 캐시되므로 반복적인 작업에 속도가 유리.
String strSQL = "SELECT TOP 5 * FROM TADMIN WITH (NOLOCK) WHERE ADMINID = ? "; PreparedStatement objPStmt = objConn.prepareStatement(strSQL); objPStmt.setString(1, "tiger"); ResultSet objRS2 = objPStmt.executeQuery(); while(objRS2.next()) { out.println(objRS2.getString("AdminName") + "<BR>"); } objRS2.close(); objPStmt.close(); objConn.close(); %>
Language/JAVA 2013. 9. 17. 13:07
유닉스에서 자바 이미지 객체를 사용하려 할때 다음과 같은 에러가 발생한다. Exception in thread "main" java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable. 이것은 일종의 JDK의 버그이다. 원인은 자바가 BufferedImage 를 생성하고 실제로 Graphics 객체를 얻어오기 위해 getGraphics나 createGraphics 메소드를 부를때, 실제로 display하거나 mouse, keyboard 자원을 하나도 쓰지 않을 것임에도 불구하고 내부적으로 AWT Toolkit이 그것들에 대한 자원을 얻어오게 되어있었기 때문이다. Sun에서는 이걸 버그로 취급하며 해결 방법은 2가지가 있다. 1. JRE 1.3 이하 일경우 www.x.org 에서 다운로드 받을 수 있는 Xvfb 라는 것을 사용하는 방법이다. 이것은 X-server 에뮬레이터이다. 참고 1.1. 가상 xwindow실행하기 1.1.1 리눅스 리눅스의 경우 XFree86-Xvfb-4.1.0-3.i386.rpm 을 설치해야 합니다. XFree86-Xvfb-4.1.0-3.i386.rpm 패키지는 아래의 패키지가 최소한 설치되어 있어야 합니다. XFree86-4.1.0-3.i386.rpm Mesa-3.4.2-7.i386.rpm Xaw3d-1.5-10.i386.rpm
설치과정중에 에러가 발생하면 아래 커맨드를 이용하여 의존성을 검사하면 됩니다. rpm -ivh --nodeps ./Mesa-3.4.2-7.i386.rpm rpm -ivh ./XFree86-4.1.0-3.i386.rpm rpm -ivh ./Xaw3d-1.5-10.i386.rpm rpm -ivh ./XFree86-Xvfb-4.1.0-3.i386.rpm
Xvfb는 100dpi 및 75dpi용 폰트도 설치되어 있어야 합니다. 폰트와 관련하여 간단하게 작업하려면 아래와 같이 하세요 wget http://www.psoft.net/downloads/X11.tgz tar xfz ./X11.tgz -C /usr/X11R6/lib/
이제 모든 설치가 완료되면 아래 커맨드로 Xvfb를 활성화 시킵니다. /usr/X11R6/bin/Xvfb ':0' -screen 0 100x100x8 &
이제 서버가 시작할 때 마다 이 기능을 활성화 시키려면 /etc/rc.d/rc.local에 추가하면 됩니다. 1.2.1 Solaris : 다운로드 : X11R6_bin.tar.gz 1.2.2 설치 : % su - # mkdir /usr/X11R6 # cp X11R6_bin.tar.gz /usr/X11R6 # cd /usr/X11R6 # gunzip X11R6_bin.tar.gz # tar xvf X11R6_bin.tar # rm X11R6_bin.tar 1.2.3. 자동실행 실행 스크립트 : xvfb.server 다운로드 자동 실행 설정 스크립트 : install.xvfb다운로드 xvfb.server에서 RUN_AS_USER=tomcat 을 적절히 수정 후 install.xvf 만 실행하면 끄~읕
참조 : http://www.x.org/ http://developers.sun.com/solaris/articles/solaris_graphics.html#3 http://www.idevelopment.info/data/Unix/General_UNIX/GENERAL_XvfbforSolaris.shtml http://chartworks.com/support/server/XvfbonUnix.html 2. JRE 1.4 이상에서 Headless AWT Toolkit을 이용해서 이 문제를 해결한다. 파일을 실행할때 간단히 -Djava.awt.headless=true 옵션을 주는것만으로 가능하다. [참고] java 1.4 버전 이상에서는 자바 자체에서 처리 가능하게 할수 있습니다. 리눅스에서 굳이 x-window나 xvf 깔기 귀찮다고 아니면 할줄 모르시는 분들은 간단하게 이문제를 해결하는 방법이 있습니다. <!-- Note: If true, the system property, java.awt.headless, will be set to true. This should be used with JDK 1.4+ on servers without graphics cards and monitors. Otherwise, the property is not set. --> <!-- <headless-server>true</headless-server> --> /WEB-INF/flex/flex-config.xml에서 이부분의 주석을 제거 해주시면 됩니다. <headless-server>true</headless-server> 그리고 자바 구동시에(톰켓이나 레진) JVM 파라메터를 적는 부분이 있을 것입니다. 레진 같은 경우 걍 뒤에 자바 파라메터 적으면 작동됩니다. resin start -Djava.awt.headless=true 즉 flex-config에서 headless-server 수정하고 jsp 엔진 구동시에 파라 메터 Djava.awt.headless=true 를 넣어주면 에러없이 잘 해결된다. 톰캣에서 이용할때는 catalina.sh 파일에 CATALINA_OPTS=-Djava.awt.headless=true를 추가하고 재구동하면 된다.
출처 - http://blog.naver.com/PostView.nhn?blogId=galahad76&logNo=20042609592
Language/JAVA 2013. 9. 3. 13:46
JAXB: Marshalling and Unmarshalling CDATA block using EclipseLink MOXy11 November 2012 By Nithya Vasudevan 1,575 views 9 CommentsRating: 0.0/5 (0 votes cast) Project Description- In the example provided here, we saw how to marshal and unmarshal CDATA block using JAXB RI by creating custom adapter class.
- In this JAXB example we will see how to marshal and unmarshal CDATA block using MOXy implementation which is available as part of Eclipselink project.
- When using MOXy JAXB implementation there is no need to write custom adapter. Just an annotation (provided by MOXy) is sufficient to handle CDATA.
Environment Used:- JDK 6 (Java SE 6) or later.
- Eclipse Indigo IDE for Java EE Developers.
- EclipseLink 2.3.2 (Download EclipseLink from here and extract the zip file). We need this for MOXy which is an implementation of JAXB API.
New project in EclipseCreate a new Java project in Eclipse IDE and name it as JAXBCDataMoxyImpl. Add JAR file- You need to add eclipselink.jar file located in “eclipselink/jlib” in your project Build Path.
- Right click on project -> Properties -> Java Build Path from left pane -> Libraries from right pane -> Add External JARs…
Create Bean classCreate a new Class “Book.java” in the package “com.theopentutorials.jaxb.to” and copy the following code. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | package com.theopentutorials.jaxb.to;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlCDATA;
@XmlAccessorType (XmlAccessType.FIELD)
@XmlRootElement (name = "book" )
public class Book {
private String name;
private String author;
private String publisher;
private String isbn;
@XmlCDATA
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this .author = author;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this .publisher = publisher;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this .isbn = isbn;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this .description = description;
}
@Override
public String toString() {
return "Book [name=" + name + ", author=" + author + ", publisher="
+ publisher + ", isbn=" + isbn + ", description=" + description
+ "]" ;
}
}
|
This is a simple bean class containing JAXB annotations whose object is marshalled andunmarshalled. The ‘description’ property is annotated with @XmlCDATA which is provided by MOXy and vendor specific. jaxb.properties fileTo use MOXy as your JAXB implementation you need to add a jaxb.properties file in the bean package. Create a new file “jaxb.properties” in the package “com.theopentutorials.jaxb.to” and copy the following entry. javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Create JAXB Handler (Helper class)Create a new Class “JAXBXMLHandler.java” in the package “com.theopentutorials.jaxb.xml” and copy the following code. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package com.theopentutorials.jaxb.xml;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import com.theopentutorials.jaxb.to.Book;
public class JAXBXMLHandler {
public static Book unmarshal(File importFile) throws JAXBException {
Book book = new Book();
JAXBContext context;
context = JAXBContext.newInstance(Book. class );
Unmarshaller um = context.createUnmarshaller();
book = (Book) um.unmarshal(importFile);
return book;
}
public static void marshal(Book book, Class[] classes,
Map<String, Map<String, StreamSource>> properties, File selectedFile)
throws IOException, JAXBException {
JAXBContext context;
BufferedWriter writer = null ;
try {
writer = new BufferedWriter( new FileWriter(selectedFile));
context = JAXBContext.newInstance(classes, properties);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true );
m.marshal(book, writer);
} finally {
try {
writer.close();
} catch (IOException io) {
}
}
}
}
|
- This is a helper class which has methods to perform marshalling and unmarshalling. These methods are called from client code (in this case, main() method).
- By default, the marshaller implementation of the JAXB RI tries to escape characters.
- We use an overloaded JAXBContext.newInstance(Class) to configure ‘properties’ for this instantiation of JAXBContext. The interpretation of properties is implementation specific.
MOXy binding fileMOXy JAXB implementation allows you to enable a element to use CDATA. You could use MOXy’s binding file to indicate that the book’s ‘description’ property should use CDATA. Create a XML file in your project and name it as “oxm.xml” and copy the following code. 01 02 03 04 05 06 07 08 09 10 | <? xml version = "1.0" encoding = "UTF-8" ?>
< java-types >
< java-type name = "com.theopentutorials.jaxb.to.Book" >
< java-attributes >
< xml-element java-attribute = "description" cdata = "true" />
</ java-attributes >
</ java-type >
</ java-types >
</ xml-bindings >
|
Create Java Application client (main())Create a new Class “JAXBCDataDemo.java” in the package “com.theopentutorials.jaxb.main” and copy the following code. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | package com.theopentutorials.jaxb.main;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBException;
import javax.xml.transform.stream.StreamSource;
import com.theopentutorials.jaxb.to.Book;
import com.theopentutorials.jaxb.xml.JAXBXMLHandler;
public class JAXBCDataDemo {
public static void main(String[] args) {
Book book = new Book();
book.setAuthor( "Kathy Sierra" );
book.setName( "SCJP" );
book.setPublisher( "Tata McGraw Hill" );
book.setIsbn( "856-545456736" );
String desc = "<p>With hundreds of practice questions and hands-on exercises, "
+ "<b>SCJP Sun Certified Programmer for Java 6 Study Guide</b>" +
"covers what you need to know"
+ "--and shows you how to prepare--" +
"for this challenging exam. </p>" ;
book.setDescription(desc);
Map<String, StreamSource> oxm = new HashMap<String, StreamSource>( 1 );
oxm.put( "com.theopentutorials.jaxb.to" , new StreamSource( "oxm.xml" ));
Map<String, Map<String, StreamSource>> properties =
new HashMap<String, Map<String, StreamSource>>();
properties.put( "eclipselink-oxm-xml" , oxm);
Class[] classes = { Book. class };
try {
JAXBXMLHandler.marshal(book, classes, properties, new File( "book.xml" ));
Book book2 = JAXBXMLHandler.unmarshal( new File( "book.xml" ));
System.out.println( "Unmarshal: " + book2);
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
|
- This class creates book object with ‘description’ property containing HTML tags and calls marshal method from JAXBXMLHandler helper class passing book object and the file to write the object.
- We call unmarshal method passing the marshalled file name which returns a book object.
- Finally, printing the book object (which calls toString() from Book class).
OutputRun the JAXBCDataDemo.java. Book [name=SCJP, author=Kathy Sierra, publisher=Tata McGraw Hill, isbn=856-545456736, description= <p>With hundreds of practice questions and hands-on exercises, <b>SCJP Sun Certified Programmer for Java 6 Study Guide</b> covers what you need to know--and shows you how to prepare--for this challenging exam. </p>] Refresh your project in Project Explorer (press F5 on your project) to see the generated XML file. 01 02 03 04 05 06 07 08 09 10 11 12 | <? xml version = "1.0" encoding = "UTF-8" standalone = "yes" ?>
< book >
< name >SCJP</ name >
< author >Kathy Sierra</ author >
< publisher >Tata McGraw Hill</ publisher >
< isbn >856-545456736</ isbn >
< description > <![CDATA[<p>With hundreds of practice questions
and hands-on exercises, <b>SCJP Sun Certified Programmer
for Java 6 Study Guide</b> covers what you need to know--
and shows you how to prepare --for this challenging exam. </p>]]>
</ description >
</ book >
|
Folder StructureThe complete folder structure of this example is shown below.
Language/JAVA 2013. 8. 29. 14:58
두 방법에 의해서 반환되는
Class 인스턴스는 시점에 따라서 달라지는데
.class는 compile time에
결정되고 .getClass()는 rumtime에
결정된다.
간단한 예제 프로그램으로 차이점을 확인할 수
있다.
public class
ClassExample { public
ClassExample() {
printClass(); } final public void
printClass() {
System.out.println("ClasExample.class :
" + ClassExample.class);
System.out.println("Sub_ClassExmaple.class :
" + Sub_ClassExample.class);
System.out.println("this.getClass() : "
+ this.getClass()); } public static void
main(String[] args) {
System.out.println("new
ClassExample()"); new
ClassExample();
System.out.println("\nnew
Sub_ClassExample()"); new
Sub_ClassExample(); } }
public class
Sub_ClassExample extends
ClassExample { } ----------- output
--------------------------- new
ClassExample() ClasExample.class : class
test.ClassExample Sub_ClassExmaple.class :
class test2.Sub_ClassExample this.getClass() : class
test.ClassExample
new
Sub_ClassExample() ClasExample.class : class
test.ClassExample Sub_ClassExmaple.class :
class test2.Sub_ClassExample this.getClass() : class
test2.Sub_ClassExample
출처 - http://javafreak.tistory.com/52
Language/JAVA 2013. 8. 29. 14:41
1. Log4J란 ? - 자바 프로그램 작성 시 로그를 남기기 위해서 사용되는 Logging Framework - URL : http://logging.apache.org/log4j/docs/ 2. Log4J 설치하기( URL : http://logging.apache.org/log4j/docs/download.html ) 2.1. 해당 파일 다운 받기 2.1.1. 기본파일 - log4j-1.2.11.jar : Log4J를 사용하기 위해서 필요한 Jar 파일 (http://logging.apache.org/log4j/docs/download.html ) 2.1.2. 확장파일 ( DataBase에 로그파일을 남기기 위한 파일 ) - jdbcappender.jar : JDBCAppender를 사용하기 위한 Jar 파일 - ojdbc14.zip : Oracle 드라이버 Jar 파일 ( 해당 DBMS에 대한 드라이버파일 ) 2.2. log4j Configuration 파일 설정하기 2.2.1. Root Logger 설정
log4j.rootLogger=INFO, console, filelog ,dblog |
- 첫번째는 Log Level을 설정하고 뒤에는 Appender를 설정한다. - Appender는 상위에 표현되어 있는 것 같이 console(화면출력), filelog(파일), dblog(데이터베이스)로 설정할 수 있으며 Appender에 대한 상세설정은 추후 표기한다. - console, filelog, dblog 등의 명칭은 아래에 설정된 명칭을 사용한다. - Log Level은 DEBUG, INFO, WARN, ERROR, FATAL 로 구성되며, 위와 같이 INFO로 설되어 있으면 INFO이하인 DEBUG를 제외한 모든 로그가 기록된다.
log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-5p,%d{yyyy/MM/dd HH:mm:ss.SSS},%-5X{APP}, %-8X{TSC}, %m %n |
2.2.2. console Appender 설정 - 첫번째 라인 : console에 대한 클래스 정의 - 두번째 라인 : 로그를 나타내기 위한 Layout 클래스 정의 세번째 라인 : Layout에 대한 ConversionPattern을 정의 - 2.2.3. filelog Appender 설정
log4j.appender.filelog=org.apache.log4j.DailyRollingFileAppender log4j.appender.filelog.Append=true log4j.appender.filelog.DatePattern='.'yyyy-MM-dd-HH log4j.appender.filelog.File=./log/app.csv log4j.appender.filelog.layout=org.apache.log4j.PatternLayout log4j.appender.filelog.layout.ConversionPattern=%-5p,%d{yyyy/MM/dd HH:mm:ss.SSS},%-5X{APP}, %-8X{TSC}, %m %n |
- 첫번째 라인 : filelog에 대한 클래스 정의 - 두번째 라인 : 파일에 대한 Append 여부 - 세번째 라인 : 파일을 Backup하기 위한 DatePattern을 정의 - 네번째 라인 : 로그파일명을 정의 - 다섯째 라인 : 로그를 나타내기 위한 Layout 클래스 정의 - 여섯째 라인 : Layout에 대한 ConversionPattern을 정의 2.2.4. dblog Appender 설정
CREATE TABLE APP_LOG ( SYSTEMNAME VARCHAR2(100 BYTE), LOGDATE TIMESTAMP DEFAULT SYSDATE, LOGLEVEL VARCHAR2(100 BYTE), MDC1 VARCHAR2(100 BYTE), MDC2 VARCHAR2(100 BYTE), MESSAGE VARCHAR2(4000 BYTE), TROWABLE VARCHAR2(4000 BYTE) ) |
- DB로그를 작성하기 위해서는 위와 같이 DB에 Table을 만들어야 한다.
1 Line:log4j.appender.dblog=org.apache.log4j.jdbcplus.JDBCAppender 2 Line:log4j.appender.dblog.url=jdbc:oracle:thin:@168.219.10.149:1521:MCSDB 3 Line:log4j.appender.dblog.dbclass=oracle.jdbc.driver.OracleDriver 4 Line:log4j.appender.dblog.username=sds 5 Line:log4j.appender.dblog.password=sdsdb 6 Line:log4j.appender.dblog.sql=INSERT INTO APP_LOG( SYSTEMNAME, LOGDATE, LOGLEVEL, MDC1,MDC2, MESSAGE, TROWABLE ) values ('MCSMGR',TIMESTAMP '@TIMESTAMP@','@PRIO@','@MDC:APP@','@MDC:TSC@','@MSG@','@THROWABLE@') 7 Line:log4j.appender.dblog.layout=org.apache.log4j.PatternLayout 8 Line:log4j.appender.dblog.layout.ConversionPattern=%m 9 Line:log4j.appender.dblog.buffer=1 10 Line:log4j.appender.dblog.commit=true 11 Line:log4j.appender.dblog.quoteReplace=true 12 Line:log4j.appender.dblog.throwableMaxChars=3000 |
- 1 Line : dblog에 대한 클래스 정의 - 2 Line : DB url 정의 - 3 Line : DB 드라이버 클래스 정의 - 4 Line : DB User 정의 - 5 Line : DB Password 정의 - 6 Line : INSERT SQL문 정의 - 7 Line : 로그를 나타내기 위한 Layout 클래스 정의 - 8 Line : Layout에 대한 ConversionPattern을 정의 - 9 Line : DB를 Update하기 전까지 SQL문의 Buffer 개수. 1이면 바로 Update 함 - 10 Line : commit 여부 - 11 Line : single quotes (')를 2 single quotes ('')로 변경 여부 - 12 Line : throwable/exception stack trace의 최대 문자 개수 정의 2.3. Logging Class 작성하기
import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.MDC; import org.apache.log4j.PropertyConfigurator; public class Trace { private static Logger McsLogger = Logger.getRootLogger(); public static void log( Level level, String app, String tsc, String message ) { log(level,app,tsc,message, null ); } public static void log( Level level, String app, String tsc, String message, Throwable t ) { if( tsc == null ) tsc = ""; if( app == null ) app = ""; MDC.put("APP",app); MDC.put("TSC", tsc ); McsLogger.log( level, message, t ); MDC.remove("APP"); MDC.remove("TSC"); } public static void main(String args[]) { String Path = System.getProperty( "user.dir" ); PropertyConfigurator.configureAndWatch( Path +"/config/log4j.properties", 1000); System.out.println("URL:"+ Path +"/config/log4j.properties" ); Trace.log( Level.INFO, "APP1","TQFRP01","Message01"); Trace.log( Level.WARN, "APP2","TQFRP05","Message02"); Trace.log( Level.FATAL, "APP3","TQFRP01","Message03", new Exception("Deaded!!")); System.out.println("TEST COMPLETED !!"); } } |
- 위와 같이 시스템별로 로그클랙스를 작성한다.
3. Log4J 적용 예제 3.1. 폴더구조 | bin : class 파일 config : log4j.properties lib : jdbcappender.jar, log4j-1.2.11.jar, ojdbc14.zip log : 로그파일( app.cvs ) src : 소스파일( Trace.java ) |
3.2. 실행하기 run.bat 를 실행
참조-PatternLayout 아래 Conversion Pattern은 실제로 Test 후, 사용하시길 바랍니다. Conversion Character | Effect | c | 클래스 명 예 ) %c{2} : "a.b.c" 는 "b.c". | C | 클래스 명 예) %C{1} : org.apache.xyz.SomeClass → SomeClass | d | 날짜 형식 예 ) %d{dd MMM yyyy HH:mm:ss,SSS} , %d{HH:mm:ss,SSS} | F | 파일 명 | l | 이벤트를 발생시킨 Caller의 위치정보 | L | 이벤트를 발생시킨 Caller의 라인번호 | m | 이벤트 메세지 | M | 이벤트를 발생시킨 Caller의 함수명 | n | 라입구분자 | p | 로그이벤트 우선순위 | r | Application이 시작된 이후, 이벤트가 발생될 때까지 시간( milliseconds ) | t | 스레드의 이름을 출력 | x | NDC(nested diagnostic context)의 사용하기 | X | MDC (mapped diagnostic context) 사용하기 예) %X{clientNumber} : clientNumber는 Key를 의미함 | % | %%는 화면에 %를 출력함 |
출처 - http://blog.naver.com/gh2501/125766571
Language/JAVA 2013. 8. 29. 14:40
Log는 프로그램을 하다 보면 매우 유용한 정보입니다. 그렇다고 무작정 로그를 남기는 것도 시스템 performance에 악영양을 미치므로 꼭 필요한 부분에 로그를 남겨두는 것이 좋습니다. 로그를 남기는 가장 쉬운 방법은 System.out.println("something logs....");와 같이 System.out.println을 사용하면 되지만 프로그램을 개발완료 후에는 불필요한 로그를 삭제하는 작업이 필요하겠죠? 만약 삭제하지 않으면 system log에 엄청난 쓰레기 로그들이 남겠죠? 그러나 이런 로그들이 시스템 오류가 발생했을 때는 매우 귀중한 자원이 됩니다. 무작정 삭제할 수도 없고 그렇다고 그대로 놓아두면 시스템 부하가 생기겠죠? 이러한 로그를 잘 관리할 수 있는 뭔가가 필요할 겁니다. 이 문제를 해결하기 위해 나온 것이 log4j 프레임웍이라고 볼 수 있습니다. Log4j에서 로그는 환경파일 설정을 통해 선택적으로 남길 수 있으며, 로그를 남기는 물리적인 매체를 설정할 수도 있습니다. Text file로 남기거나 database로 남기거나 등등.. 자 그럼 log4j를 한번 사용해 보도록 할까요? Log4j는 다음의 사이트에서 다운로드 받을 수 있습니다. http://logging.apache.org/log4j/1.2/download.html apache-log4j-1.2.16.zip 파일을 다운받으시면 될 것 같네요. 압축을 풀명 여러 파일이 있는데 아래의 log4j-1.2.16.jar파일을 import 시키면 됩니다.
다음은 로그를 어떻게 남길지 결정하기 위해 환경설정파일을 만들어야 겠죠? 기본적으로 log4j의 환경파일은 log4j.properties입니다. 또한 기본적인 위치는 WEB-INF\classes directory에 위치시키시면 됩니다. 우선 저는 src 디렉토리에 위치 시켰습니다. 그럼 log4j.properties의 내용을 확인해 볼까요? log4j.rootCategory=DEBUG, console, filelog log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-5p,%d{yyyy/MM/ddHH:mm:ss.SSS},%-5X{APP}, %-8X{TSC}, %m %n log4j.appender.filelog=org.apache.log4j.DailyRollingFileAppender log4j.appender.filelog.Append=true log4j.appender.filelog.DatePattern='.'yyyy-MM-dd-HH log4j.appender.filelog.File=./log/application.log log4j.appender.filelog.layout=org.apache.log4j.PatternLayout log4j.appender.filelog.layout.ConversionPattern=%-5p,%d{yyyy/MM/ddHH:mm:ss.SSS},%-5X{APP}, %-8X{TSC}, %m %n |
두가지 방법만 일단 알아보겠습니다. 콘솔로 남기는 방법과 파일로 남기는 방법입니다. Log4j는 5가지의 로그 레벨이 있습니다. DEBUG, INFO, WARN, ERROR, FATAL 개발자는 로그를 남길 때 이 5가지의 범주로 로그를 남기시면 됩니다. 이는 추후에 알아보기로 하고 환경설정을 하나씩 확인해 보겠습니다. log4j.rootCategory=DEBUG, console, filelog 로그를 남기는 레벨을 지정하고 로그 출력방향을 설정합니다. 위 설정은 DEBUG레벨로 로그를 출력하고 콘솔과 파일로그로 남긴다는 의미입니다. Console, filelog의 이름은 개발자가 마음대로 수정할 수 있습니다. 자 console의 환경설정을 볼까요? 로그출력방향을 콘솔로 설정하고 로그 패턴을 설정하고 있습니다. 자세한 사항은 다음의 사이트에서 http://blog.naver.com/gh2501/125766571를 참조하시기 바랍니다. 잘 정리되어 있어요 ^^; log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%-5p,%d{yyyy/MM/dd HH:mm:ss.SSS},%-5X{APP}, %-8X{TSC},%m %n 파일로 로그를 출력합니다. log4j.appender.filelog=org.apache.log4j.DailyRollingFileAppender log4j.appender.filelog.Append=true log4j.appender.filelog.DatePattern='.'yyyy-MM-dd-HH log4j.appender.filelog.File=./log/application.log log4j.appender.filelog.layout=org.apache.log4j.PatternLayout log4j.appender.filelog.layout.ConversionPattern=%-5p,%d{yyyy/MM/dd HH:mm:ss.SSS},%-5X{APP}, %-8X{TSC},%m %n 자 그러면 이제 로그를 남기도록 설정을 해보도록 하겠습니다. 기존에 테스트하던 소스를 활용해 보겠습니다. package org.power.test; import org.apache.log4j.Logger; import org.power.dao.BbsDAO; import org.power.dao.BbsMybatisDAOImpl; import org.power.vo.BbsVO; import junit.framework.TestCase; public class BbsMybatisDAOImplTest extends TestCase { private BbsDAO bbsdao; public Logger logger; protected void setUp() throws Exception { super.setUp(); bbsdao = new BbsMybatisDAOImpl(); logger = Logger.getLogger(this.getClass()); } public void testSelect() { BbsVO vo = new BbsVO(); try { vo = bbsdao.select(1500); logger.debug(vo.toString()); logger.info(vo.toString()); logger.warn(vo.toString()); logger.error(vo.toString()); logger.fatal(vo.toString()); } catch (Exception e) { e.printStackTrace(); } } |
위의 테스트 코드를 Debug레벨로 로그를 남기고 실행해 보며 다음과 같이 로그가 표시됩니다. 위를 보면 debug, info, warn, error, fatal의 모든 로그가 표시됩니다. 특히 재미있는 것은 ibatis의 로그도 표시되고 있습니다. 즉, ibatis도log4j를 사용하고 있다는 의미겠죠? 그럼 레벨을 warn로 해보면 어떻게 될까요? log4j.properties에서 다음의 속성을 바꾸어 보겠습니다. log4j.rootCategory=WARN, console, filelog
WARN 레벨 이상의 로그만 표시되고 있습니다. 자 개발시에 필요한 DEBUG정보들은 DEBUG로 레벨로 로그를 남기고 실제 운영시에는 로그레벨을 ERROR 레벨로 설정하면 로그가 쌓이는데 소모되는 시스템부하를 줄일 수가 있겠죠? 또한 문제가 발생시에는 로그레벨을 DEBUG로 설정하여 로그를 확인하면 오류를 쉽게 컨트롤 할 수 있을 것이라 봅니다. 다만, log4j도 문제가 있습니다. 실제적으로 로그만 출력을 하지 않을 뿐 로그를 만드는 작업, 즉 logger.debug(vo.toString()); 와 같은 코드가 실제적으로 시스템 리소스를 소비하기 때문입니다. String 작업은 java에서 가장 많은 리소스를 차지한다고 합니다. 이런 부하를 해결하기 위해 또 다른 log 관련 프레임웍의 사용이 대두 된다고합니다.
출처 - http://blog.naver.com/byebird?Redirect=Log&logNo=20140995455
Language/JAVA 2013. 8. 28. 17:22
TDD 프로젝트에 join 한지 두달이 넘어갑니다. 이제 Spring Framwork 에서 JUnit 테스트 만드는 일은 제법 익숙해 졌어요. 오늘은 Private 메소드에 대한 JUnit 테스트 만드는 방법을 정리해 두어야 겠습니다. 우선 Method 메소드를 만들어서 테스트할 private 메소드를 담을 겁니다. Method m = singlePaymentController.getClass().getDeclaredMethod("method name",input parameter -class-);
singlePaymentController 는 테스트할 클래스 이름인데요. 미리 인스턴스를 생성해 놓은 변수 입니다. (SinglePaymentController singlePaymentController = new SinglePaymentController(); 이렇게요.
그 클래스에서 getClass()를 안의 getDeclaredMethod() 를 불러 냅니다. private 메소드를 외부에서 접근할 때는 이 getDeclaredMethod()를 사용하고 private field 에 접근할 때는 getDeclaredField() 나 getDeclaredFields를 사용합니다. 이 밖에서getDeclaredConstructor(), getDeclaredClass() 등 여러가지가 있습니다. 필요할 때 사용하면 됩니다.
getDeclaredMethod() 안에 들어가는 인자들은 해당 메소드 이름이 string으로 들어가고 그 다음엔 그 메소드의 input parameter 들을 열거하면 됩니다. 그러면 테스트 하고 싶은 private 메소드를 Method 객체 안에 담을 수가 있습니다. m.setAccessible(true); 이제 위 코드 처럼 해당 private 메소드를 접근할 수 있도록 합니다. 이제 외부에서 그 private 메소드에 접근 할 수 있습니다. 이제 해당 private method 를 실행시키면 됩니다. invoke 메소드를 사용하는데요.
그 private method를 담은 Method 객체를 invoke 해 주면 됩니다. m.invoke() 이렇게요.
여기서 invoke 안에는 그 private 메소드가 들어있는 class와 private method 에 전달 될 input parameter 를 넣어 주면 됩니다. private 메소드가 들어있는 클래스는 아까 사용했던 singlePaymentController 가 되겠네요. 그리고 그 private method의 input parameter는 새로 생성해서 테스트 데이터를 넣어 주셔야 됩니다. input parameter 에 필요한 값들 넣기 m.invoke(클래스 이름, input parameter) assert 하기 이렇게해서 해당 private method 안에서 처리되어야 할 값들을 assert 문에 넣어서 예상값과 실제 처리된 값을 비교하면 되겠죠. 만약 그 private 메소드가 return 값이 있다면 invoke 해서 return 되는 값을 받아서 그 값을 가지고 assert 하면 됩니다.
완성된 소스는 아래와 같습니다. public class jUnitPrivateTest { @Test public void testJUnitPrivate(){ privatemethod jPrivate = new privatemethod(); Method m; try { m = jPrivate.getClass().getDeclaredMethod("jUnitPrivate",String.class,String.class); m.setAccessible(true); String result =null; String a = "Korea"; String b = "Seoul"; result = (String) m.invoke(jPrivate,a,b); assertEquals("Korea : Seoul",result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @throws java.lang.Exception */ @BeforeClass public static void setUpBeforeClass() throws Exception { } /** * @throws java.lang.Exception */ @AfterClass public static void tearDownAfterClass() throws Exception { } /** * @throws java.lang.Exception */ @Before public void setUp() throws Exception { } /** * @throws java.lang.Exception */ @After public void tearDown() throws Exception { } } 출처 - http://coronasdk.tistory.com/658
|