이 블로그 검색

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

2011년 9월 17일 토요일

java annotation3

 annotation의 적용 사례로
프로젝트의 유스케이스를 추적하는 어노테이션을 작성하는 것을 정리해 보도록 하겠습니다.

 프로젝트 관리자는 구현된 유스케이스의 수를 이용하여 프로젝트의 진척도를 알 수 있으며 개발자는 시스템 내의
비즈니스 규칙을 변경하거나 디버깅할 때 유스케이스를 쉽게 찾을 수 있으므로 프로젝트의 유지보수를 쉽게 할 수 있을것입니다.

- @UseCase 선언
UseCase.java

//: annotation.usecase/UseCase.java
package annotation.usecase;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id();
public String description() default "no description";
}
- 다음은 클래스의 메소드에 유스케이스 정보를 기록한 예제입니다.
PasswordUtils.java
//: annotation.usecase/PasswordUtils.java
package annotation.usecase;

import java.util.List;

public class PasswordUtils {

@UseCase(id = 47, description = "password must contain at least one numeric")
public boolean validatePassword(String password){
return (password.matches("\\w*\\d\\w*"));
}

@UseCase(id = 48)
public String encryptPassword(String password){
return new StringBuilder(password).reverse().toString();
}

@UseCase(id = 49, description = "New password can't equal previously used ones")
public boolean checkForNewPassword(List<String> prevPasswords, String password){
return !prevPasswords.contains(password);
}
}

*어노테이션 프로세스 작성하기!
어노테이션을 읽고 처리할 수 있는 프로세서가 없다면 어노테이션은 단지 주석에 불과할 뿐입니다.
그러므로 어노테이션을 사용하는 과정에서 해당 프로세서를 정의하고 적용하는 것이 중요합니다.
자바 SE5는 이러한 툴을 만들기 위한 리플렉션 API의 확정성을 제공합니다.

- 다음은 어노테이션을 적용한 PasswordUtils 클래스를 읽고 리플렉션을 사용하여 @UseCase를 검색하는 어노테이션 프로세스 입니다.
UseCaseTracker.java

package annotation.usecase;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class UseCaseTracker {

public static void trackUseCases(List<Integer> useCases, Class<?> cl){
for(Method m : cl.getDeclaredMethods()){
UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null){
System.out.println("Found Use Case :" + uc.id() + " " + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for(int i : useCases){
System.out.println("Warning : Missing use case-" + i);
}
}
/**
* @param args
*/
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}

}

-실행결과







*어노테이션 요소

UseCase.java에 정의된 @UseCase 태그는 int 형의 id요소와 String 형의 description 요소를 가지고 있습니다.
다음은 어노테이션 요소에 허용되는 타입의 목록입니다.
- 모든 기본형 타입(int, float, boolean 등)
- String
- enum
- Annotation
- 상기 타입의 배열

->포장클래스 (Wrapper Class) 는 사용할수 없다.

자 이정도면 어느정도 annotation 에 대한 감이 잡히시는지요?
시간이 된다면 이어서 어노테이션을 이용하여 데이터베이스 생성 스크립트를 만들어주는 예제에 대해서
정리해 보도록 하겠습니다. 

java annotation2

* 어노테이션의 정의일반적인 인터페이스의 정의와 매우 유사함
컴파일러는 다른 자바 인터페이스와 마찬가지로 어노테이션을 클래스로 컴파일 한다.


package annotation.begin;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test { }
어노테이션 정의시 @Target, @Retention 이라는 메타-어노테이션이 필요함.
@Target 은 어노테이션을 적용할 대상(예를들면 메소드 또는 필드)
@Retention 은 해당 어노테이션이 소스코드(SOURCE), 클래스파일(CLASS), 또는 런타임(RUNTIME) 중 어디에서 적용되는지 정의.

위의 @Test와 같이 요소를 가지지 않은 어노테이션은 표식 어노테이션(marker annotation)이라고 불린다.

java annotation

컴파일러나 외부툴들에게 부연설명을 하는 역할을 한다.

예를들면,

@Override

JDO에서
@Version

등이있다.

기존에는 이런 정보들을 xml파일로 작성하여 해당 툴들에게 알렸다.

2011년 8월 23일 화요일

jsp에서 useBean 과 import 의 차이


--------------------------------- 질문 -------------------------------------------
---------------------------------------------------------------------------------

일전에 jsp 페이지 내에서 useBean으로 객체를 생성하는 것과 객체의 직접 생성에 관한 글을 어디선가 봤었는데 다시 찾아보려니 찾을 수가 없습니다 ㅠ.ㅠ
<%@ import="test.Test"%>
<jsp:useBean name="test" class="test.Test" scope="session"/>
이것과
<%@ import="test.Test"%>
<%
      Test test = new Test();
%>
이렇게 만드는 방식에서의 scope 에 관해서
혹시 일전의 링크 주소를 알고 계시거나 위에 관해서 설명해 주실수 있는 분 부탁드립니다.


-----------------------------------답변----------------------------------------------
-------------------------------------------------------------------------------------
첫번째 질문만 답 드리께요..제가 아는 선에서만요..
useBean으로 생성한거랑 new 해서 생성한거랑의 차이점을 소스로 한번 확인해보세요..

각각의 경우 .java로 변환된 work폴더아래의 jsp.java파일을 보시면 이부분이 틀릴겁니다.

useBean으로 객체생성하면 아래 소스가 _jspService라는 메소드에 추가되거든요..

jsp 라이프 사이클 보시면 _jspService는 알수 있으리라 생각합니다.

synchronized (pageContext) {
sb= (oil.common.board.GongiLogic)
pageContext.getAttribute("sb",PageContext.PAGE_SCOPE);
if ( sb == null ) {
_jspx_specialsb = true;
try {
sb = (oil.common.board.GongiLogic) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "oil.common.board.GongiLogic");
} catch (ClassNotFoundException exc) {
throw new InstantiationException(exc.getMessage());
} catch (Exception exc) {
throw new ServletException (" Cannot create bean of class "+"oil.common.board.GongiLogic", exc);
}
pageContext.setAttribute("sb", sb, PageContext.PAGE_SCOPE);
}
}

제 생각엔 scope를 쓸 수 있느냐..없느냐 차이 같습니다. 맞는지 아닌지 딴 분들도 의견 주셨음 합니다.

그 외엔 sb = (oil.common.board.GongiLogic) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "oil.common.board.GongiLogic");

이 코드가 뭔가 특별한 건지..아마 이 코드를 아시면 알고자 하시는 차이점을 정확히 아실수 있을것 같아요..
저도 궁금..

일단 scope을 쓸수 있느냐 없느냐의 차이고 뭐 jsp에서 지원해주는 기능 마다하고 new 해서 생성하는건 적절한 코딩에서 멀어지는 길이니...
그럼 수고하세요..

위처럼 객체를 생성시에 scope에 관해서 부탁드립니다.






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








----------------------------------- 질문 -----------------------------------------------
Ok on a Java Server Page I can use a function in two ways:
Either I declare
<jsp:useBean id="myBean" scope="session" class="mypack.mysubpack.MyClass" />
or I declare
<%@ page import = "mypack.mysubpack.MyClass" %>

In each case I can call a function later by coding

MyClass.myFunction();

So what is the difference between the two variantes?

Why are Beans invented if we don't need them because we have the import statement ?

Ulf



---------------------------------------------------------------------------답변-------------------------------------------------------------


(Ulf Meinhardt) writes:

> Ok on a Java Server Page I can use a function in two ways:
> Either I declare
> <jsp:useBean id="myBean" scope="session" class="mypack.mysubpack.MyClass" />


This checks if an object called "myBean" exists in the session
attributes, and if necessary creates and puts it there. It also adds a
variable called "myBean" that can be referenced later, in e.g.
<%=myBean.getFoo()%>.

> or I declare
> <%@ page import = "mypack.mysubpack.MyClass" %>


This does nothing more than add an import statement in the beginning
of the generated servlet.

> In each case I can call a function later by coding
>
> MyClass.myFunction();
>
> So what is the difference between the two variantes?


See above.

> Why are Beans invented if we don't need them because we have the
> import statement ?


Because beans aren't limited to what you artificially limit them to.
You can do much more with beans than just call static methods in their
classes.

2011년 8월 11일 목요일

assert문

1.       assert expression1;

2.       assert expression1 : expression2;



위의 두 문장에서 expression1 이 검증이 필요한 Boolean 표현식이다. 이 표현식은 개발자가 프로그램이 수행되는 동안 항상 ‘참(true)’이 되어야 한다고 요구하는 조건이 된다. 두 번째 문장에 있는 expression2 는 검증이 실패했을 때 상세 정보를 표현하기 위한 메시지로 String으로 변환 가능한 형태여야 한다.

[출처] 자바 assert|작성자 스나이퍼

2011년 7월 18일 월요일

세션

request.setAttribute("Exist", "N");
로 설정한 값은


request.getAttribute("Exist");
로 가져와야한다.

2011년 7월 17일 일요일

파일 확장자 구하기

fileExtIndex = fileName.lastIndexOf(".");
fileExt         = fileName.substring(fileExtIndex);

2011년 5월 16일 월요일

이 인터넷 사이트를 열 수 없습니다. 요청한 사이트를 사용할 수 없거나 찾을 수 없습니다.

  • 원인
Internet Explorer에서 보안 웹 사이트(SSL)의 Microsoft Office 문서(.doc 파일, .xls 파일, .ppt 파일 등)를 열거나 다운로드하려고 하면 문서를 사용할 수 있고 서버에서 다운로드할 수 있는 경우에도 다음 오류 메시지 중 하나가 나타날 수 있습니다.



  • 해결방법
다음과 같이 Cache-Control 을 세팅해주면 됩니다.
 response.setHeader("Cache-Control", "max-age=0");




<%@ page contentType="application/vnd.ms-excel; charset=UTF-8" %>
<head>
<%
    response.setHeader("Content-Type", "application/vnd.ms-xls");
    response.setHeader("Content-Disposition", "attachment;filename=DownloadFile.xls");
    response.setHeader("Content-Description", "JSP Generated Data");  
    response.setHeader("Pragma", "public");
    response.setHeader("Cache-Control", "max-age=0");%>
</head>
<body> 
..........내용............
</body>
</html>

2011년 4월 3일 일요일

@SuppressWarnings("serial")

Hi, If your class implements the interface java.io.Serializeable, either directly or indirectly, you should provide a field called serialVersionUID. If you do not provide this field and compile the class, you will get a warning at compile time. If you do not want this warning, simply add the line @SupressWarnings("serial") before your class definition. Make sure, you use Java 5.0 in order to use annotations. HTH, - Günthe

2011년 3월 28일 월요일

자바 정렬


아래 두가지 방법이 있다.

java.lang Interface Comparable<T>
java.util Interface Comparator<T>

두 인터페이스를 이용해서 Collections.sort를 이용해 정렬을 할 수가 있는데,
List에 들어가는 객체에 Comparable을 implements함으로써, 정렬을 할 수있게 된다.

방법1. Comparable을 implements한다.

class PersonalInfo implements Comparable<PersonalInfo>{
 
 private String name = null;
 
 private String phoneNumber = null;
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
   this.name = name;
 }
 
 public String getPhoneNumber() {
  return phoneNumber;
 }
 
 public void setPhoneNumber(String phoneNumber) {
  this.phoneNumber = phoneNumber;
 }
 
  public boolean getSortingMode() {
  return sortingMode;
 }
 public void setSortingMode(boolean sortingMode) {
  this.sortingMode = sortingMode;
 }
 
 
@Override
 public int compareTo(PersonalInfo o) {
    return name.compareTo( o.getName() );
  }
}

compareTo라는 메소드를 구현해야 하는데, 그 안에 비교하고자 하는 항목을 compareTo를 이용하여
비교해준 후,
Collections.sort()의 파라미터로 PersonalInfo객체가 들어있는 리스트를 넣어주기만 하면 된다.

위와 같은 방법은 편리하나, 여러가지 항목으로 정렬을 해야 할 경우 제약이 좀 있다.

그래서 사용하는 것이,
바로 Comparator 이다.

방법2. Comparator사용.

     Comparator<PersonalInfo> comparator = new Comparator<PersonalInfo>(){
      @Override
      public int compare(PersonalInfo o1, PersonalInfo o2) {      
       return o1.getName().compareTo( o2.getName() );
      }      
     };
     Collections.sort( list, comparator );

와 같은 방법으로 할 수 있다. 여러개의 정렬 항목에 따른 comparator를 만든 후, Collections의 파라미터로 던져주면,
정렬은 더이상 고민하지 않아도 될 것이다.

참고로 Collections.sort()의 documents내용은 다음과 같다.
public static <T extends Comparable<? super T>> void sort(List<T> list)
public static <T> void sort(List<T> list, Comparator<? super T> c)

2011년 3월 23일 수요일

스마트폰으로 접근시 모바일홈페이지로 자동이동

<% 
String browser = request.getHeader("User-Agent");
boolean result = false;
if (browser.indexOf("Android") >0) {  // 안드로이드
 result = true;
 } else if (browser.indexOf("iphone","iPod","PPC") > 0) {  // 아이폰등등..
 result = true;
 }
 if (result == true) {
 response.sendRedirect("이동할경로");
 }
%>









<script type="text/javascript">
var mobileKeyWords = new Array('iPhone', 'iPod', 'BlackBerry', 'Android', 'Windows CE', 'LG', 'MOT', 'SAMSUNG', 'SonyEricsson'); 
for (var word in mobileKeyWords){ 
    if (navigator.userAgent.match(mobileKeyWords[word]) != null){ 
        location.href = "http://m.i-sh.co.kr/"; 
        break; 
    } 



</script>

2011년 1월 30일 일요일

Calendar TimeZone 설정하기

TimeZone tz = TimeZone.getTimeZone("GMT+09:00");
                Calendar oCalendar = Calendar.getInstance(tz);  // 현재 날짜/시간 등의 각종 정보 얻기
                System.out.println("현재 년: " +  oCalendar.get(Calendar.YEAR));
                String year =Integer.toString(oCalendar.get(Calendar.YEAR));
                   System.out.println("현재 월: " + (oCalendar.get(Calendar.MONTH) + 1));
                   String month = Integer.toString(oCalendar.get(Calendar.MONTH) + 1);
                   System.out.println("현재 일: " +  oCalendar.get(Calendar.DAY_OF_MONTH));
                   String day=Integer.toString(oCalendar.get(Calendar.DAY_OF_MONTH));
                   System.out.println("현재 시: " +  oCalendar.get(Calendar.HOUR_OF_DAY)); // 24시간제

2011년 1월 20일 목요일

replace

replace 는 스트링대 스트링으로 replace 할 수 있었고
replaceAll는 정규표현을 사용하여 바꿀 수 있었습니다.

2011년 1월 16일 일요일

인코딩

  • 웹브라우져에게 인코딩 정보 전달
response.setContentType("text/html; charset=euc-kr");
내용물의 형식을 알려주는것
text의 html 이고, charset 은 euc-kr 이라고 웹 브라우저에게 알려주는 구문이다.

       - 이걸 해 놓지 않으면 브라우져가 알아서 문서를 인코딩함

  • get방식에서 받아온 정보 인코딩 하기
기본적으로 웹 환경은 문자를 무조건 iso-8859-1 이라는 케릭셋으로 인코딩해서 전송한다.
getParameter로 받아온 값을  재처리를 해주어야한다.
iso-8859-1 -> euc-kr
첫번째로 String name 으로 받은 iso-8859-1 로 전송된 넘어온 파라메터 값을
byte 단위로 쪼갠다.
byte[] b = name.getBytes("iso-8859-1");
쪼개어 배열 b 에 저장된 데이터를 euc-kr 로 재조합하여 변수 name 에 넣는다.
name = new String(b, "euc-kr");

  • post방식으로 넘어온 정보 인코딩 하기
get 방식은 iso-8859-1 로 들어온것을 byte 단위로 쪼개었다가 다시 재조합하는 과정을 거치는데 반해
post 방식에서는 request.setCharacterEncoding("euc-kr"); 한줄로 간단하게 처리가 됨을 알 수 있다.
더불어 파라메터 값이 하나가 아니고 여러개일때 get방식에서는 파라메터 하나하나를
각각 처리 해주어야하지만 post 방식에서는 저 한줄만으로 모두 처리가 되므로 아주 편리하다.


  • 웹브라우져에 보낼 데이터 인코딩 하기
response.setCharacterEncoding("euc-kr");