자바/Java StringBuffer 사용 하기


1. StringBuffer append() : 

매개변수로 입력된 값을 문자열로 변환하여 StringBuffer 인스턴스가 저장하고 있는 문자열의 뒤에 덧붙인다.


예제

StringBuffer sb = new StringBuffer("abc");

StringBuffer sb2 = sb.append(true);

sb.append('d').append(10.0f);

StringBuffer sb3 = sb.append("ABC").append(123);


결과

sb = "abctrued10.0ABC123"

sb2 = "abctrued10.0ABC123"

sb3 = "abctrued10.0ABC123"


2. StringBuffer reverse() :

StringBuffer 인스턴스에 저장되어 있는 문자열의 순서를 거꾸로 나열 한다.


예제

StringBuffer sb = new StringBuffer("0123456");

sb.reverse();


결과

sb = "6543210"



Posted by 양형

댓글을 달아 주세요

  1. 1466411160 2016.06.20 17:25  댓글주소  수정/삭제  댓글쓰기

    잘보고가요~

Java 실행 옵션 정리

Java 2016. 2. 3. 16:33

사용법:java <options> <classfiles> <argument> 또는 

          java <options> -jar file.jar <argument>
options: 옵션
classfiles: 호출될 클래스 파일 이름
file.jar: 호출될 jar파일 이름
argument:main함수에 파라미터로 보내질 문자열


예를들어, main함수를 포함하는 Hello.class 파일이 존재할경우, 
java Hello 로 프로그램을 실행시킬수 있는데, 확장자인 class는 생략할수 있지만, 
대소문자는 구별하므로, 정확하게 기입해야 한다.
java Hello Greeting 처럼 Greeting을 덧붙일경우, main함수에 문자열인자로 Greeting을 보낼수 있다.

 

a) -client:
자바 HotSpot Client VM을 선택한다. (디폴트 값이다)

 

b) -server:
자바 HotSpot Server VM을 선택한다.

 

c) -classpath (-cp):
참조할 클래스 파일 패스를 지정하는데, jar파일, zip파일, 클래스파일의 디렉터리 위치를 기술한다.
각 클래스파일 패스는 콜론(:)을 통해서, 분리시켜 기술한다
자바VM은  자바프로그램을 로딩시, -classpath로 지정된 클래스 패스나, java플래폼이 설치된, 운영체제에서의 
환경변수로 지정된, 클래스패스를 통해서, 클래스 파일들을 참조하게 된다.

 

d) -D <property name>=<property value>:
시스템의 property 값을 설정한다.

ex) java -Djava.library.path=. HelloWorld

자바의 시스템 property(속성)중 "java.library.path"값을 "." (현재디렉터리)로 지정해서, HelloWorld 실행시켜라는 의미 이다.

위와같이 자바VM에 지정된 속성을 실행시 -D옵션을 사용해서, 변경, 지정할수 있다.

 

e) -jar 파일이름:

jar파일로 압축되어져 있는 자바 프로그램을 실행시킨다.

클래스 파일이름 대신 jar파일을 사용해서, 압축되어져 있는 자바 프로그램을 실행시킬수 있는데, 위프로그램이 제대로 실행되어지기 위해서, Jar파일안의 manifest라는 텍스트 파일에 Main-Class:classname 같은 형태의 텍스트 라인이 포함되어 있어야 한다.

그리고, 여기에 기술된 classname은 main함수를 포함하고 있는 클래스 이름이 되어야 한다.

 

f) -verbose:

자바프로그램 실행되어지는 정보를 화면에 출력해준다.

-verbose:class

로딩되어지는 각클래스들의 정보를 화면에 출력한다.

-verbose:gc

garbage collection 이벤트를 화면에 출력한다.

-verbose:jni

native 함수들과 다른 자바 native 인터페이스 사용에 대한 정보를 출력한다

 

g) -version:

현재 JVM의 버젼 정보만 출력한다

 

h) -showversion:

현재 JVM의 버젼정보를 출력한다.

java -showversion HelloWolrd

와 같이 자바 프로그램을 실행시키면서, 자바 버젼정보를 출력할수 있다.

 

i) -X

비표준 자바옵션 리스트를 화면에 출력해준다.

 

-Xms, -Xmx 

자바를 구동시, JVM이 사용가능한 최대 메모리 사이즈를 변경합니다.

JVM이 자바프로그램을 구동하기 위해, 초기설정된 메모리사이즈는 64M입니다.

사용방법은 다음과 같습니다

java -Xms <초기힙사이즈> -Xmx <최대힙사이즈>

예를들어, Hello.class 자바 프로그램을 시작시, 256M(메가)의 힙사이즈를 할당하며, 최대 512M의 힙사이즈를 할당받고 싶다면,  다음과같이 합니다.

java -Xms256m -Xmx512m Hello


-XX:PermSize,  -XX:MaxPermSize

클래스 메타 정보 메모리 (Xms, Xmx 메모리와 별도로 관리된다.

-XX:PermSize=64m -XX:MaxPermSize=256m

Posted by 양형

댓글을 달아 주세요

java.net.UnknownHostException

Java 2016. 1. 28. 17:57
  • [원인]

웹 서버의 DNS 설정이 되어있지 않아서 발생되는 문제입니다.

이 문제는 localhost 환경에서는 발생되지 않지만, 직접 설치된 서버 혹은 외부서버에서 가동 시에 문제가 될 수 있습니다.

이 문제는 SNMP 통신 혹은 PING 등의 Network 관련 작업을 수행할 경우,

해당 웹 서버에서 외부로의 이동이 요구될 때 발생될 수 있는 문제입니다.

  • [해결방법]

각 웹 서버의 설정에 맞게 DNS 설정을 합니다.

[1] 서버가 IBM AIX 일 경우

telnet 으로 해당 서버에 접속 cd /etc/resolv.conf 파일을 vi 편집기로 수정하여

해당 ISP 의 네임서버와 IP 주소를 등록합니다.

(ex : 127.0.0.1 localhost )

[2] 서버가 TOMCAT 일 경우

telnet 으로 cd /etc/ 경로로 이동하여 vi 편집기로 hosts 파일을 수정합니다.

[1] 번과 마찬가지로 수정하면 됩니다.

ps. 운영체제는 리눅스 혹은 UNIX 기준입니다. Windows OS 일 경우 아래와 같이 변경하시면 됩니다.

경로 : windows/system32/driver/etc

위의 경로를 따라가면 hosts 라는 파일이 있습니다. 해당 파일을 메모장 혹은 기타 편집기를 이용하여

수정하시면 됩니다.

일반적인 hosts 파일의 내용은 아래와 같습니다만, 상이할 수 있습니다.

#========================================================================================

# Copyright (c) 1993-2006 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host

127.0.0.1 localhost
127.0.0.1 activate.adobe.com
127.0.0.1 3dns-3.adobe.com
127.0.0.1 adobe-dns-2.adobe.com
127.0.0.1 adobe-dns-3.adobe.com
127.0.0.1 ereg.wip3.adobe.com
127.0.0.1 activate-sea.adobe.com
127.0.0.1 wip3.adobe.com
127.0.0.1 wwis-dubc1-vip60.adobe.com
127.0.0.1 activate-sjc0.adobe.com
127.0.0.1 practivate.adobe.com
127.0.0.1 ereg.adobe.com
127.0.0.1 activate.wip3.adobe.com
127.0.0.1 3dns-2.adobe.com
127.0.0.1 adobe-dns.adobe.com

#========================================================================================


Posted by 양형

댓글을 달아 주세요

테스트 코드를 작성 하다보면 가장 먼저 접하게 되는 것은 테스트에 대한 결과 데이터 확인 입니다. 이 같은 확인은 Junit에서 작성 할 수 있게 도와주며 테스트 코드를 만들시 거의 필수적으로 만들어야 합니다.

1. assertThat이란?
assert 메소드는 많은 종류를 가지고 있습니다. 그 종류들을 하나씩 설명을 하지 못하지만 메소드 명으로만으로도 대충 짐작하시면서 사용 할 수 있기때문에 넘기겠습니다. 
 assertThat은 기존의 assert방식에서 나중에 나온 메소드로 자유롭게 검증 할 수 있는 조건을 만들어 준다는 점에서 차이가 나게 됩니다.

2. assertThat 사용


간단한 assertThat 활용입니다. aasetThat(  검사할 대상데이터 ,  Matcher   ) 이런 구조로 되어 있습니다. 
 여기서 is() 메소드가 생소 할 수 있는대요 바로 equals와 비슷한 역활을 수행하게 됩니다. 첫번째 인자값과 같으면 테스트 통과 하게 됩니다.

Posted by 양형

댓글을 달아 주세요

Request method 'HEAD' not supported 오류에 대한 대처 방법.

HTTP method GET, POST 이외에...PUT, DELETE...등 그 중 HEAD....

원리는 간단하다. web.xml 전 단계에서 doFilter 를 이용해 우회 처리를..

01public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throwsIOException, ServletException {
02         
03        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
04        logger.debug("========== isHttpHead(httpServletRequest) : {}", isHttpHead(httpServletRequest));
05        if (isHttpHead(httpServletRequest)) {
06            chain.doFilter(new ForceGetRequestWrapper(httpServletRequest), response);
07        else {
08            chain.doFilter(new FilteredRequest(request), response);
09        }
10    }
11     
12    private boolean isHttpHead(HttpServletRequest request) {
13        return "HEAD".equals(request.getMethod());
14    }
15 
16    private class ForceGetRequestWrapper extends HttpServletRequestWrapper {
17        public ForceGetRequestWrapper(HttpServletRequest request) {
18            super(request);
19        }
20 
21        public String getMethod() {
22            return "GET";
23        }
24    }
25     
26    public void destroy() {
27    }
28}

doFilter 에 분기문을 추가하여 HEAD 요청시 GET으로 Method 를 변경한다.

참고 http://axelfontaine.com/blog/http-head.html 
http://forum.spring.io/forum/spring-projects/web/89981-request-method-head-not-supported

Posted by 양형

댓글을 달아 주세요

ArrayIndexOutOfBoundsException

Java 2015. 12. 16. 09:17
ArrayIndexOutOfBoundsException
- Array 변수의 특정 번째에 데이터가 없는 경우, 즉 Array변수의 데이터가 0부터 7까지 있는데 8번재의 데이터를 찾으려고 시도 할때 발생되는 에러 입니다.
Example Source
public static void main(String[] args) {
   try{
      int value;
      int array[] = {6, 16, 26,36,46,56,66,76};
     int index = 8;
      value = array[index];   // <-- 여기서 발생
      System.out.println("Execution does not reach here if there is a invalid index.");
   }catch(ArrayIndexOutOfBoundsException e){
      System.out.println( "Valid indexes are 0, 1,2,3, 4,5,6 or 7" );
   }
 }
 
 출처 : http://doplait.springnote.com/pages/6458459


Posted by 양형

댓글을 달아 주세요

CommonUtil.java

Java 2015. 12. 15. 17:36
/*
* @(#) CommonUtil.java 2013. 1. 11
*
* Copyright 2011 NHN Corp. All rights Reserved.
* NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package pe.mayciel.fos.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
/**
* 각종 utility method 를 모아놓은 클래스.
* @author Hwang Seong-wook
* @since 2013. 01. 11.
* @version 1.0.0.1 (2013. 01. 11.)
*/
public class CommonUtil {
/**
* str 값을 splitter 구분자로 나누어서 set 에 담고 set 을 반환한다.<br>
* set 에 있는 각각의 값들은 trim 처리를 하여 반환한다.
* @param <T> Set&lt;String&gt; 을 상속받은 객체
* @param set 나누어진 데이터를 담을 set 객체
* @param str 원본 데이터. splitter 로 데이터가 나뉘어져 있다.
* @param splitter 데이터들의 구분자. 정규식 형태.
* @return
*/
public static <T extends Set<String>> T str2Set(T set, String str,
String splitter) {
if (StringUtils.isNotBlank(str)) {
String[] arr = str.split(splitter);
for (String string : arr) {
set.add(string.trim());
}
}
return set;
}
/**
* str 값을 splitter 구분자로 나누어서 HashSet 으로 만들어 반환한다.<br>
* set 에 있는 각각의 값들은 trim 처리를 하여 반환한다.
* @param str 원본 데이터. splitter 로 데이터가 나뉘어져 있다.
* @param splitter 데이터들의 구분자. 정규식 형태.
* @return
*/
public static Set<String> str2HashSet(String str, String splitter) {
return str2Set(new HashSet<String>(), str, splitter);
}
/**
* str 값을 splitter 구분자로 나누어서 list 에 담고 list 를 반환한다.<br>
* set 에 있는 각각의 값들은 trim 처리를 하여 반환한다.
* @param <T> List&lt;String&gt; 을 상속받은 객체
* @param list 나누어진 데이터를 담을 list 객체
* @param str 원본 데이터. splitter 로 데이터가 나뉘어져 있다.
* @param splitter 데이터들의 구분자. 정규식 형태.
* @return
*/
public static <T extends List<String>> T str2List(T list, String str,
String splitter) {
if (StringUtils.isNotBlank(str)) {
String[] arr = str.split(splitter);
for (String string : arr) {
list.add(string.trim());
}
}
return list;
}
/**
* str 값을 splitter 구분자로 나누어서 ArrayList 로 만들어 반환한다.<br>
* set 에 있는 각각의 값들은 trim 처리를 하여 반환한다.
* @param str 원본 데이터. splitter 로 데이터가 나뉘어져 있다.
* @param splitter 데이터들의 구분자. 정규식 형태.
* @return
*/
public static List<String> str2ArrayList(String str, String splitter) {
return str2List(new ArrayList<String>(), str, splitter);
}
/**
* str 값을 splitter 구분자로 나누어서 array 로 만들어 반환한다.<br>
* array 에 있는 각각의 값들은 trim 처리를 하여 반환한다.
* @param str 원본 데이터. splitter 로 데이터가 나뉘어져 있다.
* @param splitter 데이터들의 구분자. 정규식 형태.
* @return
*/
public static String[] str2Array(String str, String splitter) {
if (null == str) {
return null;
}
String[] res = str.split(splitter);
for (int i = 0; i < res.length; i++) {
res[i] = res[i].trim();
}
return res;
}
/**
* str 값을 regexpSplitter 구분자로 나눈 후 enumClass 로 전환하여 리스트에 담아 반환한다.<br>
* enum 으로 전환 시, trim 처리를 한다.
* @param str 원본 데이터. regexpSplitter 로 데이터가 나뉘어져 있다.
* @param regexpSplitter 데이터들의 구분자. 정규식 형태.
* @param enmuClass 변환할 enum 의 class
* @return
*/
public static <T extends Enum<T>> List<T> str2EnumList(String str,
String regexpSplitter, Class<T> enmuClass) {
if (null == str || null == regexpSplitter || null == enmuClass) {
return null;
}
String[] strArr = str.split(regexpSplitter);
List<T> result = new ArrayList<T>();
for (String string : strArr) {
result.add(Enum.valueOf(enmuClass, string.trim()));
}
return result;
}
/**
* str 값을 regexpSplitter 구분자로 나눈 후 enumClass 로 전환하여 array 에 담아 반환한다.<br>
* enum 으로 전환 시, trim 처리를 한다.
* @param str 원본 데이터. regexpSplitter 로 데이터가 나뉘어져 있다.
* @param regexpSplitter 데이터들의 구분자. 정규식 형태.
* @param enmuClass 변환할 enum 의 class
* @return
*/
public static <T extends Enum<T>> T[] str2EnumArray(String str,
String regexpSplitter, Class<T> enmuClass) {
if (null == str || null == regexpSplitter || null == enmuClass) {
return null;
}
String[] strArr = str.split(regexpSplitter);
@SuppressWarnings("unchecked") T[] result = (T[])Array.newInstance(
enmuClass, strArr.length);
for (int i = 0; i < strArr.length; i++) {
result[i] = Enum.valueOf(enmuClass, strArr[i].trim());
}
return result;
}
/**
* collection (List, Set) 의 모든 값을 splitter 값을 구분자로 연결하여 반환한다.<br>
* 객체에서 값은 toString 메소드를 이용하여 가져온다.
* @param col 원본 collection.
* @param splitter 데이터들의 구분자.
* @return
*/
public static String collection2String(Collection<? extends Object> col,
String splitter) {
StringBuilder sb = new StringBuilder();
Iterator<? extends Object> it = col.iterator();
while (it.hasNext()) {
if (sb.length() != 0) {
sb.append(splitter);
}
sb.append(it.next().toString());
}
return sb.toString();
}
/**
* array 안의 값을 splitter 값을 구분자로 연결하여 반환한다.<br>
* 객체에서 값은 toString 메소드를 이용하여 가져온다.
* @param arr
* @param splitter
* @return
*/
public static String array2String(Object[] arr, String splitter) {
if (null == arr || null == splitter) {
return null;
}
StringBuilder sb = new StringBuilder();
for (Object obj : arr) {
if (sb.length() != 0) {
sb.append(splitter);
}
sb.append(obj.toString());
}
return sb.toString();
}
/**
* ?, *, string 으로 이루어진 패턴을 정규식 표현으로 변환하여 반환한다.
* @param rawPattern
* @return
*/
public static String patternGenerator(String rawPattern) {
if (StringUtils.isBlank(rawPattern)) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("^");
rawPattern = rawPattern.toUpperCase();
int len = rawPattern.length();
for (int i = 0; i < len; i++) {
String ch = rawPattern.substring(i, i + 1);
if ("?".equals(ch)) {
sb.append("([\\w\\W]{1})");
} else if ("*".equals(ch)) {
sb.append("([\\w\\W]*)");
} else {
sb.append(ch);
}
}
sb.append("$");
return sb.toString();
}
/**
* HTML Entity code 를 encoding 하여 반환한다.<br>
* encoding 하는 대상 string 은 아래와 같다.<br>
* &, <, >, ", space
* @param str
* @return
*/
public static String entityCodeEncode(String str) {
if (StringUtils.isBlank(str)) {
return str;
}
str = str.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(
">", "&gt;").replaceAll("\"", "&quot;").replaceAll(" ", "&nbsp;");
return str;
}
/**
* HTML Entity code 를 decoding 하여 반환한다.<br>
* decoding 하는 대상 code 는 아래와 같다.<br>
* &amp;amp;, &amp;lt;, &amp;gt;, &amp;quot;, &amp;nbsp;
* @param str
* @return
*/
public static String entityCodeDecode(String str) {
if (StringUtils.isBlank(str)) {
return str;
}
str = str.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll(
"&quot;", "\"").replaceAll("&nbsp;", " ").replaceAll("&amp;", "&");
return str;
}
/**
* fileName 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.<br>
* UTF-8 로 인코딩 된 것으로 간주한다.
* @param fileName 해당 file 의 full path
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(String fileName) throws Exception {
return loadFileByLine(fileName, "UTF-8");
}
/**
* fileName 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.
* @param fileName 해당 file 의 full path
* @param charsetName file 의 charset, null인 경우 UTF-8 로 설정됨.
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(String fileName,
String charsetName) throws Exception {
return loadFileByLine(new FileInputStream(fileName), charsetName);
}
/**
* file 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.<br>
* UTF-8 로 인코딩 된 것으로 간주한다.
* @param file
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(File file) throws Exception {
return loadFileByLine(file, "UTF-8");
}
/**
* file 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.
* @param file
* @param charsetName file 의 charset, null인 경우 UTF-8 로 설정됨.
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(File file, String charsetName) throws Exception {
return loadFileByLine(new FileInputStream(file), charsetName);
}
/**
* fileInputStream 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.<br>
* UTF-8 로 인코딩 된 것으로 간주한다.
* @param fis
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(FileInputStream fis) throws Exception {
return loadFileByLine(fis, "UTF-8");
}
/**
* fileInputStream 에 해당하는 text 파일을 읽어서, 줄 단위 List 로 반환한다.
* @param fis
* @param charsetName file 의 charset, null인 경우 UTF-8 로 설정됨.
* @return
* @throws Exception
*/
public static List<String> loadFileByLine(FileInputStream fis,
String charsetName) throws Exception {
if (StringUtils.isBlank(charsetName)) {
charsetName = "UTF-8";
}
InputStreamReader isr = new InputStreamReader(fis, charsetName);
List<String> result = new ArrayList<String>();
char[] cbuf = new char[1];
StringBuilder sb = new StringBuilder();
while (isr.read(cbuf) > 0) {
if (Character.toString(cbuf[0]).equals("\r")) {
result.add(sb.toString());
isr.read(cbuf);
sb = new StringBuilder();
if (!Character.toString(cbuf[0]).equals("\n")) {
sb.append(cbuf);
}
} else if (Character.toString(cbuf[0]).equals("\n")) {
result.add(sb.toString());
sb = new StringBuilder();
} else {
sb.append(cbuf);
}
}
result.add(sb.toString());
return result;
}
/**
* \r\n, \r, \n 을 &lt;br&gt; 테그로 바꿔준다.
* @param str
* @return
*/
public static String cr2br(String str) {
if (StringUtils.isBlank(str)) {
return str;
}
return str.replace("\r\n", "<br>").replace("\r", "<br>").replace("\n",
"<br>");
}
/**
* &lt; &gt; 로 둘러쌓인 모든 글자를 제거한다.
* @param html
* @return
*/
public static String stripTags(String html) {
String pattern = "(<[^>]*>)";
return html.replaceAll(pattern, "");
}
/**
* 파일 명에서 확장자를 뽑아서 반환한다.<br>
* (즉, 마지막 . 이후의 글자를 반환한다.)<br>
* 반환되는 확장자는 소문자로 치환해서 반환한다.<br>
* 확장자가 없는 경우 빈 string("") 을 반환한다.
* @param fileNm
* @return
*/
public static String getFileExt(String fileNm) {
if (StringUtils.isBlank(fileNm)) {
return "";
}
int lastIdx = fileNm.lastIndexOf(".");
if (lastIdx < 0) {
return "";
}
return fileNm.substring(lastIdx + 1).toLowerCase();
}
/**
* 입력받은 arg 들 중에서 가장 처음으로 null 이 아닌 값을 반환한다.<br>
* 모두 다 null 이면 null 을 반환함.
* @param arg
* @param args
* @return
*/
public static Object getNotNullObj(Object arg, Object... args) {
if (null != arg) {
return arg;
}
for (Object obj : args) {
if (null != obj) {
return obj;
}
}
return null;
}
/**
* 입력받은 string 들 중에서 가장 처음으로 empty 가 아닌 값을 반환한다.<br>
* 모두 다 empty 이면 null 을 반환함.
* @param str
* @param strs
* @return
*/
public static String getNotEmptyStr(String str, String... strs) {
if (StringUtils.isNotEmpty(str)) {
return str;
}
for (String string : strs) {
if (StringUtils.isNotEmpty(string)) {
return string;
}
}
return null;
}
/**
* 입력받은 string 들 중에서 가장 처음으로 blank 가 아닌 값을 반환한다.<br>
* 모두 다 blank 이면 null 을 반환함.
* @param str
* @param strs
* @return
*/
public static String getNotBlankStr(String str, String... strs) {
if (StringUtils.isNotBlank(str)) {
return str;
}
for (String string : strs) {
if (StringUtils.isNotBlank(string)) {
return string;
}
}
return null;
}
/**
* 파일 용량을 표시하는 string 을 받아서 용량에 맞는 string 으로 변환하여 반환한다.<br>
* ex. 2048KB --> 2MB, 1048576 --> 1MB<br>
* <br>
* 소숫점은 표시하지 않는다.<br>
* 소숫점 값을 얻고 싶으면 fileSizeFormat(String value, int maxFractionDigits) 을 이용할 것.
* @param value 파일 용량. 숫자만으로 이루어지면 byte 단위로 취급. 뒤에 K, KB, M, MB 등의 단위를 인식한다(대소문자 구분안함).
* @return
*/
public static String fileSizeFormat(String value) {
return fileSizeFormat(value, 0);
}
/**
* 파일 용량을 표시하는 string 을 받아서 용량에 맞는 string 으로 변환하여 반환한다.<br>
* ex. 2048KB --> 2MB, 1048576 --> 1MB
* @param value 파일 용량. 숫자만으로 이루어지면 byte 단위로 취급. 뒤에 K, KB, M, MB 등의 단위를 인식한다(대소문자 구분안함).
* @param maxFractionDigits 반환하는 숫자에서 표시할 소숫점 자릿수
* @return
*/
public static String fileSizeFormat(String value, int maxFractionDigits) {
if (StringUtils.isBlank(value)) {
return "0B";
}
String regex = "([0-9]+(?:\\.[0-9]+)?)([KMGT]?)";
Pattern pt = Pattern.compile(regex);
Matcher mc = pt.matcher(value.toUpperCase());
if (mc.find()) {
double val = getByteSize(mc);
String unit = "";
if (val < Math.pow(1024, 1)) {
unit = "B";
} else if (val < Math.pow(1024, 2)) {
val /= Math.pow(1024, 1);
unit = "KB";
} else if (val < Math.pow(1024, 3)) {
val /= Math.pow(1024, 2);
unit = "MB";
} else if (val < Math.pow(1024, 4)) {
val /= Math.pow(1024, 3);
unit = "GB";
} else {
val /= Math.pow(1024, 4);
unit = "TB";
}
return formatNumber(val, maxFractionDigits) + unit;
}
return "0B";
}
/**
* 입력받은 string 이 숫자로만 이루어져 있는지 여부를 반환한다.
* @param str
* @return
*/
public static boolean isNumber(String str) {
if (StringUtils.isBlank(str)) {
return false;
}
String numPattern = "[\\d]+";
return Pattern.matches(numPattern, str);
}
/**
* sb 에 th 의 에러로그 값을 추가한다.
* @param sb
* @param th
*/
public static void appendErrorLogs(StringBuffer sb, Throwable th) {
StringWriter sw = new StringWriter();
th.printStackTrace(new PrintWriter(sw));
sb.append(sw.toString());
}
/**
* ko_KR 과 같은 형식으로 되어 있는 locale 값을 {@link Locale} 도메인으로 반환한다.<br>
* 형식이 맞지 않으면 null 을 반환.
* @param localeStr ko_KR 형식
* @return
*/
public static Locale getLocale(String localeStr) {
if (StringUtils.isBlank(localeStr)) {
return null;
}
String[] split = localeStr.split("_");
if (split.length != 2) {
return null;
}
return new Locale(split[0], split[1]);
}
/**
* language 값과 country 값으로 {@link Locale} 도메인을 반환한다.<br><br>
* language 값이 없거나 2자리 미만이면 null 을 반환하고,<br>
* 2자리 이상이면 앞 2자리만 취한 후, 소문자 처리하여 작업한다.<br>
* country 값이 없거나 2자리 미만이면 null 을 반환하고,<br>
* 2자리 이상이면 앞 2자리만 취한 후, 대문자 처리하여 작업한다.
* @param language 언어 값. ko 형식. 앞 2자리만 인식하며, 소문자 처리하여 작업한다.
* @param country 국가 값. KR 형식. 앞 2자리만 인식하며, 대문자 처리하여 작업한다.
* @return
*/
public static Locale getLocale(String language, String country) {
if (StringUtils.isBlank(language) || language.length() < 2) {
return null;
}
if (StringUtils.isBlank(country) || country.length() < 2) {
return null;
}
if (language.length() != 2) {
language = language.substring(0, 2);
}
language = language.toLowerCase();
if (country.length() != 2) {
country = country.substring(0, 2);
}
country = country.toUpperCase();
return new Locale(language, country);
}
/**
* 입력받은 list 의 순서를 역순으로 조정한 새 list 를 반환한다.
* @param list
* @return list
*/
public static <T> List<T> createReverseList(List<T> list) {
if (null == list) {
return null;
}
int listCount = list.size();
List<T> newList = new ArrayList<T>(listCount);
for (int i = listCount - 1; i >= 0; i--) {
newList.add(list.get(i));
}
return newList;
}
/**************************************************
*
* Private Methods
*
**************************************************/
/**
* matcher 의 정보를 기반으로 용량을 byte 로 환산하여 반환한다.
* @param matcher
* @return
*/
private static double getByteSize(Matcher matcher) {
double val = Double.parseDouble(matcher.group(1));
String unit = matcher.group(2);
if ("K".equals(unit)) {
val *= Math.pow(1024, 1);
} else if ("M".equals(unit)) {
val *= Math.pow(1024, 2);
} else if ("G".equals(unit)) {
val *= Math.pow(1024, 3);
} else if ("T".equals(unit)) {
val *= Math.pow(1024, 4);
}
return val;
}
/**
* 숫자를 정해진 양식으로 다듬어서 반환한다.
* @param val
* @param maxFractionDigits
* @return
*/
private static String formatNumber(double val, int maxFractionDigits) {
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(maxFractionDigits);
return nf.format(val);
}
}


'Java' 카테고리의 다른 글

[오류]org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'HEAD' not supported  (0) 2015.12.16
ArrayIndexOutOfBoundsException  (0) 2015.12.16
CommonUtil.java  (0) 2015.12.15
jUnit 사용하기  (0) 2015.12.15
Eclipse 디버거 사용법  (0) 2015.11.24
자바 I/O란  (0) 2015.11.24
Posted by 양형

댓글을 달아 주세요

jUnit 사용하기

Java 2015. 12. 15. 17:35



'Java' 카테고리의 다른 글

ArrayIndexOutOfBoundsException  (0) 2015.12.16
CommonUtil.java  (0) 2015.12.15
jUnit 사용하기  (0) 2015.12.15
Eclipse 디버거 사용법  (0) 2015.11.24
자바 I/O란  (0) 2015.11.24
Exception Handling  (0) 2015.11.02
Posted by 양형

댓글을 달아 주세요

Eclipse 디버거 사용법

Java 2015. 11. 24. 12:05

꽤 많은 분들이 디버거의 존재 자체를 모르고 있거나 혹은 디버거가 있다는 사실은 알아도 그 효용성에 의문을 제기하곤 합니다. 왜냐하면, 우리에겐 Log 클래스나 혹은 printf같은 훌륭한(?) 디버깅 도구가 있다고 생각하기 때문이죠. 물론 이렇게 필요한 변수를 찍어보면서 어떤 곳에서 버그가 있는지를 알아보는 일이 잘못된 일은 아닙니다만 복잡한 여러 상황이 맞물려 재현되는 버그는 이러한 고전적인(?) 방법을 써서 알아보기가 매우 어렵습니다.

원인을 정확히 그리고 빨리 파악하려면 디버거의 사용법을 숙지하고 사용하는 것이 가장 좋습니다. 대부분의 개발 환경에서 디버거를 제공하는데 다행히 이클립스에서도 쓸만한 디버거를 내장하고 있습니다.

오늘 포스팅에서는 이클립스 디버거 사용법에 대해 다루어 볼까 합니다.

이클립스 디버거 뷰


이클립스는 디버거 뷰를 제공하여 디버거를 사용할 수 있도록 합니다. 디버거 뷰는 어디에서 확인할 수 있을까요? 바로 우측 상단에 Debug 뷰에 들어가면 그곳에서 확인할 수 있습니다.

debugger-view

디버깅의 시작


그렇다면 어떻게 디버깅을 활성화한 상태로 프로그램을 실행할 수 있을까요? 상단 메뉴의 Run에서 프로그램을 실행할 때 Debug를 이용하여 프로그램을 실행하면 디버거가 작동하게 됩니다.

run-debug

브레이크 포인트 설정과 뷰


보통 디버깅을 할 때 가장 먼저 하는 일이 브레이크 포인트를 잡는 일입니다. 브레이크 포인트를 에러가 일어나는 라인이나 혹은 의심이 가는 변수를 추적할 수 있는 라인쯤에 잡아놓고 프로그램을 디버깅하면 해당 라인을 실행할 때 디버거가 작동하게 되고 그곳에서 프로그램을 라인 별로 진행해가며 관찰을 진행할 수 있게 됩니다.

브레이크 포인트 설정은 매우 간단합니다. 편집기 왼쪽에 파란 부분(마커 바)을 더블 클릭하게 되면 파란 원이 생기는데 이 원이 브레이크 포인트입니다. 혹은 오른 클릭하여 Toggle break point를 누르면 됩니다. 설정 후 다시 더블 클릭하게 되면 브레이크 포인트가 사라지게 됩니다.

toggle-breakpoint

또한, 디버그의 브레이크 포인트 뷰에서 지금까지 걸어놓은 모든 브레이크 포인트들의 위치를 확인할 수 있고 활성화/비활성화, 삭제도 할 수 있습니다. 여러 브레이크 포인트가 걸려있을 때에는 이 탭에서 확인하고 관리하는 것이 더 편합니다.

breakpoint-view

또한, 디버깅을 진행하고 있는 도중에도 다른 의심이 가는 라인에 브레이크 포인트를 걸 수 있습니다.

스텝 단위 진행


지정한 브레이크 포인트에 다다르면 동시에 디버거가 작동하게 되고 그 라인부터 스텝 단위의 진행을 할 수 있게 됩니다.

debug-ui

이제 이 뷰의 버튼들을 이용하여 현재 상황을 진행하거나 되돌릴 수 있습니다. 자주 사용하는 버튼의 사용법을 알아보면

  1. Resume : 다음 브레이크 포인트를 만날때까지 진행합니다.
  2. Suspend : 현재 작동하고 있는 쓰레드를 멈춥니다.
  3. Terminate : 프로그램을 종료합니다.
  4. Step Into : 메서드가 존재할 경우 그 안으로 들어가 메서드 진행 상황을 볼 수 있도록 합니다.
  5. Step Over : 다음 라인으로 이동합니다. 메서드가 있어도 그냥 무시하고 다음 라인으로 이동합니다.
  6. Step Return : 현 메서드에서 바로 리턴합니다.
  7. Drop to Frame : 메서드를 처음부터 다시 실행합니다.

등이 있습니다.

실제로 디버깅 화면에서 버튼들을 눌러보면 쉽게 그 쓰임새를 아실 수 있습니다.

변수의 상태 확인을 쉽게 해주는 변수 뷰


디버깅을 진행하는 도중 변수의 값이나 객체의 상태를 알고 싶은 상황이 생기게 됩니다. 현재 의심이 가는 변수 이외에도 이 변수에 영향을 끼칠 다른 변수들이나 객체들의 상황을 실시간으로 검사할 필요가 있을 때 변수 뷰를 이용하면 도움을 얻을 수 있습니다.

variables-view

이곳에서 변수나 객체의 상태를 확인하고 변수의 상황에 대해서 저장할 수 있습니다. 변수나 객체의 상황을 모두 저장해서 클립보드에 붙이고 싶은 일이 생기면 해당 변수를 오른클릭 후 Copy Variables를 선택합니다.

copy-var

편집 창으로 돌아가 변수에서 Command + shift + i를 누르게 되면(혹은 오른 클릭 후 Inspect를 선택) Inspector 창이 뜨게 됩니다. 이 창에서 다시 한번 Command + shift + i를 누르면 해당 변수를 Expression 뷰로 보내게 되고 이곳에서 지속해서 변수의 상태를 관찰할 수 있게 됩니다.

inspector

Expression 뷰 이용


Expression 뷰에서는 변수 이름을 입력하거나 수행해보고 싶은 명령어를 직접 입력하여 그 결과 값을 관찰할 수 있습니다. 결과 값을 관찰할 뿐만 아니라 Expression에 써놓은 변수들은 명시적으로 지우지 않는 이상 계속해서 관찰을 수행하기 때문에 변해가는 상황을 지속해서 관찰할 일이 있는 변수나 명령문을 등록해놓기에 좋습니다.

expression-view

Display 뷰 이용


디스플레이 뷰에서는 현 문맥에서 사용할 수 있는 명령어를 실행하거나 변수의 값을 조작하는 일을 수행하기에 적합한 환경을 제공합니다. Expression에서도 비슷한 기능을 제공하지만, 디스플레이 뷰를 이용하는 것이 더 편합니다. 메모장과 같이 쉽게 쓰고 지울 수 있기 때문입니다.

또한, 원본 코드의 수정 없이 편하게 현재의 맥락을 변화시킬 수 있는 것이 가장 큰 장점이라고 볼 수 있습니다.

필요한 명령어들을 적어놓은 후 실행하고 싶은 부분만 드래그하여 수행하거나 혹은 값을 리턴받을 수 있습니다. 지금은 boolean변수 하나의 값을 바꿔보기도 하고 조건 값에 따라 무언가를 리턴 받도록도 해놓은 상황을 스크린 샷으로 담아보았습니다.

값을 반환받고 싶을 때는 두 번째 버튼을, 단순히 실행만 할 때에는 세 번째 버튼을 누르면 됩니다.

display-get-result두 번째 버튼을 눌러 값을 반환받는 상황입니다.

display-execute단순히 실행만 하려면 세 번째 버튼을 누릅니다.

브레이크 포인트에 조건 걸기


브레이크 포인트에 조건을 거는 것이 굉장히 유용할 때가 있습니다. 특히 반복문안에 들어가 있는 코드들을 디버깅할 때 유용하지요. 반복문의 경우 모든 상황을 검사한다기보다는 특정 조건에서 값이 어떻게 들어가는지를 분석하는 경우가 더 많은데 이러한 상황을 검사하기 위해서 브레이크 포인트에 조건을 걸어야 합니다.

브레이크 포인트를 거는 과정까지는 똑같습니다. 브레이크 포인트를 건 후 그 포인트에서 오른 클릭을 하면 Breakpoint properties 옵션이 있는 것을 확인할 수 있습니다. 이 옵션에서 조건문을 설정하여 디버거의 활성화 조건을 설정할 수 있습니다.

breakpoint-properties

먼저 Conditional을 활성화하여 어떤 조건에서 디버깅 화면으로 전환할지를 쓰면 되는데 이 창에 조건식을 쓰면 됩니다.

breakpoint-condition

또 hit count를 이용하여 조건을 걸 수도 있습니다. hit count에 값을 적용하면 해당 라인에 브레이크 포인트가 hit count만큼 잡힌 이후 디버깅 화면으로 전환하게 됩니다. hit count 옵션은 반복문에서 한 100번쯤 이후에 디버깅을 시작하고 싶거나 하는 일이 생길 때 유용하게 쓸 수 있습니다.

breakpoint-hitcount


http://spoqa.github.io/2012/03/05/eclipse-debugger.html


'Java' 카테고리의 다른 글

CommonUtil.java  (0) 2015.12.15
jUnit 사용하기  (0) 2015.12.15
Eclipse 디버거 사용법  (0) 2015.11.24
자바 I/O란  (0) 2015.11.24
Exception Handling  (0) 2015.11.02
초보 개발자를 위한 디버깅 방법 소개  (0) 2015.10.27
Posted by 양형

댓글을 달아 주세요

자바 I/O란

Java 2015. 11. 24. 10:30

자바 I/O란

자바에서 중급정도 소리를 들으려면 IO와 NIO를 넘어야 할 수 밖에 없죠.
저도 공부를 한다는 생각으로 이곳 저곳 참조해서 나름대로 정리를 연재해 나갈 생각입니다 
허접한 실력이지만 함께 나누는 공간이 되었으면 합니다. 많이 부족하니 더 좋은 내용, 덧붙일 내용이나 틀린점 있으면 바로바로 올려주시면 감사드리겠습니다.
결국 함께 공부하자는 목적이 제일 큰 듯 합니다. 

오늘 아침 출근해서 메일을 확인하는데 운영자님께서 메일을 보내주셨더라구요.
"지금 시작하지 않으면 늦는다. 고로 지금 하는 것이 제일 빠르다"라는 메일을 받고 느낀 것이 많았답니다. 
피할 수 없다면 즐깁시다 여러분! 

1. 입출력 스트림

  • 자바에서는 모든 데이터의 입출력을 스트림이라는 개념에 의해 이루어집니다.
  • 데이터 입출력시 모든 데이터를 형태와는 관계 없이 일련된 흐름으로 전송을 하는 것이 스트림 입출력 모델의 기본 개념입니다.
  • 자바에서의 입출력은 기본적으로 아래처럼 두 가지 형태로 이루어집니다.

1.1 바이트 스트림(ByteStream)

  • 바이트, 바이트 배열, 정수, 데이터 등의 흐름
  • InputStream/OutputStream Class, 그리고 이들의 하위 클래스를 통해서 제공
  • 크기는 8bit(=1byte) 갖는 스트림들이 입출력

1.2 문자 스트림(CharacterStream)

  • 문자, 문자 배열, 문자열의 흐름
  • Reader/Writer Class, 그리고 그들의 하위 클래스를 통해서 제공
  • 크기는 16bit(=2bytes) 갖는 유니코드 문자들의 스트림

2. 부가설명.

  • Reader/Writer Class는 기본적으로 InputStream/OutputStream Class와 같은 기능을 제공해 주고 있지만,
    ByteStream method는 바이트 또는 바이트 배열에 대해 동작하고, CharacterStream method는 문자, 
    문자 배열, 또는 문자열에 대해서 동작하도록 되어 있습니다. 
    따라서, ByteStream을 위해 사용가능한 대부분의 기능은 CharacterStream에 대해서도 사용가능합니다.
  • CharacterStream을 사용하는 이유는 두바이트 유니코드 방식으로 처리를 하므로 거의 대부분의 언어를 처리할 수 있기 때문입니다. 중공 빼고^^
    그러나 ... 텍스트 파일을 보면 아주 다양한 encoding 형태를 보여 거의 처리가 불가능하죠. 
    그래서 자바에서는 브릿지 개념으로 제공되는 클래스들이 있습니다.

텍스트 파일 처리방식이 전세계적으로 동일하거나 아니면 단일언어이면 아래에 있는 것들이 필요없겠죠.

  • InputStreamReader : Byte InputStream으로부터 한바이트씩 죄다 읽어 들여 주어진 인코딩에 해당하는 문자들로 만들어 줍니다. 그냥 읽는다면 깨질 확률이 아주 높겠죠.
  • OutputStreamWriter : 반대로 문자들을 한바이트씩 쪼개어서 바이트들로 변환해 Byte OutputStream으로 쓰겠죠. 

다음으로는 ByteStream / CharacterStream의 클래스들을 살펴보기로 하죠.

'Java' 카테고리의 다른 글

jUnit 사용하기  (0) 2015.12.15
Eclipse 디버거 사용법  (0) 2015.11.24
자바 I/O란  (0) 2015.11.24
Exception Handling  (0) 2015.11.02
초보 개발자를 위한 디버깅 방법 소개  (0) 2015.10.27
스택트레이스(stack trace)  (0) 2015.10.27
Posted by 양형

댓글을 달아 주세요