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

2017년 2월 1일 수요일

[spring] @Scheduled 로 이번달의 마지막 일자에 실행하기가 안될때

Spring 에서 @Scheduled 어노테이션 사용시 해당월의 마지막에 실행하려고
'L' 문자를 사용하려고 하면 에러가 발생한다.

그래서 매일 실행 하면서 java에서 마지막 날을 확인해서 실행 하는 방식으로 처리 하였다.

@Scheduled(cron="1 0 0 * * *")
private void SchedulerEndDayOfMonth() {
  
    Calendar cal = Calendar.getInstance();
    // 오늘이 월의 마지막 일인지 확인
    boolean isLastDay = cal.get(Calendar.DATE) == cal.getActualMaximum(Calendar.DATE);
 
    if(isLastDay) {
        // 실행 내용 
    }
}

2016년 12월 14일 수요일

[JNI] Java JNI 연동 방법

Java에서 C쪽 레거시 연동을 위해서 JNI를 사용할 때가 있습니다.
이때 연동하는 절차에 대해서 간단하게 정리해 봤습니다.

1. java 에서 호출 하기

public class Hello {
    native void helloFromC(int iValue, String sValue);
    static {
        System.loadLibrary("chello");
    }
    static public void main(String argv[]) {

        int i = 1;
        String s = "testval";
        Hello helloWorld = new Hello();
        helloWorld.helloFromC(i, s);
    }
}

native 로 C쪽에서 사용할 메소드를 선언합니다.
그리고  System.loadLibrary  로 C 소스를 로딩합니다.
마지막으로  호출해서 사용합니다.

2. java 소스 컴파일 및 C에서 사용할 소스의 헤더 생성하기

일단 javac 로 자바 파일을 컴파일 한 후에 javah 로 c에서 사용할 헤더파일을 생성합니다.

$ javac Hello.java
$ javah Hello

3. c 코드 작성하기 

#include "Hello.h"

JNIEXPORT void JNICALL Java_Hello_helloFromC
  (JNIEnv * env, jobject jobj, jint ival, jstring sval)
{
 const char *name = (*env)->GetStringUTFChars(env, sval, NULL);
     printf("Hello from C!\n");
     printf("%d ____ %s \n",ival,name);
     
     printf("Hello from C exit\n");     
}

4. c 코드 컴파일 하기

$ gcc -o libchello.so -shared chello.c -lc -fPIC

* 참조하는 라이브러리가 있는경우 아래와 같이 참조를 해서 컴파일 한다.
$ gcc -o libchello.so -shared -I/home/temp/Stat_Test -I/home/FRAMEWORK/include chello.c -lc -fPIC -L/home/FRAMEWORK/lib/ -lstctl


5. 실행한다. 

$ java Hello

실행시 다음과 같은 에러가 나는 경우가 있습니다.
이런 경우는 64bit 로 컴파일하고 32bit JDK 버젼에서 실행한 경우이다. 

$ /usr/local/j2sdk1.4.2_19/bin/java Hello
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/temp/TT/libchello.so: /home/temp/TT/libchello.so: wrong ELF class: ELFCLASS64 at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511) at java.lang.Runtime.loadLibrary0(Runtime.java:788) at java.lang.System.loadLibrary(System.java:834) at Hello.(Hello.java:4)

* 주의 사항 : 테스트는 패스를 숨기기위해서 일부 경로 정보를 조작한게 있습니다.
(무조건 복붙해서 돌리면 에러가 날 수도 있다는 뜻입니다.)
* 주의 사항 : 테스트는 같은 폴더에 있어서 패스 설정하는 부분이 빠져 있습니다.
* 주의 사항 : 실제 Web 서버에서 사용할때는 라이브러리가 LD_LIBRARY 패스에 들어가 있어야 합니다.

2016년 8월 2일 화요일

[Java] Java Web application Login 설계

Java web 어플리케이션에 로그인 설계 with spring framework

1. 기능 정의

- 로그인
    - 사용자에게 아이디 패스워드를 받아서 로그인 한다.
    - 로그인 이후 사용자를 메인 페이지로 이동시킨다.
- 로그아웃
    - 사용자를 로그아웃 처리한다.
- 로그인 확인
    - 로그인이 안되어 있는경우 로그인 페이지로 이동한다.
    - 로그인이 되어 있는경우 접속을 허가 한다.
- 중복 로그인 방지
    - 동일한 아이디로 로그인이 되어 있는 경우 기존 사용자의 접속을 종료 하고 로그인 한다.
- 로그인/로그아웃 이력 저장
    - 로그인 이력 기록
    - 로그아웃 이력 기록
    - 동일 아이디 접속에 의한 로그아웃 이력 기록
    - 세션 타임아웃에 의한 로그아웃 이력 기록 (옵션)
    - 관리자에 의한 로그아웃 이력을 기록(옵션)
- 관리자 로그인/로그아웃 관리 기능 (옵션)
    - 현재 로그인된 사용자 목록을 조회 한다.
    - 로그인된 사용자를 로그아웃 시킨다.

2. 주요 기술 및 기능 구성

- Spring framework 기반으로 개발 한다.
- 브라우져와 서버와의 연동은 rest 방식을 사용한다.
- 로그인 확인 체크는 interceptor를 통해서 처리한다.
- 로그인한 사용자의 관리는 Manager 관리 객체를 만들고 Thread safe 하게 ConcurrentHashmap을  이용하여 처리 한다.
- 세션이 끝나는경우 로그아웃 처리를 위해서는 HttpSessionListener 를 구현해서 처리 한다.
- 자발적인 로그아웃이 아닌경우 로그아웃된 이유는 해당 세션에 넣어 준다.

3. 로그인/로그아웃 Case

- 로그인
    - 사용자의 아이디/패스워드를 입력 후 로그인
- 로그 아웃
    - 로그 아웃 기능을 통해 정상 로그아웃
    - 로그인 된 상태에서 다른곳에서 동일한 아이디로 로그인
    - 관리자 관리 기능으로 강제 로그 아웃
    - 서버 장애/셧다운 (처리 불가)

4. 추가 기능

- 지정된 횟수만큼 로그인 실패시 로그인 잠금 기능(초기화 필요/일정시간동안 잠금)
- 자동입력 방지 기능
- 초기 비밀 번호 변경 기능
- 아이디 찾기
- 비밀번호 찾기

5. 보안 고려 사항

- 아이디는 6자 이상으로 한다.
- 패스워드는 대/소/숫자/특수 에서 3가지 이상의 조합으로 등록 하도록 한다.
- 로그인 실패 시 출력 멘트는 보안 이슈로 인해서 모호하게 출력해야 한다.
    - ex> 아이디/패스워드가 잘못되었습니다.

6. 추가 사항

- 세션 타임 아웃에 의한 로그아웃 시키고 이력을 저장하는 부분은 리스너로 등록된 객체에서 스프링 bean 에 접근해야 하기 때문에 보류(가능은 하나 별의미가 없어서 보류 처리)

2014년 1월 6일 월요일

[Spring] spring + java web application 다국어 지원 설정

다국어를 사용하기 위해서는 코딩시에 여러가지 사항들을 고려 해야 한다.
spring framework 및 설정을 통해서 다국어를 사용하는 방법에 여러가지가 있다.
상황에 따라서 쿠키를 이용하거나 세션 그리고 브라우져의 언어 설정을 이용하는 방법등 다양한 방법이 있지만 세션을 이용하는게 현재 작업하는 내용과 가장 일치 하기 때문에 이 방법에 대해서 정리 하도록 한다.


[목차]

  1. 인코딩 설정 하기
  2. Spring 설정 
  3. Locale을 설정하는 Controller 클래스 작성
  4. 현재 설정된  Locale을 확인 하는 클래스 작성 
  5. 메시지를 언어 설정에 따라서 가져오는 클래스
  6. Javascript용 파일 생성하기
  7. JAVA에서 사용하는 방법
  8. JSP에서 사용 하는 방법 
  9. javascript  설정및 사용하는 방법

[설명]

1. 인코딩 설정하기 

다국어를 사용하기 위해서는 web.xml 에서 인코딩필터를 UTF-8 로 설정해 주어야 한다. 

  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
<filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
  </filter-mapping>


2. Spring 설정하기


Spring 의 application-servlet.xml  파일에 MessageSource 를 설정한다.
아래 설정은 ReloadableResourceBundleMessageSource 을 사용하여 설정을 바꾸면 다시 읽도록 처리 하였다.

<!-- 
    MessageSource 를 선언하고 설정한다. 
    메시지는 classpath 에 선언된곳에 놓는다 .
-->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="basenames">
<list>
           <value>classpath:/com/test/mydomain/message</value>
        </list>
    </property>
    <property name="fallbackToSystemLocale" value="false"/>
    <property name="cacheSeconds" value="60"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
    <property name="defaultLocale" value="ko" />
  </bean>

<!-- java 에서 사용하기 위해 만든 클래스 -->
<bean id="prop" class="com.common.util.Prop" />
  



  •  /com/test/mydomain 이 패키지 위치에  다국어 문장을 포함한 파일을 넣는다.
    message.property - 기본 언어 셋
    message_ko.property - 한국어 언어셋
    message_en.property - 영어 언어셋

  • 파일의 내용은 다음과 같은 형식이다.  ( 영어인 경우 아래 문장들이 영어로 번역되어 들어 가면된다.)

    test.message=안녕하세요.test.hello={0}님 안녕하세요. {1}
    {0}과 {1} 은 치환될 영역이다. 사용자가 해당 문구를 사용시에 치환해서 사용해야 하는 경우 이런식으로 메시지를 작성해서 치환하면 된다.
  • 기본적으로 한국어를 사용하면 굳이 message_ko.property를 만들지 않아도 된다.


3. Locale을 설정하는 Controller 클래스 작성

/**
 * 세션에 있는 로케일을 변환 하는 Controller 클래스
 */


@Controller
public class LocaleController {

    @RequestMapping(value = "/changeLocale")
    public String changeLocale(HttpServletRequest request, HttpServletResponse response, @RequestParam(required = false) String locale) {
        HttpSession session = request.getSession();
        Locale lo = null;
        
        //step. 파라메터에 따라서 로케일 생성, 기본은 KOREAN 
        if (locale.matches("en")) {
                lo = Locale.ENGLISH;
        } else {
                lo = Locale.KOREAN;
        }

        // step. Locale을 새로 설정한다.          session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, lo);
        // step. 해당 컨트롤러에게 요청을 보낸 주소로 돌아간다.
        String redirectURL = "redirect:" + request.getHeader("referer");
        return redirectURL;
    }


}


4. 현재 설정된  Locale을 확인 하는 클래스 작성


public class LocaleUtil {

    /**
    * 기본 로케일을 리턴한다. 기본은 한글이다. 
    */
    public static Locale getDefaultLocale() {
        return Locale.KOREAN;
    }

    /**
    *  HttpServletRequest 를 받아서 저장되어 있를 locale 값을 리턴한다. 없는 경우는 기본 로케일을 리턴한다. 
    */

    public static Locale getLocale(HttpServletRequest request) {
        Locale locale = null;
        HttpSession session = request.getSession(); 
        locale = (Locale)session.getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);

        if (locale == null ) {
            locale = getDefaultLocale();
        }
        return locale;
    }


}

5. 메시지를 언어 설정에 따라서 가져오는 클래스

public class Prop implements MessageSourceAware {
    
    private static MessageSource msg;

    public void setMessageSource (MessageSource msg) {
        Prop.msg = msg;
    }
    
    /**
     * 시스템 속성을 얻기위한 함수
     * 호출 내용은 기존 메시지와 동일하나 기능적으로 구분하기 위해서 추가한 메소드 이다. 
     */
    public static String prop(String key) {
    return Prop.msg(key);
    }
    
    public static String prop(String key, Locale locale) {
    return Prop.msg(key, locale);
    }
    
    public static String propFormat(String key, Object...objects) {
         return MessageFormat.format(Prop.msg(key),objects);
    }
    
    public static String propFormat(String key, Locale locale, Object...objects) {
        return MessageFormat.format(Prop.msg(key, locale),objects);
    }
    
   /**
    * 메지시를 리턴한다.
    */
    public static String msg(String key){
        return msg.getMessage(key, null, Locale.getDefault());
    }
    
    public static String msg(String key, Locale locale){
        return msg.getMessage(key, null, locale);
    }
}


6. javascript용 파일 생성하기
message.i18n.js  는 사용하기 편리 하도록 만든 파일이다. 파일 내용은 아래와 같다.

function loadBundles(lang) {
        jQuery.i18n.properties({
            name:'message', 
            path:'/js/message/prop/', 
            mode:'both',
            language:lang, 
            callback: function() {
        }
    });
}

i18nProp = jQuery.i18n.prop;


7. JAVA에서 사용하는 방법

자바에서 controller 에서 HttpRequest 객체를 넣어서 현재 locale 를 얻어 온 다음에 Prop 클래스를 통해서 메시지를 가져 온다.


Locale locale = LocaleUtil.getLocale(request);


String message= Prop.propFormat("message.java", locale,  "[Message]","java");


8. JSP에서 사용 하는 방법
spring tag 를 통해서 값을 가져온다.



<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<spring:message code="message.jsp" arguments=" 메시지, JSP"/>


9. javascript  설정및 사용하는 방법
javascrpit 는 설정 파일을 별도로 만들었다. 이 경우 javascript에서 파일(message.i18n.js)을 지정해서 하나만 사용하는 편이 편하다.



<script type="text/javascript" language="JavaScript"  src="/js/lib/jquery.i18n.properties-min-1.0.9.js"></script>
<script type="text/javascript" language="JavaScript"  src="/js/message/message.i18n.js"></script>

<script type="text/javascript">
<!--
jQuery(document).ready(function() {
loadBundles('<%=(LocaleUtil.getLocale(request)).toString()%>');
});
//-->


</script>








2010년 8월 27일 금요일

[java] ServletContext - 어플리케이션 내부의 변수 공유 방법

- 한 어플리케이션 내부의 모두 같은 정보를 공유하기 위한 클래스


[설정 방법]

위치 : web.xml

예제 :
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

.....

<context-param>
<param-name>AdminEmail</param-name>
<param-value>admin@gmail.com</param-value>
</context-param>

......

</web-app>


[사용방법]

String adminEmail = getServletContext().getInitParameter("AdminEmail");

{OR}

ServletContext context = getServletcontext();
String adminemail = context.getInitParameter("AdminEmail");

[java]ServletConfig 서블릿 클래스간의 변수 공유 방법

- 하나의 서블릿 클래스에서 같은 설정 정보를 공유하기 위한 클래스


[설정 방법]
위치 : web.xml

예제 :
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">

.....
<servlet>
    <servlet-name>Tester</servlet-name>
    <servlet-class>com.example.Tester</servlet-class>
    <init-param>
        <param-name>AdminEmail</param-name>
        <param-value>admin@gmail.com</param-value>
    </init-param>
</servlet>

<servlet-mapping>
    <servlet-name>Tester</servlet-name>
    <url-pattern>/Tester.do</url-pattern>
</servlet-mapping>

......

</web-app>



[사용방법]

String adminEmail = getServletConfig().getInitParameter("AdminEmail");

{OR}

ServletContext context = getServletConfig();
String adminemail = context.getInitParameter("AdminEmail");

2010년 8월 26일 목요일

java.net.Inet4AddressImpl.getLocalHostName(Native Method) 에러 테스트

Java 어플리케이션(WebLogic등) 을 실행시 기동 하는데 시간이 오래 걸리는 경우가 있다. 이때 thread dump 를 발생 시켰을때 
    java.net.Inet4AddressImpl.getLocalHostName(Native Method)
부분에서 hang 이 걸리는 경우 가 있는데 이 부분을 테스트 하기 위한 간단한 java 프로그램이다.

이런경우 host 파일의 설정이나 어떤 이유에서든 host명을 제대로 인식하지 않아서 발생하는 경우 이다.


[실행방법]$>uname -a
$>javac test/TestHostName.java
$>java -Djava.net.preferIPv4Stack=true TestHostName


[java source]
import java.net.InetAddress;

public class TestHostName {

    public static void main(String[] args) {
        try {
            long start = System.currentTimeMillis();
            InetAddress addr = InetAddress.getLocalHost();
            long stop = System.currentTimeMillis();
            System.out.println("Found: " + addr.getHostAddress() + " in: " + (stop - start) + " ms.");
        } catch (Exception e) {

        e.printStackTrace();

    }
}

}

java classloader 동작 방식

[ClassLoader 의  loading 되는 순서]

 
  1. bootstrap classloader ( JVM 실행시 실행되어 Object class 를 로딩함)
  2. system classloader
  3. common classloader
  4. application classloader (어플리케이션 단위로 클래스 로더가 생성됨 -> 따라서 어플리케이션사이에 클래스 공유를 안함)
  5. jspfile classloader (JSP 파일마다 하나씩 생성)

[ClassLoader 의 호출관계]

Class가 필요한 경우 자신이 속한 ClassLoader 에게 Class를 호출하게 된다.
그런 경우 ClassLoader는 자신의 부모(상위) ClassLoader에게 해당 클래스를 가지고 있는지 확인 한다.
만약 부모 ClassLoader에도 해당 클래스가 없다면 system ClassLoader 까지 호출이 올라 가게된다.
System ClassLoader 에게도 해당 클래스가 없는경우 자신의 범위에 있는 Class Path 에서 해당 Class가 있는지 확인하고 있으면 Loading 하고 클래스를 리턴한다.
만약 자신의 범위의 해당 Class가 없으면 ClassNotFoundException을 발생시킨다.
부모에게서 ClassNotFoundException 을 받은경우 자신의 범위의 Class Path 에서 해당 클래스가 있는지 확인을 하게 된다.
이런 방식으로 처음 요청한 ClassLoader 까지 돌아 오게 된다.


[WebLogic의 Class 찾는 순서]
  1. Domain 폴더의 lib 폴더 (  CLASSPATH 환경변수)
  2. WEB-INF/classes
  3. WEB-INF/lib

2010년 8월 23일 월요일

[Java]Java EE Application type

[JAR (Java ARchive)]
    Java Lib , EJB : 클래스와 패키지를 묶는다.

    폴더 구조

    /                                                  (*.class, 패키지 폴더)
    /META-INF                               
        - ejb-jar.xml                         ( EJB 의 경우 포함)        - weblogic-ejb-jar.xml        (WebLogic의 경우)




[WAR (Web ARchive)]
    Web Application

    폴더 구조

    /                                                   (*.jsp, 등 웹 파일)
    /WEB-INF
        - web.xml
        - weblogic.xml
    /classes                                       (*.class)
    /lib (*.jar)
    /tld                                               (* 옵션, 태그라이브러리 관련)


[EAR (Enterprise ARchive)]
    Enterprise Application , EJB jar + WAR 구조

    폴더구조
   
    /
    /META-INF
        - application.xml
    /JAR, WAR 가 이곳에 들어 간다. (폴더 형태로 들어가도 상관없다.)


[RAR (Resource ARchive)]

[Java Link] Java 관련

[IBM JVM]


    IBM java diagnostics
        - http://publib.boulder.ibm.com/infocenter/javasdk/v5r0/index.jsp?topic=/com.ibm.java.doc.diagnostics.50/diag/welcome.html

http://www.ibm.com/developerworks/aix/library/au-JavaPart1.html

http://www.ibm.com/developerworks/aix/library/au-JavaPart2.html


    Getting more memory in AIX for your Java applications
        - http://www.ibm.com/developerworks/systems/articles/aix4java1.html

http://javagosu.tistory.com/5






[SUN JVM]
    option list
        - http://blogs.sun.com/watt/resource/jvm-options-list.html