700


HttpSessionBindingListener 프로그래밍 - 자바

HttpSessionBindingListener 는 웹에서 동시 사용자의 수 또는 하나의 아이디로 동시접속을 제한 할때 유용한 인터페이스 이다.  HttpSessionBindingListener 는 두개의 메소드를 지니는데 valueBound() 와 valueUnbound() 메소드 이다.
 
valueBound() 는 HttpSessionBindingListener 클래스의 인스턴스가 세션에 attribute로
등록될떄 호출된다  session.setAttribute(플래그, 값)
valueUnbound()는 session.removeAttribute(플래그); 사용시
또는 세션종료시  session.invalidate()호출된다.
 
다음은 이를 이용한 동시 사용자및 중복 로그인 방지 프로그램이다.
 
 
LoginManager.java
 
package cookie;
 
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionBindingEvent;
import java.util.Hashtable;
import java.util.Enumeration;
 
public class LoginManager implements HttpSessionBindingListener
{
             private static LoginManager loginManager = null;
             private static Hashtable loginUsers = new Hashtable();
             private LoginManager(){
                           super();
             }
             public static synchronized LoginManager getInstance(){
                           if(loginManager == null){
                                        loginManager = new LoginManager();
                           }
                           return loginManager;
             }
 
             //아이디가 맞는지 체크
             public boolean isValid(String userID, String userPW){
                           return true;   //자세한 로직은 미구현
             }
 
             //해당 세션에 이미 로그인 되있는지 체크
             public boolean isLogin(String sessionID){
                           boolean isLogin = false;
                           Enumeration e = loginUsers.keys();
                           String key = "";
                           while(e.hasMoreElements()){
                                        key = (String)e.nextElement();
                                        if(sessionID.equals(key)){
                                                     isLogin = true;
                                        }
                           }
                           return isLogin;
             }
 
             //중복 로그인 막기 위해 아이디 사용중인지 체크
             public boolean isUsing(String userID){
                           boolean isUsing = false;
                           Enumeration e = loginUsers.keys();
                           String key = "";
                           while(e.hasMoreElements()){
                                        key = (String)e.nextElement();
                                        if(userID.equals(loginUsers.get(key))){
                                                     isUsing = true;
                                        }
                           }
                           return isUsing;
             }
 
             //세션 생성
             public void setSession(HttpSession session, String userID){
                           loginUsers.put(session.getId(), userID);
                           session.setAttribute("login", this.getInstance());
             }
 
             //세션 성립될 때
             public void valueBound(HttpSessionBindingEvent event){
             }
 
             //세션 끊길때
             public void valueUnbound(HttpSessionBindingEvent event){
                           loginUsers.remove(event.getSession().getId());
             }
 
             //세션 ID로 로긴된 ID 구분
             public String getUserID(String sessionID){
                           return (String)loginUsers.get(sessionID);
             }
 
             //현재 접속자수
             public int getUserCount(){
                           return loginUsers.size();
             }
};
 
Bind_login.jsp
 
<%@ page contentType="text/html;charset=euc-kr"
             import="cookie.LoginManager"%>
 
<% LoginManager loginManager = LoginManager.getInstance(); %>
<html>
<body>
<center>
현재 접속자수 : <%= loginManager.getUserCount() %><p>
<hr>
<%
             if(loginManager.isLogin(session.getId())){  //세션 아이디가 로그인 중이면
                           out.println(loginManager.getUserID(session.getId())+"님 안녕하세요<br>"
                                                                  +"<a href=bind_logout.jsp>로그아웃</a>");
             }
             else{  //그렇지 않으면 로그인 할 수 있도록
%>
<form name="login" action="bind_login_ok.jsp">
아이디: <input type="text" name="userID"><br>
비밀번회: <input type="text" name="userPW"><br>
<input type="submit" value="로그인">
</form>
<%         }%>
</center>
</body>
</html>
 
Bind_login_ok.jsp
 
<%@ page contentType="text/html;charset=euc-kr"
             import="cookie.LoginManager"%>
 
<% LoginManager loginManager = LoginManager.getInstance(); %>
<%
             request.setCharacterEncoding("euc-kr");
            
             String userID = request.getParameter("userID");
             String userPW = request.getParameter("userPW");
 
             if(loginManager.isValid(userID, userPW)){
                           if(!loginManager.isUsing(userID)){
                                        loginManager.setSession(session, userID);
                                        response.sendRedirect("bind_login.jsp");
                           }
                           else{
                                        throw new Exception("이미 로그인중");
                           }
             }
             else{
                           throw new Exception("ID/PW 이상");
             }
%>
 
Bind_logout.jsp
 
<%@ page contentType="text/html;charset=euc-kr"%>
<%
             session.invalidate();
             response.sendRedirect("bind_login.jsp");
%>

JavaScript Tip 프로그래밍 - JSP

페이지 로딩시 java함수 호출하기

보통 페이지를 호출할 때 자바스크립트가 실행되도록 하는 경우 아래와 같이 body에 onLoad라는 이벤트 핸들러를 쓴다.

  1. <body onLoad="해당함수();"> //IE에서만 실행됨. 쓰지 않는 것이 좋다.

그런데 header 페이지를 따로 통일시켜 페이지 디자인과 개발 소스를 나누어 관리하는 경우 body에 onLoad 이벤트 핸들러를 쓰기가 쉽지 않다.

수십, 수백페이지중 특정 페이지에서 호출을 하려고 하는데 header파일을 건드리기는 주저하기 마련이다.

이런 경우 다른 방법으로 onLoad 이벤트 핸들러를 호출할 수 있는 방법이 있다.

  1. <script language="javascript">
  2. window.onload() { 
    1. 해당함수();
  3. }
  4. </script>

 

select 메뉴의 포커스 없애기

원래 html의 속성을 생각하면 onfocus()로 포커스 지정,  onblue()로 포커스 해제가 되어야 한다.

그런데 select 메뉴의 경우 초기화 후 javascript를 통해 생성하는 경우(ajax에서 dom을 뿌려줄 때) 중에 onLoad시 자동 생성되는 경우에 이 포커스가 잘 안먹는다.

이럴때는 꽁수로 아래와 같이 하자. (사실 값은 현재 존재하지 않는 값이면 다 된다. 명료하게 보여주려고 -1을 선택했을 뿐.=ㅅ=

  1. document.frm.selectMenu.selectedIndex = -1

 

크로스 브라우징 관련하여 주의해야하는 부분

IE기준으로 많은 웹페이지들이 개발되고 있지만 본질적으로 웹개발은 웹표준을 준수하여 이를 따르는 여러 브라우저에서 동일하게 출력이 되도록 하는 것이 옳다.

이를 위해서 웹개발시 주의해야하는 부분들에 대해 살펴보자.

  1. IE전용 함수 혹은 각 브라우저용 전용 함수의 사용을 자제한다.

    • 먼저 아래의 소스를 보자. 
      1. <script language="javascript">
        1. function window::onLoad() { 
          1. 함수 구현
        2. }
      2. </script>
    •  위의 경우 IE에서는 페이지 로딩시 onLoad()에 속한 부분이 올바르게 실행되지만 FF(파이어 폭스)와 같은 타 브라우저에서는 실행이 되지 않는다.
      이는 해당 함수가 IE전용 함수이기 때문이다 이러한 함수들은 굳이 onLoad와 같은 IE전용함수로 만들지 않고 구현될 부분을 실행영역 하단에 위치 시키는 것이 좋다.
      1. <div id="insertArea"></div>
      2. <script language="javascript"> 
        1. document.getElementById("insertArea").innerHTML = "구현된 출력부분";
      3. </script>
    • 또 다른 방법으로 window:onLoad()가 아닌 window.onload = function() 을 쓰는 것이다. 

      1. <script language="javascript">
      2. window.onload= function() {

        1. 함수 구현
      3. }
      4. </script>
    •  스크립트 실행 전에 실행영역을 지정해야 오류가 나지 않는다는 것을 명심해야한다. (브라우저에서 출력할 source를 line by로 읽어들여 실행하기 때문이다.)
  2.  W3C의 규약을 지키는 속성들을 사용한다.
    • 각 브라우저마다 특화된 무수히 많은 메소드와 속성이 있겠지만 W3C에서 규약한 메소드와 속성을 따르는 것이 좋다. 이는 브라우저들은 기본적으로 W3C에서 규약한 웹표준을 표현하려고 하기 때문이다.
      이에 대해서 정리한 사이트가 있다. (http://www.w3schools.com/)
      하지만 W3C의 규약을 지킨다 하더라도 각 브라우저마다 이를 실행하는 것은 차이가 존재할 수 있다. 예를 들어 아래와 같은 HTML DOM Style Object를 보자.
      1. <div id="outputArea"></div>
      2. <script language="javascript> 
        1. document.getElementById("outputArea").style.marginLeft = "30";
      3. </script>
    • 위의 경우 IE에서는 제대로 처리가 되지만 FF에서는 올바른 처리가 되지 않는다.
      이는 FF에서는 단위 명시가 불분명한 경우 오류 처리로 무시해버리기 때문이다 따라서 위의 경우는 아래와 같이 단위도 명시해주는 것이 좋다. 
      1. <div id="outputArea"></div>
      2. <script language="javascript"> 
        1. document.getElementById("OutputArea").style.marginLeft = "30px";
      3. </script>
    • [여백]
  3. 전역변수를 사용할 경우 꼭 변수선언을 해준다.
    • IE에서는 전역변수의 경우 var를 지정해주지 않으면 전역변수로 인식을 하지 않는다.
    • FF에서는 전역변수를 지정하지 않더라도 function외부에서 변수가 사용이 되면 전역변수가 된다.
  4. ajax를 사용시 xml에서 정보를 불러들이는 경우 차이가 있다.
    • IE의 경우 불러온 값을 호출을 할때 순차적으로 불러온 노드의 값을 각 item의 text로 불러들여진다. FF의 경우 text 속성이 없으며 불러들여진 nodeList의 값이 IE와 다르다.
    • IE의 경우
      • #루트노드
        노드네임
        ...
        노드네임
    • FF의 경우
      • #루트노드
        노드네임
        #자식노드
        노드네임
        #자식노드
        노드네임
        ...
        #자식노드
        노드네임
    • 위와 같이 순차적으로 불러들여지는 값이 차이가 생긴다. 어쩔수 없이 구분을 지어서 사용해야 하는 실정이다. 
    •  text 속성은 IE전용 속성이며 W3C규약이 아니다. 따라서 사용하지 않는 것이 좋다.  (현 상황에선 별수 없을듯..)
      1. objNodeList.item(i).childNodes.item(0부터 노드의 갯수만큼).text
    • FF의 경우 노드별로 text를 불러들이는 함수가 없고 대신 textContent라는 속성이 존재하여 해당 노드의 값을 저장한다. 따라서 위에서 사용한 부분이 FF에서는 아래와 같이 변형되어진다.
    • textContent 속성은 FF에서만 사용이 가능하나 W3C 규약에 정해져 있다. (그러나 타 브라우저에서 지원하지 않고 있는 실정이다.)
      1. if (objNodeList.item(i).nodeName != "#text") { 
        1. objNodeList.item(i).childNodes.item(1..3..5..7의 노드텍스트 속성이 존재하는 부분).textContent;
      2. }
    •   [여백]
  5. FF의 경우 vbScript를 지원하지 않는다.

 

배열변수 생성과 관련한 성능향상 방법에 대하여

흔히 xml을 호출하여 innerHTML 메소드를 통해 값을 뿌려줄 때, 혹은 기타 구문처리에서 for문을 돌려 해당 xml의 내용을 어떤 변수에 반복 삽입하는 방법을 즐겨쓰게 된다.

그전에 한가지 언급하자면 호출된 값을 뿌려주는 방식은 2가지가 있는데

  1. dom개체를 생성하여 해당 노드에 innerHTML을 통해 값을 입력한다.
  2. 변수에 innerHTML을 통해 입력할 값을 모은다음에 한방에 집어넣는다.

dom을 통해 각 노드들의 object model을 생성하는 것보다 변수을 생성해서 한꺼번에 뿌려주는 것이 확실히 성능에 도움이 된다.

이것은 일반적으로 많이 쓰이는 방법이다.

 

이에 대해서 좀더 성능향상을 할 수 있는 방법에 대해 이야기하도록 하겠다.

이에 대해 명확하게 눈으로 보이는 결과를 확인하기 위한 소스를 짜보도록 하자.

  1. <html>
  2. <head>
  3. <script language="javascript">
  4. var maxLoop = 500;
  5. var testContent = "이것은 테스트입니다.<br>";
  6. function testDOM(){
    1. var myHtml = document.childNodes.item(0);
    2. var myBody = myHtml.childNodes.item(1);
    3. var testArea = myBody.childNodes.item(0);
    4. var startTime = new Date().getTime();
    5. for (var i=0; i<maxLoop; i++) {
      1. testArea.innerHTML+= testContent;
    6. }
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  7. }
  8. function testInnerHTML1(){
    1. var testArea = document.getElementById("testArea")
    2. var roopText;
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
    5. testArea.innerHTML = testArea.innerHTML + testContent;
    6. }
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  9. }
  10. function testInnerHTML2(){
    1. var testArea = document.getElementById("testArea");
    2. var roopText = "";
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
      1. roopText += testContent;
    5. }
    6. testArea.innerHTML = roopText;
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  11. }
  12. function testInnerHTMLByArray() {
    1. var testArea = document.getElementById("testArea");
    2. var roopText = new Array();
    3. var startTime = new Date().getTime();
    4. for (var i=0; i<maxLoop; i++) {
      1. roopText[roopText.length] = testContent;
    5. }
    6. testArea.innerHTML = roopText.join('');
    7. var endTime = new Date().getTime();
    8. var runTime = endTime - startTime;
    9. document.getElementById("runTime").innerHTML = "실행 시간 : " + runTime;
  13. }
  14. </script>
  15. </head>
  16. <body>
  17. <div id="testArea"></div>
  18. <div id="runTime"></div>
  19. <a onClick="testInnerHTML1();">testInnerHTML1</a></br>
  20. <a onClick="testInnerHTML2();">testInnerHTML2</a></br>
  21. <a onClick="testInnerHTMLByArray();">testInnerHTMLByArray</a></br>
  22. </body>
  23. </html>

위의 예제를 보면 순서대로

  1. innerHTML에 매번 추가 작업을 실행하는 경우
  2. 변수를 생성하여 값을 저장한후 한번에 innerHTML을 실행한 경우
  3. 배열을 만들어 해당 배열을 join메소드를 통해 저장한 경우

 이다. DOM처리를 테스트 하지 않은 것은 일단 DOM생성을 통한 출력은 상당히 느리다는 전제를 이미 하고 있기 때문이다.

우선 1번과 2번의 결과를 테스트 해보면 아래의 사실을 알 수 있다.

  • innerHTML을 매번 로딩하는 것이 부하가 더 걸린다. 
    • 이것은 innerHTML은 객체를 생성하는 명령이므로 변수에 값을 저장하는 경우에 비해 많은 부하가 걸린다는 사실을 알 수 있다.

2번과 3번의 경우 500번 정도의 Loop 실행으로는 별 차이를 느끼기 힘드므로 5000번으로 늘려 테스트를 해보자.

아마 2배~3배 이상 성능이 향상되는 것을 느낄 수 있을 것이다.

 

이것은 코드의 효율성 때문인데 매번 변수를 불러들어오는 경우 지난번 저장한 값을 다시 불러들여야 한다는 문제점이 발생한다.

즉, 점점 추가되는 값이 누적될수록 코드는 느려지고 성능은 점점 떨어지게 된다.

실제로 저 위의 값을 5만번으로 늘려서 실험해본결과 2번은 69201이란 시간이 걸린 반면 3번의 경우는 단지 2974의 시간이 걸렸다.

즉. 누적을 피할 수 있는 코드가 성능향상에 많은 도움이 되는 코드라는 것이다.

이는 Javscript 뿐만아니라 모든 언어에서 공통적으로 적용되는 사항이다.

 

단일 대입 if 구문 코드 줄이기

아래와 같이 사용하는 경우가 많다.

  1. <script language="javascript"> 
    1. if (a > b) {
      1. c = a;
    2. } else { 
      1. c = b;
    3. }
  2. </script>

 

위와 같이 조건식을 타서 하나의 실행코드가 들어가는 경우는 아래와 같이 '{', '}'의 생략이 가능하다.

  1. <script language="javascript"> 
    1. if (a > b) c = a;
    2. else c = b;
  2. </script>

 

또한 else if 구문이 없이 A가 아니면 B라는 식의 조건문은 아래와 같이 단축이 가능하다.

  1. <script language="javascript"> 
    1. c = a > b ? a : b;
  2. </script>

 

스타일 지정관련 성능향상에 대하여

순수 자바스크립트에서의 스타일 지정은 다음과 같은 형태로 이루어진다.

  1. <script language="javascript">
  2. function setStyle(obj) { 
    1. var selObj = document.getElementById("obj");
    2. obj.style.fontWeight = 700;
    3. obj.style.fontFace = "Arial";
    4. obj.style.fontSize = "20px;"
    5. obj.style.backgroundColor = "#FF0000";
    6. obj.style.color = "#FFFFFF";
    7. obj.noWrap = true;
  3. }
  4. </script>

하지만 이런형태의 개발은 위에서 설명한 배열변수 향상에 관한 내용과 똑같은 이유로 인해 속도저하의 원인이 된다. (반복적인 객체 호출이 실행되고 있으므로.)

따라서 위와 같은 코드는 아래와 같이 변경하는 것이 좋다.

  1. <script language="javascript">
  2. with (obj) {

    1. style.cssText = "font-Weight:700;font-face:Arial;font-size:20px;background-color:red;color:white;";
    2. noWrap = true;
  3. }
  4. </script>

 

뒤로가기 방지

일반적으로 자바스크립트의 이동은 아래와 같이 하게 된다.

  1. <script language="javascript"> 
    1. location.href="이동할 주소";
  2. </script>

그러나 아래와 같이 사용하게 되면 현재 페이지의 URL을 이동하되 history에 남기지 않아 back 할 수 없도록 한다.

  1. <script language="javascript"> 
    1. location.replace("이동할 주소");
  2. </script>

 

이미지 프리로딩

마우스 온 오버 할때 버튼이미지가 교체된다거나 배경 이미지의 변경이 있는 경우 아래와 같은 자바스크립트를 통해 해당 이미지를 바꿔주곤 한다.

  1. <img src="a.gif" onmouseover="this.src='b.gif';">

이런 경우 마우스가 오버하는 순간 이미지를 불러들여오게 되는데 만약 이미지가 배경이미지이거나 혹은 불러들이는 어떤 데이터가 용량이 큰 경우 사용자의 입장에서는 사이트의 반응이 느리다고 느낄 수 있다.

이런 문제를 해결하기 위해서는 미리 해당 데이터를 불러들여오는 방법이 있는데

불러들여오는 방법에는 여러가지가 있을 수 있다.

숨겨진 div그룹안에 해당 image를 호출하거나 아이프레임을 쓴다거나 하는 방법들을 쓸 수 있지만

이런 식으로 이미지를 불러들이는 경우 디스플레이 되지 않는 이미지를 로딩하기 위해 첫 페이지의 진입속도가 더뎌지는 문제가 생기게 된다.

따라서 아래와 같은 방법을 사용하면 좋다.

  1. <script language="javscript">
  2. var preloadImage;
  3. function preload() {
  4. preloadImage  = new Image();

    preloadImage.src="이미지주소";

    }

    window.onload = function() {

    preload();

    }

  5. </script>

설명하자면 미리 로딩할 이미지를 담을 객체를 전역 이미지 객체로 생성한 후 이 객체에 담을 이미지들을 담고 있는 함수를 현 페이지의 로딩이 끝난 상태에서 불러들이는 것이다.

 

insertAdjacentHTML, insertAdjacentText

InnerHTML 이나 InnerText는 해당 element 내에 HTML이나 text를 집어넣지만 위의 두 속성은 추가를 하는 개념이다.

추가를 하는 위치는 해당 element의 바로 앞, 시작된 태그의 바로 안쪽 시작부분, 태그 종로 바로 다음 부분이다.

  1. insertAdjacentHTML("BeforeBegin", "들어갈 내용");

위치에 대한 값은 위에 언급한 3가지가 있으며 해당 값은 아래와 같다.

  • BeforeBegin : 시작 태그 바로 앞
  • AfterBegin : 시작 태그 바로 뒤
  • AfterEnd : 종료 태그 바로 뒤

 

Animation 효과를 줄 때는?

Javascript로 화면에 보이는 객체에 대하여 속성값을 변경하는 것은 알고 있다.

그렇다면 이러한 속성값의 변화를 통해 Animation 효과를 줄 때는 어떻게 해야할까?

이럴때는 setInterval 함수를 사용하면 된다.

이 함수는 주기적으로 다른 함수를 호출하는데 쓰이는데 이 함수를 통해 객체의 속성값이 점차적으로 변하도록 하면 Animation 효과가 나타나게 되는 것이다.

함수의 사용법은 다음과 같다.

  1. <script language="javascript">
  2. var setXposition = 0;
  3. var setYPosition = 0;
  4. function start() { 
    1.  window.setInterval("move()", 50);
  5. }
  6. function move() { 
    1. document.getElementById("moveTarget").left = setXposition + 1;
    2. document.getElementById("moveTarget").left = setXposition + 1;
  7. }
  8. </script>

 

간단한 정규식 모음

자주 쓰이는 정규식 패턴이다.

  1. var regNum =/^[0-9]/; 
  2. var regPhone =/^[0-9]{2,3}-[0-9]{3,4}-[0-9]{4}/;
  3. var regMail =/^[_a-zA-Z0-9-]+@[._a-zA-Z0-9-]+.[a-zA-Z]/;
  4. var regDomain =/^[.a-zA-Z0-9-]+.[a-zA-Z]/;
  5. var regAlpha =/^[a-zA-Z]/;
  6. var regHost =/^[a-zA-Z-]/;
  7. var regHangul =/[가-힣]/;
  8. var regHangulEng =/[가-힣a-zA-Z]/;
  9. var regHangulOnly =/^[가-힣]/;
  10. var regId = /^[a-zA-Z]{1}[a-zA-Z0-9_-]{4,15}/;

기타 패턴은

http://bluebreeze.co.kr/entry/javascript-정규식-표현정리

링크를 참조.

 

Ajax 호출 결과 display 딜레이 문제 처리

ajax를 호출 한 후 리턴된 결과를 display 하려고 할 때 display  c

출처 : http://bluesky.springnote.com/pages/375558


window.onload() 프로그래밍 - JSP


body 태그에서는 onload 이벤트가 먹는데 table이나 div에서는 먹지를 않아서..
(어디선가 onload는 거의 다먹는다고 들었는데 원래 안먹는건지;;)

 <script type="text/javascript" language="javascript">
    function window.onload()
    {
 
    }
 </script>

이렇게 스크립트를 쓰면 페이지가 load될때 호출 할 수 있다.

참고 : 네이버지식인

IE6에서 png파일 적용 시키기 웹표준 / 웹디자인

 

 

 

 

1. 배경에 png 파일을 쓰는 경우

 

   : ie6에서 쓰는 핵만 써주면 너무 간단하게 해결이 된다. (첨부파일 : png 적용_01.htm)

 

<!DOCTYPE html PUBLIC "-//W3C//DTD xhtml 1.0 Transitional//EN">
<html>
<head>
<title> :: png 적용 시키기 :: STEP 1 :: </title>
<meta http-equiv="Content-type" content="text/html; charset=euc-kr">
<style>
body {background:#000;}
#png {width:40px;height:75px;background:url(btn_next.png) no-repeat left top; _background:none; _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='btn_next.png',sizingMethod='crop');}
</style>
</head>

 

<body>
<div id="png">
</div>
</body>
</html>

 

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

참고로 설명 드리자면 ie6을 제외한 곳에서 배경을 주고 ie6에선 배경을 없애고 필터로 적용한 것입니다.

 

2. png에 a테그를 적용하고싶은 경우

 

   : 완벽한 표준이라 부르긴 뭐하지만 살짝 돌려서 생각하면 참 쉬운 방법이 있습니다. (첨부파일 : png 적용_02.htm)

 

<!DOCTYPE html PUBLIC "-//W3C//DTD xhtml 1.0 Transitional//EN">
<html>
<head>
<title> :: png 적용 시키기 :: STEP 2 :: </title>
<meta http-equiv="Content-type" content="text/html; charset=euc-kr">
<style>
img {border:none;}
body {background:#000;}
#png {width:40px;height:75px;background:url(btn_next.png) no-repeat left top; _background:none; _filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='btn_next.png',sizingMethod='crop');}
</style>
</head>

 

<body>
<div id="png">
   <a href="http://blog.naver.com/purism02"><img src="blank.gif" width="40" height="75" alt="NEXT" /></a>
</div>
</body>
</html>

 

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

배경에 png를 깔아주고 a링크에만 gif를 올려주어서 위치를 잡아주었습니다.

 

3. img 테그에 쉽게 png에 적용 하는 방법

 

   :  통괄적으로 사용하기 가장 쉽고 오류 잡을 때 가장 표준화에 접근한 방식입니다.  (첨부파일 : png 적용_03.htm)

 

<!DOCTYPE html PUBLIC "-//W3C//DTD xhtml 1.0 Transitional//EN">
<html>
<head>
<title> :: png 적용 시키기 :: STEP 3 :: </title>
<meta http-equiv="Content-type" content="text/html; charset=euc-kr">
<style>
body {background:#000;}
.png {_display:inline-block;}
.png img {_filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);}
</style>
</head>

 

<body>
<div>
   <span class="png" style="_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='btn_next.png');">
      <img src="btn_next.png" alt="NEXT" />
   </span>
</div>
</body>
</html>

 

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

이번엔 <spna>이란 아이를 사용해서 inline 으로 css를 넣어서 모양을 만들어 주었습니다.

 

 

 

첨부파일 pngAdd.zip 은 엉이님 블로그의 파일을 받아서 올린겁니다.

보통은 js 를 이용하여 처리합니다.
해당 첨부파일 : unitpngfix.zip

UTL_FILE.FOPEN

v_Use := UTL_FILE.FOPEN(디렉토리,파일명,'r'); --r은 읽기 w은 쓰기

 

if UTL_FILE.IS_OPEN(v_Use) then --파일이 열려 있으면 true

 loop

  begin

   UTL_FILE.GET_LINE(v_Use,v_Input); --파일을 한라인씩 가져와 v_Input 에 담는다.

   v_line1 := fn_split(v_Input,1); --스플릿 함수를 사용하여 잘라낸다. 스플릿 함수는 알아서 만드시길

   v_line2 := fn_split(v_Input,2);

 

   INSERT INTO TEST_TABLE(COL1,COL2) VALUES(v_line1,v_line2);

 

  exception WHEN NO_DATA_FOUND THEN
        v_rmk := 'SUCCESS'; exit;
  end;

 end loop;

end if;

 

UTL_FILE.FCLOSE(v_Use); --열린 파일을 닫아준다.

 

 

[출처] UTL_FILE PACKAGE|작성자 스며들기


던파라디오 홈페이지 접속안하고 듣기 낙서장 - 넋두리

주소 :
http://d-fighter.nefficient.co.kr/samsungdnf/neople/radio/dnfradio_syj_20100805.mp3

http://d-fighter.nefficient.co.kr/samsungdnf/neople/radio/dnfradio_syj_오늘날짜.mp3

뒤의 날짜를 오늘 날짜로 변경한 후 클릭하면됩니다. ㅇ_ㅇ;
난중에 주소 바뀌면,

또 찾으면 되겠지요. (YYYYMMDD) 형태입니다.

User-Agent

           
   if (request.getHeader("User-Agent").indexOf("MSIE") >= 0) request.setAttribute("MSIE", "Y");
   

[Java] String을 InputStream으로..

[Java] String을 InputStream으로..

매우 좋은 글!

String을 InputStream으로 만들어야 하는 경우가 종종 발생한다.
라이브러리가 파일이나 네트웍과 같은 곳으로부터 읽어서 처리할 수 있도록 전달인자를 InputStream으로 되어 있다. 하지만 이 파일의 내용이 DB와 같은 곳에 있다면?? DB에서 읽으면 문자열일텐데.. 이걸 다시 파일에 기록하고 InputStream을 열어서 전달하기는 좀 무리가 있다. (어쩌면 난 경험이 부족해서 이런 경우에 더 좋은 방법이 있는데 모르는 것일 수도 있다. =ㅅ=;;)

일단.. String으로 읽어서 String을 InputStream으로 바꾸는 방법을 찾아봤다. JDK 1.0에 StringBufferInputStream라는 클래스가 있지만 이 녀석은 deprecated되었다. 대신 StringReader를 사용하라고 한다. InputStream과 Reader의 차이는 InputStream은 byte 단위로 읽는 녀석이지만, Reader는 문자(character) 단위로 읽는 녀석이다. ASCII의 경우는 동일하겠지만, 유니코드가 섞여 있다면 처리 방식이 달라질 수 있다. 문자열이라는 것은 인코딩이 되어 있으니까 String은 InputStream이 아닌 Reader로 읽는 것이 맞는 말이다.


그래서 StringBufferInputStream은 말 그대로 폐기.. 또 다른 방법은.. Apache Ant 라이브러리에 있는 StringInputStream을 사용하는 방법이다. 사용 방법은 아주 간단하다. Ant를 다운받고 lib 경로 아래에 있는 ant.jar 파일을 CLASS_PATH에 넣어주고 쓰면 된다. String 문자열을 생성자에 넣어주고 객체를 생성하면 그 문자열이 InputStream 처럼 동작한다. (뭐.. 그야 InputStream을 상속받았으니까 =ㅅ=;;) 아래 예제는 LDIF 파일을 읽어서 처리하는 부분이다. LDIFReader는 InputStream을 필요로 한다.

String ldifContent = "...";
StringInputStream is = new StringInputStream(ldifContent, "UTF-8");
LDIFReader reader = new LDIFReader(is, LDAPConnection.LDAP_V3);
LDAPMessage msg = reader.readMessage();
...

소스 코드를 보니 내부적으로는 Reader를 InputStream으로 변환해주는 org.apache.tools.ant.util.ReaderInputStream을 상속받아 org.apache.tools.ant.filters.StringInputStream을 구현했다. 이거 나중에 유용하게 사용할 수도 있겠다.


그리고 이런 라이브러리가 귀찮거나 기능에 비해 거추장스럽다면.. 간단하게 byte 배열을 이용하는 방법도 있다. String을 byte 배열로 변환한 후 ByteArrayInputStream을 사용하면 된다. 위의 코드에서 InputStream을 생성해 주는 부분만 아래와 같이 바꾸자.

ByteArrayInputStream is = new ByteArrayInputStream(ldifContent.getBytes("UTF-8"));



+ 정보 출처
How do I convert string into InputStream?
Java string to inputstream

초만 가지고 날짜 계산하기

 오라클 10G 기준

WITH A AS(
    SELECT TO_DATE('2010-07-03 12:03:02','YYYY-MM-DD HH24:MI S') AS FD, TO_DATE('2010-07-01 10:03:03','YYYY-MM-DD HH24:MI S') AS ED FROM DUAL
    UNION ALL
    SELECT TO_DATE('2010-07-03 12:03:02','YYYY-MM-DD HH24:MI S') AS FD, TO_DATE('2010-07-02 02:16:03','YYYY-MM-DD HH24:MI S') AS ED FROM DUAL   
)SELECT
     FD,ED,
     (FD - ED)*24*60,
     TRUNC(FD - ED) AS 일,
     MOD(TRUNC((FD - ED)*24),24) AS 시,
     MOD(TRUNC((FD - ED)*24*60),60) AS 분 
FROM A

한의 제국 07권 : 한단고기 낙서장 - 소설




    한의 제국은 일본의 뭐같은 후장빨던 매국노들은 삼대째 떵떵거리고 잘 살고 있는데
독립운동하다가 물에 빠져 죽은 조상을 둔 주인공을 매일같이 공돌이 일을 하며 하루 벌어살아가며 한탄을 합니다.

    그러다 우연에 우연을 거쳐 주인공은 광해군시대로 떨어지게 됩니다. 

    그래서 공돌이였던 지식을 활용해서 무시무시한 무기들과, 미래에 대한 선민적인 행동으로 백성들에게 사랑을 받습니다.

    07권에 들어서니 광해군이 광해제가 되는 군요. 제국을 선포합니다. 

    하하 통쾌하더군요.

    한단고기 잘몰랐는데 이글루스의 뭐같은 환까들 때문에 어떤 건지는 대충 알게됬습니다.
한의 제국의 경우 07권에서 드디어 대만이랑 필리핀 접수합니다.
신대륙 진출했고 시베리아로 확장하고 있습니다. 조금만 더 있으면 한단제국이 완성됩니다. ㅇ_ㅇ;

    이런 소설을 환까들이 보면 퇴마록의 이우형 작가처럼 이 작가를 환빠라고 매도하겠지요.
중학교 때 퇴마록에 빠져들었고 그때부터 아직까지 
수메르가 우리 갈래였다는 믿음도 다 잉여짓이라고 비판하는 것처럼 말입니다.

    중학생, 고등학생 사춘기 시절에 너들 나라는 일본에 똥꼬 빨던 놈들이 떵떵거리는 나라고
너그들의 조상은 중국에 후장빨다 일본에도 후장빨던 모든 주변 국가들의 빵셔틀 나라였다라는 사실을 말하는 것보다,

    우리 옛날에는 중국 넘봤고, 일본 교육 시켜주고 그런 멋진 엉아들이었어라는 이야기가 더 즐겁지 않겠습니까
정확히는 잘 모르지만 한단고기가 나온 것도 일제 침략기 중 우리나라가 예전에는 좀
강했다는 희망을 담기 위한 과장된 부분이 없지 않은 그런 판타지 중 하나가 종교로 발전하게 된
경우라고 알고 있습니다.

    뭐 일본의 역사왜곡을 옹호하는 건 아니기 때문에 우리나라의 자주적인 역사 왜곡을 옹호하는
좀 이기적인 글이 되버리는 군요. 그냥 위기 상황에서 자주성을 높이기 위해 과장된 판타지 소설이 존재할 수 있다는
사실에 대해서는 이해해줍시다 정도겠습니다.

   하고싶은 말은 판타지 소설을 진실로 믿고 시동어를 부르지르는 아혜들에게 마법을 못부리니
너는 마법사가 아니라고 하는 못된 어른이 되지는 말자는 말입니다.

    한단고기를 믿는 건 아니지만 뭔가 이런 대체역사를 보고 일본을 괴롭히고 중국을 쳐부수는 모습이
통쾌하니 한단고기를 믿는 사람들을 이해 못하는 건 아닙니다.
(원래 미국도 괴롭혀줘야하는데, 광해군시대는 미국은 존재하지 않았...)


판독성    : ★★★★★    : 읽기 편합니다.
전개속도 : ★                : 07권부터 주변인물들 이야기를 하다보니 지루해졌습니다.
캐릭터    : ★★★★★    : 1권부터 주인공은 킹왕짱

    결론 한의제국 07권 재미있습니다. 환상미디어는 책을 너무 늦게 보내줍니다. 

1 2 3 4 5 6


300