반응형
반응형
반응형

일반적으로 Action 클래스에서는 다음과 같은 로직을 통해 중복 Form Submit 여부를 체크할 수 있다.

  • Action Class

    boolean valid = isTokenValid(request, true);
    if (valid) {
        // TODO: submit 할 때 수행할 로직을 넣을 것
        System.out.println("status: performed");
    } else {
        // TODO: init / reload 할 때 수행할 로직을 넣을 것
        System.out.println("status: initialized or reloaded");
    }
    saveToken(request);

  • JSP

    <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" 
    value="<%= session.getAttribute(org.apache.struts.Globals.TRANSACTION_TOKEN_KEY) %>">

    UI(JSP, HTML)에서는 "org.apache.struts.taglib.html.TOKEN"을 Key로 하는 Hidden Field를 통해 할당된 Token 값을 서버로 전송하고, 해당 Action 클래스에서는 isTokenValid 메소드 호출을 통해 이 Token 값과 Session에 저장된 Token 값을 비교함으로써, Token의 유효성을 검사한다.

위에 소스에 대해 개괄적으로 설명하면 Action 을 처리하면서 saveToken(request); 부분에서
세션에 토큰키를 생성하여 저장하게 된다.(현재시간과 세션아이디를 가지고 MD5 알고리즘을 이용해 생성)

JSP페이지에서 이를 히든타입으로 form에 담게 되고 submit을 통해 Action으로 가면
현재 세션에 저장되어 있는 토큰키와 form에 담겨 request로 넘어온 토큰키와 비교를 하게 된다.
그 키값이 같으면 정상처리를 하게 되고 saveToken(request); 부분을 통해 신규 토큰키가 생성되고
세션에 다시 담기게 된다. 이후에 새로고침이나 뒤로가기를 통해 다시 넘어오는 토큰키는 이전에 처리된
토큰키를 그대로 담고 있기 때문에 새로 생성된 신규 토큰키와 다르므로 중복처리를 제어할수 있는것이다.

토큰에 관한 부분은 아래 링크에 상세히 설명되어 있고 jsp에 name은 명확히 동일하게 작성되어야 한다.
 
아래 링크에서 "56.3.1. Double Submit의 개념" 부분을 참고하도록 하자.
http://dev.anyframejava.org/docs/anyframe/4.6.0/reference/html/ch56.html
반응형

GET으로 보낼때 한글깨짐
server.xml에 URIEncoding="EUC-KR" 이나 URIEncoding="UTF-8" 추가

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="EUC-KR"/>

POST로 보낼때 한글깨짐
모든 jsp와 servlet에서 request.getParameter를 호출하기전에 characterEncoding을 지정해줌
request.setCharacterEncoding("EUC-KR");

이게 싫다면...
web.xml에 필터를 추가해준다
톰캣 6.0인경우 예제 경로는 apache-tomcat-6.0.18\webapps\examples

1. web.xml에 다음을 추가해준다
<filter>
        <filter-name>Set Character Encoding</filter-name>
        <filter-class>filters.SetCharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>EUC-KR</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Set Character Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2. 필터클래스를 만들어줌
예제경로는 apache-tomcat-6.0.18\webapps\examples\WEB-INF\classes\filters\SetCharacterEncodingFilter.java

프로젝트홈\WEB-INF\classes\filters\SetCharacterEncodingFilter.java
에 복사해서 넣어놓자.
반응형

내장객체

1. out : 페이지 내용을 담고 있는 출력 스트림 객체

2. request : 파라미터를 포함한 요청정보를 담고 있는 객체

3. response : 요청에 대한 응답을 담고있는 객체

4. session : 세션 정보를 담고 있는 객체

5. application : 어플리케이션 Context의 모든 페이지가 공유할 데이터를 담고 있는 객체

6. pageContext : 페이지 실행에 필요한 Context정보를 담고있는 객체

7. page : JSP페이지의 서블릿 객체

8. config : JSP페이지의 서블릿 설정 데이터 초기화 정보객체

9. exception : JSP페이지의 서블릿 실행시 처리하지 못한(에러발생) 예외 객체

 

★★★ request, session, application, pageContext 내부객체는 임의의 속성값(attribute)을 저장하고 읽을 수 있는 메서드를 제공한다.

 

setAttribute(String key, Object value) : 주어진 key에 속성값을 연결한다.
getAttribute(String key) : 주어진 key에 대한 속성값을 얻는다.
removeAttribute(String key) : 주어진 key에 연결된 속성값을 제거한다.
getAttributeNames() : 모든 속성의 이름을 얻어낸다.

. JSP페이지에 관련된 객체 : page, config
. 페이지 입출력 관련된 객체 : request, response, out
. 컨텍스트에 관련된 객체 : session, application, pageContext
. 에러에 관련된 객체 : exception

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ out 내장 객체 Method
1. isAutoFlush() : 출력 버퍼가 가득찼을 때 자동으로 밀어낼 것인지 여부 지정 (true/fasle)
2. getBufferSize() : 출력 버퍼 전체 size를 구함
3. getRemaining() : 출력 버퍼중 남아있는 size를 구함
4. clearBuffer() : 출력 버퍼를 비운다.
5. println() : String을 출력한다.
6. flush() : 출력 버퍼 내용을 밀어낸다.
7. close() : 출력 버퍼 내용을 밀어 내고, 출력 버퍼를 닫는다.

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ request 내장 객체 메서드
1. getMethod() : 요청 방식 알아내기 (get, post)
2. getRequestRUI() : 요청 파일 경로 알아내기 (예: jsp2/RequestTest.jsp)
3. getRequsetURL() : 요청 경로 알아내기 (예: http://localhost:9000/jsp2/Request.jsp)

4. getRemoteHost() : 클라이언트 호스트 이름 알아내기
5. getRemoteAddr() : 클라이언트 주소 알아내기
6. getRemoteUser() : (인증을 이용한 경우) 이용자 ID 알아내기

7. getProtocol() : 사용중인 프로토콜 알아내기(HTTP1.1)
8. getServerName() : 서버 도메인 이름 알아 내기
9. getServerPort() : 서버 Port 알아내기

10. getHeader(name) : name에 해당하는 요청 헤더 항목 값을 알아내기

11. getParameter(name) : name에 해당하는 파라미터값 얻는다.
12. getParameterValues(name) : name에 해당하는 파라미터값을 모두 얻는다.
13. getParameterNames() : form에 있는 모든 파라미터 이름을 얻는다.

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ response 내장 객체 메서드
1. setContentType(type) : 출력 문서의 contentType 설정
2. getCharacterEncoding() : 문자 인코딩 설정 내용 알아내기
3. setHeader(name, value) : 응당 헤더 설정
   예: response.setHeader("Refresh", "3;URL=http://www.daum.net");//3초후 URL로 이동
4. sendRedirect("url") : 지정 url로 요청을 재전송한다.
   예: response.sendRedirect("로컬URL");
       response.sendRedirect("외부URL");

 

※ response.sendRedirect와 forward 액션태그 차이점
  - sendRedirect()는 웨브라우저가 다른 페이지로 이동하는덷 이때 다른 페이지로 가기의해 웹 브라우저는 웹서버에 새로운 Http요청을 보낸다. 즉, TCP네트워크 연결이 다시 만들어 지는 것이다.

 - 이제 비해 forward액션은 JSP엔진에서 Http요청을 다른 페이지로 보내는 것이다. 즉, Http요청 처음 만들어진 것 하나만 있는 것이다. 이것은 중요한 의미를 갖는다.
    cf) <jsp:forward page="로컬URL"/>
         <jsp:forward page="외부URL"/> --안됨!! 

 - sendRedirect()는 사용하면 웹브라우저에서 처음에 전송한 Http요청과 이 요청에 포함된 데이터들은 새로 이동된 페이지에서 사용할 수 없게 된다. 반면에 forward액션을 사용하면 Http요청은 하나만 사용하기 때문에 새로 이동된 페이지에서도 클라이언트에서 전송된 데이터를 사용할 수 있다.

 

※ forward액션 태그
   방법1 <jsp:forward page="로컬URL"/> = <jsp:forward page="로컬URL"></jsp:forward>
   방법2 <jsp:forward page="로컬URL">
               <jsp:param name="id" value="kim"/>
               <jsp:param name="pwd" value="123"/>
            </jsp:forward>


※ include지시자(디텍티브)

   <%@ include file ="파일명.확장자" %>
                              name.txt
                              aa.html
                              bb.jsp <- 현재 JSP페이지에 포함할 문서
        *include지시자는 단순히 문서를 포함시킨다. 포함시킬 문서는 헤더부분 넣지 말아야한다.

※ include액션
   *include앤셕 실행될 결과물을 현재페이지에 포함시킨다.
   <방법1>
      <jsp:include page="로컬URL" flush="true"/>
   <방법2>
      <jsp:include page="로컬URL" flush="true"/>
          <jsp:param name=" " value=" "/>
          <jsp:param name=" " value=" "/>
          .....

      </jsp:include>

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ application 내장 객체 메서드
 application 내장 객체는 서블릿 또는 어플리케이션 외부환경정보(context)의 내부객체입니다.
 application은 javax.servlet.ServletContext의 객체이다.

<Method>
1. String getServletInfo() : 서버 정보를 구한다.(웹 컨테이너이름과 버전, 즉 JSP컨테이너에 대한 정보)
2. String getMimeType(fileName) : fileName대한 MIME타입을 리턴한다.
  예) String str = request.getParameter("filename");
      String contentType = application.getMimeType(str);
3. String getMajorVersion() : 서버가 지원하는 서블릿규약의 Major version을 리턴한다.(정수부분)
4. String getMinorVersion() : 서버가 지원하는 서블릿규약의 Minor version을 리턴한다.(소수부분)

5. String getRealPath(url) : 지정 URL의 실제 경로를 리턴한다.
6. void log("message") : message내용을 file에 기록한다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
--myroot\WEB-INF\web.xml--
<context-param>
 <description>로깅여부</description>
 <param-name>logEnabled</param-name> <!-- 이름이 logEnabled이고 값이 true인 초기화 파라미터 추가 -->
 <param-value>true</param-value>
</context-param>
 
<context-param>
 <description>로깅레벨</description>
 <param-name>debugLevel</param-name> <!-- 이름이 debugLevel이고 값이 5인 초기화 파라미터 추가-->
 <param-value>5</param-value>
</context-param>

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ Cookie 내장 객체 생성자 &메서드
생성자
- Cookie(name, value) 이름이 name이고, 값이 value인 쿠키를 생성

메서드
 setter method or setXXX()
- setValue() : 쿠키값 설정
  setDomain() : 쿠키에 전달되는 도메인 설정
  setPath() : 쿠키에 전달되는 경로 설정
  setMaxAge() : 쿠키 나이 설정(쿠키 유효기간 설정<-초>)
  setSecure() : 보안 프로토콜(HTTPS)에서만 쿠키를 전달되도록 설정한다.
  
 getter method or getXXX()
- getName() : 쿠키이름 얻기
  getValue() : 쿠키값 얻기
  getDomain() : 쿠키가 전달되는 도메인 알아내기
  getPath() : 쿠키가 전달되는 경로 알아내기
  getMaxAge() : 쿠기 유효기간 알아내기
  getSecure() : 보안 프로토콜(HTTPS)에서만 쿠키가 전달되는지 알아내기

 <<쿠키를 생성해서 클라이언트 심는 방법>>
  Cookie cookie = new Cookie("쿠키이름", URLEncoder.encode("쿠키값"));
  response.addCookie(cookie); //쿠키심기
 
 <<클라이언트가 보내주는 쿠기를 모두 받아서 특정 이름의 쿠키값을 알아내기>>

 Cookie[] cookies = request.getCookies(0;
 if(cookies!=null){
         for(int i=0; i<cookies.length; i++){
                 if(cookies[i].getName().equals("쿠키이름")){
                         visiterName = URLDecoder.decode(cookies.getValue());
                         out.println("쿠키값 : " + visiterName);
                 }
         }
 }

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
★ session 내장 객체 메서드

- 세션은 쇼핑몰같은 구매 제품을 클릭할때마다 누가 클릭했는지 기억을 해야하는 사이트에서는
웹서버쪽에 사용자별 기록을 남겨야만 합니다.

 웹 서버쪽에 기억 시키는 것을 세션이라고 합니다.
 JSP에서는 session객체를 통하여 이용할 수 있습니다.

<< session객체 method >>
1. String getId() : 해당 세션의 고유한 세션의 ID를 리턴
2. void setMaxInactiveInterval(time) : 세션 유지 시간 설정(초단위)
3. int getMaxInacativeInterval() : 세션 유지 시간을 얻는다(기본 유지시간 30분)

4. isNew() : 새로 생성된 세션이면 true return
5. invalidate() : session를 제거

setAttribute(name, value) : session에 name, value값의 항목을 추가
getAttribute(name) : session에서 name에 해당하는 value값을 얻는다.

* HttpSession getSession() :
  1. getSession(true) : true는 새로운 세션을 create만 하는 것
  2. getSession(false) : false는 현재 세션을 그대로 리턴 하는 것
  3. getSession() : session존재 여부를 확인하여,
                    session이 없다면 새로 session을 create하고
                    session이 있다면 그대로 return
                    위 2개의 장점을 취한 것.

 

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
※JSP 액션
<jsp:useBeans> - JSP페이지에서 빈을 초기화 하는데 사용
<jsp:setProperty> - 빈의 property에 값을 넣어 주기 위해 사용
<jsp:getProperty> - 빈의 property의 앖을 가져오기 위해서 사용
<jsp:forward> - 처리를 분기할 때 사용
<jsp:include> - 처리 결과무를 포함 시킬 때 사용

지시자
<%@ page %>
<%@ include file="파일명" %>
<%@ taglib %>

[출처] JSP내장객체|작성자 신지c


반응형

Tomcat 5.0 JNDI Datasoruce 설정


JNDI Datasoruce 설정 개요

  • Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용
  • JNDI를 통한 커넥션 풀 사용은 J2EE 표준이고, 현존하는 거의 모든 웹 컨테이너가 지원
  • Jakarta의 DBCP 커넥션 풀과 Tomcat JNDI 설정을 통해 데이터베이스 커넥션 풀을 사용하는 방법 제시
  • 기본적으로 필요한 라이브러리
    • commons-dbcp.jar
    • commons-collections.jar
    • commons-pool.jar
    • DB에 대한 JDBC 라이브러리 (JAR)

JNDI Naming Resource 설정

  1. 위 라이브러리들을 $CATALINA_HOME/common/lib 에 복사한다. 그 이외 디렉토리에 두면 안된다.
  2. Connection 풀을 이용할 경우에는 ResultSet과 Connection 객체를 필히 직접 닫아 줘야만 한다.
  3. $CATALINA_HOME/conf/server.xml 혹은 각 웹 컨텍스트별 XML 파일의 <Context>의 자식 요소로 <Resource>를 추가한다.
  4. 웹 어플리케이션의 web.xml파일에 <resource-ref>를 추가하여 JNDI 리소스를 사용할 수 있도록 한다.
  5. 전역적인 JNDI 리소스를 이용하고자 하는 경우는 <GlobalNamingResources>

Server.xml

server.xml
<Resource name="jdbc/forumDb" auth="Container" type="javax.sql.DataSource"/>
<!-- Resource의 name 속성을 이용해서 각 어플리케이션에서 javax.sql.DataSource 객체를 얻어가게 된다. -->

<!-- 자세한 파라미터 설정은 위의 참조사이트에서 확인 -->
<ResourceParams name="jdbc/forumDb">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>

<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>

<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>

<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>

<!-- DB 사용자명과 비밀번호 설정 -->
<parameter>
<name>username</name>
<value>dbuser</value>
</parameter>
<parameter>
<name>password</name>
<value>dbpasswd</value>
</parameter>

<!-- JDBC 드라이버 클래스 -->
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>

<!-- JDBC 접속 URL -->
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@dbhost:1521:ORA</value>
</parameter>
</ResourceParams>
전역 JNDI 리소스 이용
  • <Resource>와 <ResourceParams> 요소를 server.xml의 <GlobalNamingResources> 의 자식노드로 옮기면 특정 웹 어플리케이션이 아니라, 이 톰캣에 설치된 전체 웹 어플리케이션에서 사용 할 수 있게 된다. 하지만 각 웹 어플리케이션 "<Context>"에 다음과 같은 설정을 해야 한다.
server.xml의 <Context> 부분에 추가
<ResourceLink
name="jdbc/forumDb"
global="jdbc/forumDb"
type="javax.sql.DataSource"
/>
  • 아니면 server.xml에서 <Host> 요소의 자식으로 다음을 추가하면 각 컨텍스트별 설정 필요없이 전체 웹 어플리케이션 컨텍스트에서 GlobalNamingResources로 지정된 JNDI 리소스를 사용할 수 있다.
server.xml의 <Context> 부분에 추가
<DefaultContext>
<ResourceLink
name="jdbc/forumDb"
global="jdbc/forumDb"
type="javax.sql.DataSource"
/>
</DefaultContext>

web.xml

web.xml에 리소스에 대한 reference를 설정
<resource-ref>
<description>Forum DB Connection</description>
<!-- 다음이 바로 리소스의 이름 -->
<res-ref-name>jdbc/forumDb</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

Tomcat 5.5 JNDI Datasoruce 설정


DBCP(Database Connection Pool) 설정

  • 라이브러리 설치
    • Jakarta-Commons DBCP
    • Jakarta-Commons Collections
    • Jakarta-Commons Pool
  • DBCP 는 Jakarta-Commons Database Connection Pool을 사용하는데, 위에 있는 세개의 라이브러리는 $CATALINA_HOME/common/lib/naming-factory-dbcp.jar의 한개의 JAR에 포함되어 있다.
  • 이 하나의 라이브러리가 존재하는지 확인한다.

DB connection pool 누수 방지하기

  • DBCP Datasource 설정에 다음 Resource 속성을 설정한다.
  • 디폴트는 false이다.
removeAbandoned="true"
  • 취소된 Connection에 대한 timeout 시간을 설정한다.
  • 디폴트 timeout 시간읜 300초이다.
removeAbandonedTimeout="60"
  • Connection 리소스를 취소하는 코드의 Stack Trace를 로깅하도록 설정한다.
  • 디폴트는 false이다.
logAbandoned="true"

MySQL DBCP 예제

  • MySQL JDBC 드라이버 설치 
    • MySQL 3.23.47, MySQL 3.23.47 using InnoDB,, MySQL 3.23.58, MySQL 4.0.1alpha
    • Connector/J 3.0.11-stable (the official JDBC Driver)
    • mm.mysql 2.0.14 (an old 3rd party JDBC Driver)
    • 이 중에 하나의 드라이버를 결정하여 $CATALINA_HOME/common/lib에 복사한다.
  • Context 설정 (context.xml)
context.xml
<Context path="/DBTest" docBase="DBTest"
        debug="5" reloadable="true" crossContext="true">

    <!-- maxActive: Maximum number of dB connections in pool. Make sure you
         configure your mysqld max_connections large enough to handle
         all of your db connections. Set to -1 for no limit.
         -->

    <!-- maxIdle: Maximum number of idle dB connections to retain in pool.
         Set to -1 for no limit.  See also the DBCP documentation on this
         and the minEvictableIdleTimeMillis configuration parameter.
         -->

    <!-- maxWait: Maximum time to wait for a dB connection to become available
         in ms, in this example 10 seconds. An Exception is thrown if
         this timeout is exceeded.  Set to -1 to wait indefinitely.
         -->

    <!-- username and password: MySQL dB username and password for dB connections  -->

    <!-- driverClassName: Class name for the old mm.mysql JDBC driver is
         org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
         Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
         -->

    <!-- url: The JDBC connection url for connecting to your MySQL dB.
         The autoReconnect=true argument to the url makes sure that the
         mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
         connection.  mysqld by default closes idle connections after 8 hours.
         -->

  <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
               maxActive="100" maxIdle="30" maxWait="10000"
               username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/javatest?autoReconnect=true"/>

</Context>
  • web.xml 설정
    • WebRoot의 WEB-INF/web.xml 파일에 다음 <resource-ref> 부분을 추가한다.
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
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <description>MySQL Test App</description>
  <resource-ref>
      <description>DB Connection</description>
      <res-ref-name>jdbc/TestDB</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

Oracle 8i, 9i & 10g 예제

  •  Oracle의 경우에는 MySQL 예제에서 최소한의 수정을 통해 설정할 수 있다.
  • 오라클9i까지는 oracle.jdbc.driver.OracleDriver 드라이버를 지원하지만 이후에는 oracle.jdbc.OracleDriver 드라이버를 활용해야 한다.
  • 오라클 드라이버를 포함하는 JAR 파일을 $CATALINA_HOME/common/lib에 설치한다.
  • context.xml 설정
<Resource name="jdbc/myoracle" auth="Container"
              type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
              url="jdbc:oracle:thin:@127.0.0.1:1521:mysid"
              username="scott" password="tiger" maxActive="20" maxIdle="10"
              maxWait="-1"/>
  • web.xml 설정
<resource-ref>
 <description>Oracle Datasource example</description>
 <res-ref-name>jdbc/myoracle</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
 <res-auth>Container</res-auth>
</resource-ref>
  • 자바 활용 코드 예제
Context initContext = new InitialContext();
Context envContext  = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
//etc.

Tomcat 6.0 JNDI Datasoruce 설정


Tomcat 5.5와 동일한 설정

  • 톰캣 5.5의 설정방법과 동일하게 6.0에서도 설정한다.

참고자료


 
반응형
Jar 파일로 응용프로그램을 배포하다 보면 이미지 화일이나 프로퍼티 화일, 자료화일등을

함께 묶어서 배포할 경우가 있다. 해당 자원에 접근하기 위해서는 이전에도 포스팅한바가 있는

java.lang.ClassLoader을 이용해 해당 자원에 접근 할수 있다.

간단한 예를 보자.
ClassLoader loader = this.getClass().getClassLoader();
Icon tIcon = new ImageIcon(loader.getResource("res/tImag.git"));

그 외에도 ClassLoader.getResourceAsStream(String name) 메소드를 이용하여
InputStream을 통한 방법도 있다.

자바웹스타트 환경에서는 Java 2 SE API에서 제공하지 않는 추가적인 기능을 하는 API를
제공한다. 이것은 JNLP API라고 한다. JNLP API를 이용하여 개발할 경우는 jnlp.jar가
필요한데 이러한 파일은 JNLP Developer's Pack에 포함 되어 있다. 다음은 Developer's Pack을
다운로드 할 수 있는 URL이다.

http://java.sun.com/products/javawebstart/download-jnlp.html

  JNLP API가 추가적으로 제공하는 클레스는 javax.jnlp package로 묶여 있으며
BasicService, ClipboardService, DownloadService, FileOpenService, FileSaveService, 
PrintService, PersistenceService 등이 있는데 이들은 ServiceManager 클레스를 통하여
사용할 수 있다. 각각의 기능은 다음과 같다.

- javax.jnlp.BasicService

BasicService는 웹스타트의 환경적인 면이나 브라우져를 통제하기 위한 API를 제공하는데
자바 애플릿의 경우 AppletContext와 비슷한 역할을 한다. 다음 예제는 웹스타트 환경에서
웹브라우져로하여금 특정 URL로 가도록 하는 것이다.

import javax.jnlp.*;
.....

BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
bs.showDocument(new URL("http://www.javanuri.com"));



- javax.jnlp.ClipboardService

ClipboardService는 시스템에서 사용하는 클립보드에서 복사 객체를 가져오거나 클립보드로
복사하는 서비스를 제공한다. 자바웹스타트는 이 기능을 사용할 때 보안을 위하여 경고창을
보여준다. 다음은 간단한 스트링을 클립보드에 복사하는 예제이다.

import javax.jnlp.*;
.............

ClipboardService cs = (ClipboardService)ServiceManager.lookup("javax.jnlp.ClipboardService");
StringSelection ss = new StringSelection("Hello Web Start");
cs.setContents(ss);


- javax.jnlp.DownloadService

DownloadService는 자신의 자원을 Cache에 저장, 삭제등 Cache를 통제할 수 있는 서비스 API를
제공하는 클레스이다. 다음은 myapp.jar를 Cache에서 확인하고 있으면 삭제한후 다시 Cache에
저장하는 예제이다.

import javax.jnlp.*;
...........

DownloadServicd ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
URL url = new URL("http://www.javanuri.com/jws/myapp.jar");
boolean isCached = ds.isResourceCached(url, "1.0");
if(isCached) {
  ds.removeResource(url, "1.0");
}

DownloadServiceListener dsl = ds.getDefaultProgressWindow();
ds.loadResource(url, "1.0", dsl);


- javax.jnlp.FileOpenService

FileOpenService는 권한이 제약된 환경에서도 이를 사용자에게 알리고 화일을 열 수 있는
다이얼로그 윈도우를 열어주는 서비스이다.  다음 예제는 FileOpenService를 이용하여 화일을
여는 예제이다.

import javax.jnlp.*;
..............

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);

- javax.jnlp.FileSaveService


FileSaveService는 권한이 제약된 환경에서도 local disk에 화일을 저장할 수 있는
기능을 제공하는 서비스 클레스이다. 이는 FileOpenService의 경우와 반대인 기능을 제공하는
클레스이다.  다음은 FileOpenService를 이용하여 화일을 연 후에 FileSaveService를
이용하여 화일을 저장하는 예제이다.

import javax.jnlp.*;
.....................

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);
FileContents newfc = fss.saveFileDialog(null, null, fc.getInputStream(), "newfile.txt");

- javax.jnlp.PrintService

PrintService는 권한이 제약된 웹스타트 환경에서도 프린트를 가능하게 해주는 API 를 갖고 있는
서비스 클레스이다.  이 API를 이용하여 프린트를 요청하면 사용자에게 허가할 것인가를 묻는
다이얼로그가 나타난다. 다음은 PrintService를 이용한 프린트 요청 예제이다.

import javax.jnlp.*;
.....................

PrintService ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");

// default page format
PageFormat pf = ps.getDefaultPage();

// customizing page format
PageFormat npf = ps.showPageFormatDialog(pf);

// print
ps.print(new Doc());


// printable class
class Doc implements Printable {

 ....
 public int print(Graphics g, PageFormat fm, int idx) {
  ....
 }

}

}


- javax.jnlp.PersistenceService

PersistenceService는 브라우져의 쿠키와 마찬가지고 사용자의 클라이언트에 간단한 자료를 
저장할 때 사용된다. 저장되는 형태는 url형태로 자장된다.
다음은 간단한 url을 저장하고 내용을 읽어들이는 예제이다.


import javax.jnlp.*;
.....................

PersistenceService ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService");

String addr = "www.javanuri.com/some.txt";
java.net.URL = new URL(addr);

// create
ps.create(url, 1024);
FileContents fc = ps.get(url);
OutputStream os = fc.getOutputStream(false);
os.write(...);

// read
fc = ps.get(url);
InputStream in = fc.getInputStream();

in.read(...);

.......


- javax.jnlp.FileContents

FileContents 는 FileOpenService, FileSaveService, PersistenceService와 같은 서비스에서 
input과 output을 처리할 수 있도록 만들어진 클레스이다. 일반적인 File 클레스와 비슷하게
생각하면 된다.  보안과 자료 저장 형태 등이 일반 File 클레스와는 다르다. 
반응형

필자는 이전부터 자바 디컴파일러로 JAD를 사용하고 있었다.

물론 이클립스 플러그인을 이용해서 사용했지만 최근에 JD-GUI 에 대하여 알게 되었다.

JAD도 별 불편함 없이 사용하고 있지만 1.4 이후 버전에 대한 지원 소식도 없고 업그레이드도 없는듯 하다.

우선 JD-GUI  윈도우 버전을 다운로드 하여 실행해보았다.

디컴파일 속도도 빠르고 이클립스용 플러그인도 지원하고 있다.

무설치 버전으로 실행하니 일반 에디터와 같은 GUI를 제공하고 있다.

사용하기도 편리하고 무설치에 GUI까지 제공등.. 그리고 지원하는 java 버전등..

이 어찌 매력적이지 않겠는가? 밑에 JD-GUI 사이트 링크를 걸어 놓는다.

http://java.decompiler.free.fr/



GUI 화면 모습이다. 간단히 jar 파일을 실행해 보았다.. 잘 나온다..ㅎㅎ

그리고 디컴파일된 소스는 파일로 저장까지 할수 있다..  꽤 괜찮은것 같다.

이클립스 플러그인 설치는 해당 사이트에 가면 자세히 설명되어 있다.

Eclipse Platform Version: 3.4.1 에서 jD-Eclipse 플러그인 설치 과정이다.

Installation 

Eclipse 3.4 Instructions

우선 Equinox/p2 plug-in 을 설치 하여야 한다.

  1. 이클립스 메뉴에서 Help -> Software Updates...선택하면 아래와 같은 Software Updates and Add-ons 팝업창이 뜬다.

  2. Available Software 탭을 선택한다.
  3. Ganymede tree node 를 확장시킨다.(왼편의 +를 클릭) 
  4. Uncategorized tree node 를 확장시킨다.(왼편의 +를 클릭) 
  5. Equinox p2 Provisioning tree node 에 체크를하고 ,  Install... button 을 클릭한다.



  6. 마지막으로 Finish button 을 클릭하면 된다. 필자의 경우 tjf

Installation of JD-Eclipse plug-in

  1. 이클립스 메뉴에서 Help -> Software Updates...선택하면 아래와 같은 Software Updates and Add-ons 팝업창이 뜬다.
  2. Available Software 탭을 선택한다.
  3. JD-Eclipse plug-in을 new remote site 로 추가:
    1. Add Site... button 을 클릭하면 Add Site 팝업창이 뜬다..
    2. Location 텍스트 박스에 JD-Eclipse update site URL을 타이핑 한다: http://java.decompiler.free.fr/jd-eclipse/update 그리고 OK button 클릭..



  4. Software Updates and Add-ons 창에 추가된 JD-Eclipse Plug-in 을 체크하고, 오른쪽에 있는 Install... button 을 클릭한다.



  5. 다음 화면에서 , Finish button을 클릭
  6. 다음화면에서, Java Decompiler Eclipse Plug-in certificate box 가 나오면 체크를 하고 OK button 을 클릭하면 완료...  

Introduction

The “Java Decompiler project” aims to develop tools in order to decompile and analyze Java 5 “byte code” and the later versions.

JD-Core is a freeware library that reconstructs Java source code from one or more “.class” files. JD-Core may be used to recover lost source code and explore the source of Java runtime libraries. New features of Java 5, such as annotations, generics or type “enum”, are supported. JD-GUI and JD-Eclipse include JD-Core library.

JD-GUI is a standalone graphical utility that displays Java source codes of “.class” files. You can browse the reconstructed source code with the JD-GUI for instant access to methods and fields.

JD-Eclipse is a plug-in for the Eclipse platform. It allows you to display all the Java sources during your debugging process, even if you do not have them all.

JD-Core, JD-GUI and JD-Eclipse are free for non-commercial use. This means that JD-Core, JD-GUI and JD-Eclipse shall not be included or embedded into commercial software products. Nevertheless, these projects may be freely used for personal needs in a commercial or non-commercial environments.

반응형
우리는 프로그램을 사용하면서 단축키를 많이 사용한다.

필자도 여러가지 프로그램들을 사용하면서 되도록 단축키를 활용함으로 효율성을 높이려고 한다.

자바에서 스윙으로 프로그램을 만들면서 Mnemonic 과 Accelerator 에 대해 알 필요가 있었다.

Mnemonic 과 Accelerator 을 어느 경우에 사용해야 하는지 정리도 할겸 작성해 본다. 

일반적으로 메뉴를 선택할 때는 ALT + 문자 조합을 사용한다.

그리고 메뉴 내에 있는 아이템을 선택할때의 단축키 조합은 어떻게 될것인가?

메뉴를 선택할때는 setMnemonic() 메소드를 이용하여 선택하게 할수 있다.


이렇게 하면 메뉴바의 메뉴를 선택할때 ALT + f  키를 누르면 선택된다.

그리고 메뉴 내에 메뉴 아이템을 선택할때에 2가지 방법이 존재 하게 된다.

메뉴를 선택한 상태에서 문자키를 이용한 선택과 메뉴를 선택하지 않은 상태에서

다른 키조합으로 바로 메뉴 내의 메뉴 아이템을 선택하는 방법이다.

일단 첫번째 메뉴를 선택하고 메뉴내의 아이템을 선택하는 방법은 위에 했던 방식과 별반 다를바 없다.

똑같이 setMnemonic() 메소드를 이용하면 된다.


두번째 방법에서 메뉴를 선택하지 않고 단축키로 메뉴 아이템을 선택하고자 할때는

드디어 언제 나오나 싶었던 Accelerator() 메소드를 사용하면 되는 것이다.
여기서는 CTRL + o 의 조합으로 설정해 놓았다.


이렇게 코딩을 하면 단축키가 잘 먹는다.^^

참고로 키값은 API를 참고 하도록... KeyEvent 클래스를 찾으면 나와있다. 다들 아시겠지만 ^^;
반응형
업무 과정중에 디비에 데이터를 넣는 과정에서 한글 깨짐현상이 발생하였다.

문제는 2가지 정도가 발생하였는데 디비간의 데이터 이동시에 해당 컬럼의 사이즈가 서로 달랐던 것이다.

source db 는  varchar(100)  target db는 varchar(70)  그로인해 한글데이터가 잘리는 경우가 발생하여

깨짐 현상이 발생하였고 데이터를 처리하여 다른 테이블에 INSERT 과정에서 깨진 데이터는

INSERT 가 되지 않았다. 그래서 데이터를 byte단위로 잘라서 target 테이블에 insert 하여야 했다.

해서 입력된 String을 byte 단위로 잘라서 마지막에 깨진 글자가 있을시에 빼고 리턴하는 메소드를 작성.


그리고 2번째 문제가 발생하였는데 잘못된 한글 표기로 인코딩의 문제로 String 중간에 깨진 글자 발생
이 문제는 DB의 인코딩 방식과 JAVA에서 처리된 인코딩 방식의 차이로 발생 하였는데..

해당 소스가 실행되는 환경에서 어떤 인코딩에 따라 한글이 깨지는지 확인 해 보도록 하자.

+ Recent posts