Nocturne

'낙서장' 카테고리의 다른 글

불위야 비불능야  (0) 2014.12.22
故 신해철_ 저 당당함  (0) 2014.12.09
블로그 개설  (0) 2014.11.25

[jQuery] dataType속성을 이용한 JSON 데이터 가져오기


dataType속성을 이용한 JSON 데이터 가져오기



1. 다운로드

.json 파일 자체는 json 데이터라서 따로 변환 작업을 불요하나, 자바에서는 자바데이터를 JSON 데이터로 변환하는 작업이 필요하다. 해당작업을 하기 위해서는 아래의 jar 파일을 다운받자.

https://code.google.com/p/google-gson/downloads/detail?name=google-gson-2.2.4-release.zip에서 파일을 다운받는다.

--> 해당 JSP 파일에 <%@ page import="com.google.gson.*"%> 추가


2. 파일내용

(1) test3.html

<!DOCTYPE>

<html>

 <head>

  <title> jquery Ajax test </title>

  <meta charset="utf-8" />

  <script type="text/javascript" src="../jquery.js"></script>

  <script type="text/javascript">

    $(document).ready(function(){

      $("#button").click(function(){

          callAjax();

      });

    });

    function callAjax(){

   

        $.ajax({ 

        type :'post',

        data :{

        programmer : $('#programmer').val(),

        designer: $('#designer').val(),

        pm : $('#pm').val(),

        customer : $('#customer').val()

        },  

       url : './test3.jsp',

       dataType : 'json',

       success: whenSuccess,

       error: whenError

      });

    }


    var html = '';

    function whenSuccess(retdata){

    $.each(retdata, function(index,entry){ 

    html += '<div>';

      html += '<h3>' + entry.programmer +'</h3>';

      html += '<h3>' + entry.designer + '</h3>';

             html += '<h3>' + entry.pm + '</h3>';

      html += '<h3>' + entry.customer + '</h3>';

      html += '</div>';

    });

    $('#ajaxReturn').html(html);

    }

    

    function whenError(){

        alert("Error");

    }

  </script>

 </head>

 <body>

 <div style="width:500px;margin:auto;margin-top:200px;">

<form id="frm">

<div>

    <label>프로그래머</label><input name="programmer" id="programmer" >

    </div>

    <div style="margin-top:20px;">

    <label>디자이너</label><input name="designer" id="designer">

    </div>

    <div style="margin-top:20px;">

    <label>PM</label><input name="pm" id="pm">

    </div>

    <div style="margin-top:20px;">

    <label>고객</label><input name="customer" id="customer">

    </div>

    <div style="margin-top:20px;">

    <input id="button" type="button" value="버튼">

    </div>

</form>

<div id="ajaxReturn">ajaxReturnOutput</div>

 </div>

 </body>

</html>


(2) test3.jsp

JSON 라이브러리는 다양하게 존재하는 것 같다.

하지만, 사용법은 크게 벗어나지는 않는다. 각각의 라이브러리의 메소드 이름만 조금 다를뿐 기본 동작 자체는 같다고 볼 수 있다. 

이클립스에서 빨간줄 쳐진다고 당황하지 말자.!

JSONObject

   - 기본구조 : {String name : Value, String name2 : Value2 ...}


JSONArray

   - 기본구조 : [{String name : Value}, {String name2 : Value2} ...]

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import="com.google.gson.*"%>

<% 

request.setCharacterEncoding("UTF-8");

String programmer = request.getParameter("programmer");

String designer = request.getParameter("designer");

String pm = request.getParameter("pm");

String customer = request.getParameter("customer");


JsonObject JsonObject = new JsonObject();

JsonObject.addProperty("programmer",programmer);

JsonObject.addProperty("designer",designer);

JsonObject.addProperty("pm",pm);

JsonObject.addProperty("customer",customer);

JsonArray jArray = new JsonArray();

jArray.add(JsonObject);

out.print(jArray.toString());

%>

실행결과)


3. 참조 URL

http://lssang.tistory.com/9

http://aljjabaegi.tistory.com/40


[jQuery] $.getJSON 이용한 JSON 데이터 가져오기


jQuery를 이용해 JSON 데이터 가져오기


1. 준비 파일

base.css은 필수 파일이 아님.


2. 각 파일 내용

(1) ex1.json

[

  {

    "term": "BACCHUS. 바쿠스",

    "part": "명사.",

    "definition": "고대인들이 술에 취할 명분으로 편의상 만들어낸 신.",

    "quote": [

      "꼴딱꼴딱 마실수도 있고,",

      "꿀꺽꿀꺽 마실수도 있다.",

      "술독에 빠져 줄곧 마시기도 하고",

      "찔끔찔끔 마시다 밤새 마시기도 한다."

    ],

    "author": "애주가"

  },

  {

    "term": "BACKBITE. 험담하다",

    "part": "동사.",

    "definition": "상대방에게 들킬 염려가 없을 때, 그에 관해 본 그대로를 입에담다."

  },

  {

    "term": "BANG. 빵! 가지런한 앞머리",

    "part": "명사.",

    "definition": "총 쏘는 소리. 앞머리를 잘라 내린 여성의 머리모양."

  },

  {

    "term": "BEGGAR. 거지",

    "part": "명사.",

    "definition": "고통스러워하는 부자에게 매정하게도 달라붙는 귀찮은 존재."

  },

  {

    "term": "BELLADONNA. 벨라돈나",

    "part": "명사.",

    "definition": "이탈리아어로는 '우아한 부인'; 영어로는 극약의 일종.  두 언어가 본질적으로 동일하다는 것을 가리키는 뚜렷한 일례."

  },

  {

    "term": "BIGAMY. 중혼죄",

    "part": "명사.",

    "definition": "이중 결혼을 말함. 취미상의 실수.."

  },

  {

    "term": "BORE. 따분한 사람",

    "part": "명사.",

    "definition": "이쪽의 이야기를 들어주었으면 싶은 때에 저 혼자만 지껄이는 자."

  }

]


(2) index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>jQuery를 이용한 JSON 데이터 구하기</title>
    <link rel="stylesheet" href="base.css" type="text/css" />
    <script src="jquery.js"></script>
    <script>
$(document).ready(function() {
  $('#target').click(function() {
    $.getJSON('ex1.json', function(data) {
      var html = '';
      $.each(data, function(entryIndexentry) {
       html += '<div class="entry">';
       html += '<h3 class="term">' + entry.term + '</h3>';
       html += '<div class="part">' + entry.part + '</div>';
       html += '<div class="definition">';
       html += entry.definition;
       html += '</div>';
       html += '</div>';
      });
      console.log(html);
      $('#dictionary').html(html);
    });
    return false;
  });
});
    </script>
  </head>
  <body>
    <div id="container">
      <div class="letters">
        <div class="letter" id="target">
          <h3><a href="#">클릭</a></h3>
       </div>
      </div>
             
      <div id="dictionary">
      </div>

    </div>
  </body>
</html>
실행결과)
클릭 버튼을 누르면 아래와 같이 JSON 데이터가 출력된다.




3. 설명

(1) $.getJSON(url,callback)

1) 자바에서 static 메서드와 유사--> jQuery에서는 전역메서드라 불린다.

2) 첫번째 매개변수로 JSON 파일을 로드한다. 

3) 두번째 매개변수(콜백함수)에서 JSON 파일을 이용하여 로드된 데이터를 처리한다. 콜백함수는 로드된 데이터를 인자로 넘겨받는다.(JSON 데이터를 참조하기 위해 data 변수를 사용하고 있다.)


(2) $.each()

$.each(collection, callback)

1) 매개변수

- collection: 순회할 배열이나 객체

- callback: 컬렉션의 각 요소를 대상으로 실행할 콜백 함수

callback 함수에서 첫번째 매개변수는 객체의 개수를 반환한다. index는 0부터 시작한다.

callback 함수에서 두번째 매개변수 객체의 key값을 반환한다. 반환된 key값을 이용하여 value값을 구할 수 있다.

2) 반환값: 컬렉션의 매개변수


1) 데이터 배열 혹은 컬렉션(data변수)을 순회하면서 각 아이템을 표현할 HTML을 생성한다.

2) 표준 for문을 사용해 배열을 순회하는 것을 $.each()로 대체하는 것이다.

3) $.each()를 사용해 각 항목을 반복 순회하면서 전달된 entry 맵의 내용으로 HTML 구조를 생성한다.

4) 모든 항목의 HTML이 작성되면 .html()을 사용해 <div id="dictionary">에 삽입하면 해당 <div>태그의 내용이 새로운 내용으로 변경된다.



[jQuery] Ajax 데이터통신 기본


Ajax 데이터통신 기본


1. 파일 내용

(1) test.html

<!DOCTYPE>

<html>

 <head>

  <title> jquery Ajax test </title>

  <meta charset="utf-8" />

  <script type="text/javascript" src="../jquery.js"></script>

  <script type="text/javascript">

    $(document).ready(function(){

      $("#button").click(function(){

          callAjax();

      });

    });

    function callAjax(){

   

        $.ajax({

       type: "post",

       url : "./test2.jsp",

       data: {

        number : $('#number').val(),

        id : $('#id').val(),

        comment : $('#comment').val()

       },

       success: whenSuccess,

       error: whenError

      });

    }

    

    function whenSuccess(resdata){

        $("#ajaxReturn").html(resdata);

        console.log(resdata);

    }

    

    function whenError(){

        alert("Error");

    }

  </script>

 </head>

 <body>

 <div style="width:500px;margin:auto;margin-top:200px;">

<form id="frm">

<div>

    <label>글번호</label><input name="number" id="number" >

    </div>

    <div style="margin-top:20px;">

    <label>아이디</label><input name="id" id="id">

    </div>

    <div style="margin-top:20px;">

    <label>코멘트</label><input name="comment" id="comment">

    </div>

    <div style="margin-top:20px;">

    <input id="button" type="button" value="버튼">

    </div>

</form>

<div id="ajaxReturn">ajaxReturnOutput</div>

 </div>

 </body>

</html>


(2) test2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import="java.util.*"%>

<% request.setCharacterEncoding("utf-8"); %>

<% response.setContentType("text/html; charset=utf-8"); %>

<html>

<head>

<title>JSP Example</title>

</head>

<body>

<p>

<% 

 String number = request.getParameter("number");

 String id = request.getParameter("id");

 String comment = request.getParameter("comment");

 

 HashMap<String,String> map = new HashMap<String,String>();

map.put("number",number);

map.put("id",id);

map.put("comment",comment);

%>

  글번호:<%=map.get("number")%><br>

  아이디:<%=map.get("id")%><br>

  코멘트:<%=map.get("comment")%><br>

<%


%>

</p>

</body>

</html>

실행결과)

버튼 클릭시 출력되는 예제이다.


cf.) serialize() 예제

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

 <head>

  <title> jquery Ajax test </title>

  <meta charset="utf-8" />

  <script type="text/javascript" src="../jquery.js"></script>

  <script type="text/javascript">

    $(document).ready(function(){

      $("#button").click(function(){

          callAjax();

      });

    });

    function callAjax(){

        var dataString = $("form").serialize(); //파라미터 직렬화 times=10&id=abc&comment=def

        $("#postedParam").text("afterParameter:"+dataString); //확인용 화면에 뿌려보자

        $.ajax({

       type: "POST",

       url : "http://localhost:8080/AjaxPrograming/temp/test.jsp",

       data: dataString, //서버로 보낼 데이터 data변수(form객체 컬렉션)

       success: whenSuccess, //성공시 callback함수 지정

       error: whenError //실패시 callback함수 지정

      });

    }

    

    // 성공시 호출될 함수

    function whenSuccess(resdata){

        $("#ajaxReturn").html(resdata);

        console.log(resdata);

    }

    

    // 실패시 호출될 함수

    function whenError(){

        alert("Error");

    }

  </script>

 </head>

 <body>

 <div style="width:500px;margin:auto;margin-top:200px;">

<form id="frm">

<div>

    <label>반복횟수</label><input name="number" value="10">

    </div>

    <div style="margin-top:20px;">

    <label>아이디</label><input name="id">

    </div>

    <div style="margin-top:20px;">

    <label>코멘트</label><input name="comment">

    </div>

    <div style="margin-top:20px;">

    <input id="button" type="button" value="버튼">

    </div>

</form>

<div id="postedParam">beforeParameter</div>

<div id="ajaxReturn">ajaxReturnOutput</div>

 </div>

 </body>

</html>


[Java] 예외 던지기

예외 던지기


1. 예외 되던지기


한 메서드에서 발생할 수 있는 예외가 여럿인 경우, 몇 개는 try-catch문을 통해서 메서드 내에서 자체적으로 처리하고, 그 나머지는 선언부에 지정하여 호출한  메서드에서 처리하도록 함으로써, 양쪽에서 나눠서 처리되도록 할 수 있다. 그리고 심지어는 단 하나의 예외에 대해서도 예외가 발생한 메서드와 호출한 메서드, 양쪽에서 처리하도록 할 수 있다.

이것은 예외를 처리한 후에 인위적으로 다시 발생시키는 방법을 통해서 가능한데, 이것을 '예외 던지기'이라고 한다.

먼저 예외가 발생한 가능성이 있는 메서드에서 try-catch문을 사용해서 예외를 처리해주고 catch문에서 필요한 작업으로 행한 후에 throw문을 사용해서 예외를 다시 발생시킨다.

다시 발생한 예외는 이 메서드를 호출한 메서드에게 전달되고 호출한 메서드의 try-catch문에서 예외를 또다시 처리한다.

이 방법은 하나의 예외에 대해서 예외가 발생한 메서드와 이를 호출한 메서드 양쪽 모두에서 처리해줘야 할 작업이 있을 때 사용된다.

이 때 주의할 점은 예외가 발생할 메서드에서는 try-catch문을 사용해서 예외처리를 해줌과 동시에 메서드의 선언부에 발생할 예외를 throws에 지정해줘야 한다는 것이다.


class ExceptionEx23 {

public static void main(String[] args) {

try  {

method1();

} catch (Exception e) {

System.out.println("main메서드에서 예외가 처리되었습니다.");

}

} // main메서드의 끝


static void method1() throws Exception {

try {

throw new Exception();

} catch (Exception e) {

System.out.println("method1메서드에서 예외가 처리되었습니다.");

throw e; // 다시 예외를 발생시킨다.

}

} // method1메서드의 끝

}

실행결과)

method1메서드에서 예외가 처리되었습니다.

main메서드에서 예외가 처리되었습니다.

결과에서 알 수 있듯이 method1()과 main메서드 양쪽이 catch블럭이 모두 수행되었음을 알 수 있다. method1()의 catch블럭에서 예외를 처리하고도 throw문을 통해 다시 예외를 발생시켰다.

그리고 이 예외를 main 메서드 한 번 더 처리 하였다.


2. 메서드에 예외 선언


메서드에 예외를 선언하려면, 메서드의 선언부에 키워드 throws를 사용해서 메소드 내에서 발생할 수 있는 예외를 적어주기만 하면 된다. 그리고, 예외가 여러 개일 경우에는 쉼표(,)로 구분한다.

void method( ) throws Exception1, Exception2....ExceptionN{

.... 메서드의 내용

}

--> 이 메서드는 Exception1, Exception2....ExceptionN와 같은 Exception이 발생할 수 있으니, 이 메서드를 호출하고자 하는 메서드에서는  Exception1, Exception2....ExceptionN을 처리 해주어야 한다는 뜻이다. 자신을 호출한 메서드에 예외를 전가시키는 것. 예외를 발생시키는 키워드 throw와 예를 메서드에 선언할 때 쓰이는 throws를 잘 구별하자


이렇게 메서드의 선언부에 예외를 선언함으로써 메서드를 사용하려는 사람이 메서드의 선언부를 보았을 때, 이 메서드를 사용하기 위해서는 어떠한 예외들이 처리되어져야 하는 쉽게 알 수 있다.

자바에서는 메서드를 작성할 때 메서드 내에서 발생할 가능성이 있는 예외를 메서드의 선언부에 명시하여 이 메서드를 사용하는 쪽에서는 이에 대한 처리를 하도록 강요하기 때문에, 프로그래머들의 짐을 덜어 주는 것은 물론이고 보다 견고한 프로그램 코드를 작성할 수 있도록 도와 준다.


메서드에 예외를 선언할 때 일반적으로 RuntimeException클래스들은 적지 않는다. 이 들은 메서드 선언부의 throws에 선언한다고 해서 문제가 되지는 않지만, 보통 반드시 처리해주어야 하는 예외들만 선언한다. 이처럼 Java API 문서를 통해 사용하고자 하는 메서드의 선언부와 'Throws:'를 보고, 이 메서드에서는 어떤 예외가 발생할 수 있으며 반드시 처리해주어야 하는 예외는 어떤 것들이 있는지 확인하는 것이 좋다. 반드시 처리해주어야 하는 예외는 Exception 클래스들(RuntimeException 클래스들 이외의 예외 클래스들)이다.

사실 예외를 메서드의 throws에 명시하는 것은 예외를 처리하는 것이 아니라. 자신(예외가 발생할 가능성이 있는 메서드)을 호출한 메서드에게 예외를 전달하여 예외처리를 떠맡기는 것이다.

예외를 전달받은 메서드가 또다시 자신을 호출한 메서드에게 전달할 수 있으며, 이런 식으로 계속 호출스택에 있는 메서드들을 따라 전달되다가 제일 마지막에 있는 main 메서드에서도 예외가 처리되지 않으면, main 메서드 마저 종료되어 프로그램이 전체가 종료된다.


class ExceptionEx18 {

public static void main(String[] args) throws Exception {

method1(); // 같은 클래스내의 static멤버이므로 객체생성없이 직접 호출가능.

  } // main메서드의 끝


static void method1() throws Exception {

method2();

} // method1의 끝


static void method2() throws Exception {

throw new Exception();

} // method2의 끝

}

실행결과)

Exception in thread "main" java.lang.Exception

at example.ExceptionEx18.method2(ExceptionEx18.java:13)

at example.ExceptionEx18.method1(ExceptionEx18.java:9)

at example.ExceptionEx18.main(ExceptionEx18.java:5)

위의 실행 결과를 프로그램의 실행도중에 java.lang.Exception이 발생하여 비정상적으로 종료했다는 것과 예외가 발생했을 때 호출스택(Call Stack)의 내용을 알 수 있다.


위의 결과로 부터 다음과 같은 사실을 알 수 있다.

1 예외가 발생했을 때, 모두 3개의 메서드(main, method1, method2)가 호출 스택에 있었다

2 예외가 발생한 곳은 제일 윗줄에 있는 method2()이다.

3 main 메서드가 method1()를 , 그리고 method1()은 method2()를 호출했다는 것을 알 수 있다.


위의 예제를 보면, method2()에서 'throw new Exception();' 문장에 의해 예외가 강제적으로 발생했으나 try-catch문으로 예외처리를 해주지 않았으므로, method2()는 종료되면서 예외를 자신을 호출한 method1()에게 넘겨준다. method1()에서도 역시 예외처리를 해주지 않았으므로 종료되면서 main메서드에게 예외를 넘겨준다.

그러나 main메서드에서 조차 예외처리를 해주지 않았으므로 main 메서드가 종료되어 프로그램이 예외로 인해 비정상적으로 종료되는 것이다.

이처럼 예외가 발생한 메서드에서 예외처리를 하지 않고 자신을 호출한 메서드에게 예외를 넘겨줄 수는 있지만, 이것으로 예외가 처리된 것은 아니고 예외를 단순히 전달만 하는 것이다.


결국 이는 한 곳에서는 반드시 try-catch문으로 예외처리를 해주어야 한다.

class ExceptionEx19 {

public static void main(String[] args) {

method1(); // 같은 클래스내의 static멤버이므로 객체생성없이 직접 호출가능.

  // main메서드의 끝


static void method1() {

try {

throw new Exception();

} catch (Exception e) {

System.out.println("method1메서드에서 예외가 처리되었습니다.");

e.printStackTrace();

}

// method1의 끝

}

printStackTrace()를 통해 예외에 대한 정보를 화면에 출력하였다. 예외가 method1()에서 발생했으며, main 메서드가 method1()을 호출했음을 알 수 있다.


class ExceptionEx20 {

public static void main(String[] args) {

try  {

method1();

} catch (Exception e) {

System.out.println("main메서드에서 예외가 처리되었습니다.");

e.printStackTrace();

}

// main메서드의 끝


static void method1() throws Exception {

throw new Exception();

// method1()의 끝

} // class의 끝

ExceptionEx19는 method1()에서 예외처리를 했고, ExceptionEx20은 method1()에서 예외를 선언하여 자신을 호출하는 메서드(main 메서드)에 예외를 전달했으며, 호출한 메서드(main 메서드)에서는 try-catch문으로 예외처리를 했다.

ExceptionEx19 처럼 예외가 발생한 메서드(method1) 내에서 처리되어지면, 호출한 메서드(main 메서드)에서는 예외가 발생했다는 사실조차 모르게 된다.

ExceptionEx20처럼 예외가 발생한 메서드에서 예외를 처리하지 않고 호출한 메서드로 넘겨주면, 호출한 메서드에서는 method1()을 호출한 라인에서 예외가 발생한 것으로 간주되어 이에 대한 처리를 하게 된다. 이처럼 예외가 발생한 메서드 'method1()'에서 예외를 처리할 수도 있고, 예외가 발생한 메서드를 호출한 메서드 'main 메서드' 에서 처리할 수도 있다. 또는 두 메서드가 예외 처리를 분담할 수 있다.



'Programing > Java' 카테고리의 다른 글

[Java] 객체를 제거하는 방법  (1) 2015.05.19
[Java] Wrapper 클래스  (0) 2015.04.13
[Java] 예외 만들기  (0) 2014.12.25
[Java] 예외 처리 기본  (0) 2014.12.25
[Java] enum  (0) 2014.12.25

[Java] 예외 만들기


예외 만들기


1. 예외 발생시키기

키워드 throw를 사용해서 프로그래머가 고의로 예외를 발생시킬 수 있다.

1) 연산자 new를 이용해서 발생시키려는 예외 클래스의 객체를 만든 다음

  Exception e = new Exception("고의로 발생시켰음");


2) 키워드 throw를 이용해서 예외를 발생시킨다.

  throw  e;


class ExceptionEx

{

public static void main(String args[]) 

{

try {

Exception e = new Exception("고의로 발생시켰음.");

throw e; // 예외를 발생시킴

//  throw new Exception("고의로 발생시켰음.");  // 위의 두 줄을 한 줄로 줄여 쓸 수 있다.

} catch (Exception e) {

System.out.println("에러 메시지 : " + e.getMessage());

e.printStackTrace();

}

System.out.println("프로그램이 정상 종료되었음.");

}

}

실행결과)

에러 메시지 : 고의로 발생시켰음.

프로그램이 정상 종료되었음.

java.lang.Exception: 고의로 발생시켰음.

at example.demo.main(demo.java:8)


2. 사용자 정의 예외 만들기

기존의 정의된 예외 클래스 외에 필요에 따라 프로그래머가 새로운 예외 클래스를 정의하여 사용할 수 있다. 보통 Exception클래스로부터 상속받는 클래스를 만들지만, 필요에 따라서 알맞은 예외 클래스를 선택할 수 있다.

class MyException extends Exception{

MyException(String msg){// 문자열을 매개변수로 받는 생성자

super(msg);// 조상인 Exception 클래스의 생성자를 호출한다.

}

}


Exception 클래스로부터 상속받아서 MyException클래스를 만들었다. 필요하다면, 멤버변수나 메서드를 추가할 수 있다. Exception 클래스는  생성 시에 String값을 받아서 메시지로 저장할 수 있다. 사용자 정의 예외 클래스도 메시지를 저장할 수 있으려면, 위에서 보는 것과 같이 String을 매개변수로 받는 생성자를 추가해주어야 한다.

class MyException extends Exception{// 에러 코드 값을 저장하기 위한 필드를 추가 했다.

private final int ERR_CODE;// 생성자를 통해 초기화 한다.

MyException(String msg, int errcode){ //생성자

super(msg);

ERR_CODE=errCode;

}

MyException(String msg){// 생성자

this(msg, 100)l// ERR_CODE를 100(기본값)으로 초기화한다.

}

public int getErrCode(){// 에러 코드를 얻을 수 있는 메서드도 추가한다.

return ERR_CODE;// 이 메서드는 주로 getMessage()와 함께 사용될 것이다.

}

}

이전의 코드를 좀더 개선하여 메시지뿐만 아니라 에러코드 값도 저장할 수 있도록 ERR_CODE와 getErrCode()를 MyException클래스의 멤버로 추가했다.

이렇게 함으로써 MyException이 발생했을 때, catch블럭에서 getMessage()와 getErrCode()를 사용해서 에러코드와 메시지를 모두 얻을 수 있을 것이다.


class NewExceptionTest {

public static void main(String args[]) {

try {

startInstall(); // 프로그램 설치에 필요한 준비를 한다.

copyFiles(); // 파일들을 복사한다. 

} catch (SpaceException e) {

System.out.println("에러 메시지 : " + e.getMessage());

e.printStackTrace();

System.out.println("공간을 확보한 후에 다시 설치하시기 바랍니다.");

} catch (MemoryException me) {

System.out.println("에러 메시지 : " + me.getMessage());

me.printStackTrace();

System.gc(); //  Garbage Collection을 수행하여 메모리를 늘려준다.

System.out.println("다시 설치를 시도하세요.");

} finally {

deleteTempFiles(); // 프로그램 설치에 사용된 임시파일들을 삭제한다.

} // try의 끝

} // main의 끝


   static void startInstall() throws SpaceException, MemoryException { 

if(!enoughSpace()) // 충분한 설치 공간이 없으면...

throw new SpaceException("설치할 공간이 부족합니다.");

if (!enoughMemory()) // 충분한 메모리가 없으면...

throw new MemoryException("메모리가 부족합니다.");

   } // startInstall메서드의 끝


   static void copyFiles() { /* 파일들을 복사하는 코드를 적는다. */ }

   static void deleteTempFiles() { /* 임시파일들을 삭제하는 코드를 적는다.*/}

   

   static boolean enoughSpace()   {

// 설치하는데 필요한 공간이 있는지 확인하는 코드를 적는다.

return false;

   }

   static boolean enoughMemory() {

// 설치하는데 필요한 메모리공간이 있는지 확인하는 코드를 적는다.

return true;

   }

} // ExceptionTest클래스의 끝


class SpaceException extends Exception {

SpaceException(String msg) {

  super(msg);

   }


class MemoryException extends Exception {

MemoryException(String msg) {

  super(msg);

   }

}

실행결과)

에러 메시지 : 설치할 공간이 부족합니다.

example.SpaceException: 설치할 공간이 부족합니다.

at example.ExceptionEx18.startInstall(ExceptionEx18.java:24)

at example.ExceptionEx18.main(ExceptionEx18.java:6)

공간을 확보한 후에 다시 설치하시기 바랍니다.

MemoryException과 SpaceException, 이 두개의 사용자정의 예외 클래스를 새로 만들어서 사용했다

Space Exception은 프로그램을 설치하려는 곳에 충분한 공간이 없을 경우에 발생하도록 했으며, MemoryException은 설치작업을 수행하는데 메모리가 충분히 확보되지 않았을 경우에 발생하도록 하였다. 이 두 개의 예외는 startInstall()을 수행하는 동안에 발생할 수 있으며, enoughSpace()와 enoughMemory()의 실행 결과에 따라서 발생하는 예외의 종류가 달라지도록 했다.


'Programing > Java' 카테고리의 다른 글

[Java] Wrapper 클래스  (0) 2015.04.13
[Java] 예외 던지기  (0) 2014.12.25
[Java] 예외 처리 기본  (0) 2014.12.25
[Java] enum  (0) 2014.12.25
[Java] for-each문  (0) 2014.12.23

[Java] 예외 처리 기본


예외 처리 기본


컴파일 에러: 컴파일 할때 발생하는 에러이다.

런타임 에러: 프로그램의 실행도중에 발생하는 에러이다.


소스코드를 컴파일 하면 컴파일러가 소스코드(.java)에 대해 오타나 잘못된 구문, 자료형 체크 등의 기본적인 검사를 수행하여 오류가 있는지 알려준다. 컴파일러가 알려 준 에러들은 모두 수정해서 컴파일을 성공적으로 마치고 나면, 클래스 파일(.class)이 생성되고, 생성된 클래스 파일을 실행할 수 있게 되는 것이다.

컴파일러가 소스코드의 기본적인 사항은 컴파일시에 모두 걸러줄 수 있지만, 실행 도중에 발생할 수 있는 잠재적인 오류까지 검사할 수 없기 때문에 컴파일은 잘되었어도 실행 중에 에러에 의해서 잘못된 결과를 얻거나 프로그램이 비정상적으로 종료될 수 있다.


자바에서는 실행 시(runtime) 발생할 수 있는 프로그램 오류를 '에러'와 '예외' 두 가지로 구분하였다.

에러는 메모리 부족이나 스택오버플로우와 같이 일단 발생하면 복구할 수 없는 심각한 오류이고, 예외는 발생하더라도 수습될 수 있는 비교적 덜 심각한 것이다.

-> 에러와 예외는 모두 실행 시(runtime) 발생하는 오류이다.


1. 예외 클래스


RuntimeException 클래스들은 주로 프로그래머의 실수에 의해서 발생할 수 있는 예외들로서 자바의 프로그래밍 요소와 관계가 깊다.

--> 프로그래머의 실수로 발생하는 예외

Exception 클래스들은 주로 외부의 영향으로 발생할 수 있는 것들로서, 프로그램의 사용자들의 동작에 의해서 발생하는 경우가 많다.

--> 사용자의 실수와 같은 외적인 요인에 의해 발생하는 예외

RuntimeException 클래스들과 Exception 클래스들의 중요한 차이점은 컴파일시의 예외처리 체크여부이다. RuntimeException 클래스들 그룹에 속하는 예외가 발생할 가능성이 있는 코드에는 예외 처리를 해주지 않아도 컴파일 시에 문제가 되지 않지만, Exception 클래스들 그룹에 속하는 예외가 발생할 가능성이 있는 예외는 반드시 처리를 해주어야 하며, 그렇지 않으면 컴파일 시에 에러가 발생한다.


class ExceptionEx7 

{

public static void main(String[] args) 

{

throw new Exception(); // Exception을 강제로 발생시킨다.

}

}

이 예제를 작성한 후에 컴파일 하면 컴파일이 완료되지 않는다. 예외처리가 되어야 할 부분에 예외처리가 되어 있지 않다는 에러이다. 위의 결과에서 알 수 있는 것처럼, 위에서 분류한 '그 외의 Exception클래스들'이 발생할 가능성이 있는 문자들에 대해 예외처리를 해주지 않으면 컴파일 조차 되지 않는다.


따라서 위의 예제를 아래와 같이 try-catch 문으로 처리해 주어랴 컴파일이 성공적으로 이루어 질 것이다.

class ExceptionEx8 {

public static void main(String[] args) 

{

try {

throw new Exception();

} catch (Exception e) {

System.out.println("Exception이 발생했습니다.");

}

} // main메서드의 끝

}


※ 주의 할점

class ExceptionEx9 

{

public static void main(String[] args) {

throw new RuntimeException(); // RuntimeException을 강제로 발생시킨다.

}

}

위의 예제를 컴파일 하면, 예외를 처리하지 않았음에도 불구하고 이전의 예제와는 달리 성공적으로 컴파일이 될 것이다. 그러나 실행하면, RumtimeException이 발생하여 비정상적으로 종료될 것이다.

이 예제가 명백히 RuntimeException을 발생시키는 코드를 가지고 있고, 이에 대한 예외처리를 하지 않았음에도 불구하고 성공적으로 컴파일 되었다.

이와 같이 RuntimeException클래스들은 예외처리를 해주지 않아도 컴파일러가 문제삼지 않는 것을 알아야 한다.


2. 예외 처리의 정의와 목적

프로그램의 실행 도중에 발생하는 에러는 어쩔 수 없지만, 예외는 프로그래머가 이에 대한 처리를 미리 해주어야 한다.

예외처리란, 프로그램 실행 시 발생할 수 있는 예기치 못한 예외의 발생에 대비한 코드를 작성하는 것이며 예외처리의 목적은 예외의 발생으로 인한 실행 중인 프로그램의 갑작스런 비정상 종료를 막고, 정상적인 실행 상태를 유지할 수 있도록 하는 것이다.


정의:  프로그램 실행 시 발생할 수 있는 예외의 발생에 대비한 코드를 작성하는 것.

목적: 프로그램의 비정상 종료를 막고, 정상적인 실행 상태를 유지하는 것.


3. try...catch...finally

try...catch는 예외에서 핵심적인 역할을 담당하는 문법적인 요소다. 형식을 살펴보자.

class Calculator{

    int left, right;

    public void setOprands(int left, int right){

        this.left = left;

        this.right = right;

    }

    public void divide(){

        try {

            System.out.print("계산결과는 ");

            System.out.print(this.left/this.right);

            System.out.print(" 입니다.");

        } catch(Exception e){

            System.out.println("\n\ne.getMessage()\n"+e.getMessage());

            System.out.println("\n\ne.toString()\n"+e.toString());

            System.out.println("\n\ne.printStackTrace()");

            e.printStackTrace();

        }

    }

public class CalculatorDemo {

    public static void main(String[] args) {

        Calculator c1 = new Calculator();

        c1.setOprands(10, 0);

        c1.divide();

    }

}

실행결과)
e.getMessage()
/ by zero
 
e.toString()
java.lang.ArithmeticException: / by zero
 
e.printStackTrace()
java.lang.ArithmeticException: / by zero
    at org.opentutorials.javatutorials.exception.Calculator.divide(CalculatorDemo.java:11)
    at org.opentutorials.javatutorials.exception.CalculatorDemo.main(CalculatorDemo.java:25)
1) e.getMessage();
오류에 대한 기본적인 내용을 출력해준다. 상세하지 않다.
2) e.toString()
e.toString()을 호출한 결과는 java.lang.ArithmeticException: / by zero 이다. e.toString()은 e.getMessage()보다 더 자세한 예외 정보를 제공한다. java.lang.ArithmeticException은 발생한 예외가 어떤 예외에 해당하는지에 대한 정보라고 지금을 생각하자. ArithmeticException 수학적인 계산의 과정에서 발생하는 예외상황을 의미한다. (우리는 어떤 숫자를 0으로 나누려고 하고 있다는 것을 상기하자)
3) e.printStackTrace()
메소드 getMessage, toString과는 다르게 printStackTrace는 리턴값이 없다. 이 메소드를 호출하면 메소드가 내부적으로 예외 결과를 화면에 출력한다. printStackTrace는 가장 자세한 예외 정보를 제공한다.


(1) try


try 안에는 예외 상황이 발생할 것으로 예상되는 로직을 위치시킨다. 예를 들어, 사용자가 setOprands의 두 번째 인자로 숫자 0을 입력했을 때 문제가 발생할 수 있음을 예측할 수 있다. 그래서 이 로직을 try 구문으로 감싼 것이다.


(2) catch


catch 안에는 예외가 발생했을 때 뒷수습을 하기 위한 로직이 위치한다. 


(3) finally

class A{

    private int[] arr = new int[3];

    A(){

        arr[0]=0;

        arr[1]=10;

        arr[2]=20;

    }

    public void z(int first, int second){

        try {

            System.out.println(arr[first] / arr[second]);

        } catch(ArrayIndexOutOfBoundsException e){

            System.out.println("ArrayIndexOutOfBoundsException");

        } catch(ArithmeticException e){

            System.out.println("ArithmeticException");

        } catch(Exception e){

            System.out.println("Exception");

        } finally {

            System.out.println("finally");

        }

    }

}

 

public class ExceptionDemo1 {

    public static void main(String[] args) {

        A a = new A();

        a.z(10, 0);

        a.z(1, 0);

        a.z(2, 1);

    }

}

실행결과)

ArrayIndexOutOfBoundsException

finally

ArithmeticException

finally

2

finally


'Programing > Java' 카테고리의 다른 글

[Java] 예외 던지기  (0) 2014.12.25
[Java] 예외 만들기  (0) 2014.12.25
[Java] enum  (0) 2014.12.25
[Java] for-each문  (0) 2014.12.23
[Java] 오토박싱  (0) 2014.12.23

[JSP] HTTP 헤더


HTTP 헤더


1. HTTP 헤더


아래 헤더 정보는 텍스트만 있는 HTML 문서에 대한 요청/응답 헤더임.

HTTP Version 1.1을 기준으로 작성된 헤더 정보임.

(클라이언트 환경은 Windows XP, NET Framework 1.1, IE 6.0)


2. 요청 헤더


(1)  GET /test/test.htm HTTP /1.1

요청 Method와 요청 파일 정보, HTTP 버전을 뜻함.

HTTP 프로토콜은 클라이언트가 서버에게 요청하는 방식에 대한 몇 가지 동작을 정의하고 있음.

즉, 요청 Method 란 클라이언트가 서버로의 요청하는 방법을 명시함.


1) GET

지정된 리소스(URI)를 요청함.

 

2) POST

서버가 클라이언트의 폼 입력 필드 데이터의 수락을 요청함.

클라이언트는 서버로 HTTP Body에 Data 를 전송함.

 

3) HEAD

문서의 헤더 정보만 요청함.

응답 데이터(Body)를 받지 않음.


4) PUT

클라이언트가 전송한 데이터를 지정한 URI로 대체함.

cf.) FTP의 PUT과 동일함.

역시 클라이언트는 서버로 HTTP Body에 Data를 전송함.

 

5) DELETE

클라이언트가 지정한 URI 를 서버에서 삭제함.

 

6) TRACE

 클라이언트가 요청한 자원에 도달하기까지의 경로를 기록하는루프백(loop back) 검사용을 말함.

클라이언트가 요청 자원에 도달하기 까지 거쳐가는 프록시나 게이트웨이의 중간 경로부터 최종 수진 서버까지의 경로를 알아낼 때 사용함.

 

(2) Accept

클라이언트가 허용할 수 있는 파일 형식을 뜻함.(MIME TYPE)

*/* 은 특정 유형이 아닌 모든 파일형식을 다 지원한다는 의미임.


(3) User-Agent

클라이언트 소프트웨어(브라우저, OS 등)의 이름과 버전 등을 뜻함.

위의 정보에서는 MS IE 6.0, 윈도우 XP, .NET Framework 1.1 버전이 클라이언트에 설치되어 있음을 나타냄.


(4) Host

요청을 한 서버의 Host 임.


(5) If-Modified-Since

페이지가 수정되었으면 최신 버전 페이지 요청을 위한 필드임.

만일 요청한 파일이 이 필드에 지정된 시간 이후로 변경되지 않았다면, 서버로부터 데이터를 전송 받지 않음.

단, 이 경우 서버로부터 Not Modified (304) 상태코드를 전송 받음.


위의 헤더 정보는 동일한 파일을 재요청했을 때의 응답 헤더임.

파일을 변경사항이 없으므로 304(수정되지 않음)과 Content-Length : 0(데이터 받지 않음) 응답을 받음.

이렇게 함으로써 HTTP 는 요청의 부하를 줄이고 있음.


(6)  Refer

특정 페이지에서 링크를 클릭하여 요청을 하였을 경우에 나타나는 필드로써 링크를 제공한 페이지를 나타냄.

위의 요청 헤더에는 나와 있지 않지만 이 정보도 헤더에 자주 등장하는 필드임.


(7) Cookie

웹 서버가 클라이언트에 쿠키를 저장해 놓았다면 해당 쿠키의 정보를 이름과 값 쌍으로 웹 서버에게 전송함.

역시 위의 요청에는 없지만 자주 등장하는 필드임.


(8) Accept-Language

클라이언트가 인식할 수 있는 언어를 뜻함.

우선 순위 지정이 가능합니다


(9) Accept-Encoding

클라이언트가 인식할 수 있는 인코딩(압축) 방법을 뜻함.

위의 내용에서는 서버에서 gzip, deflate 로 압축한 리소스를 클라이언트가 해석 할 수 있다는 것을 뜻함.

만일 서버에서 압축을 했으면 응답헤더에 Content-Encoding 헤더에 해당 압축 방법이 명시됨.


3. 응답 헤더

(1)  HTTP /1.1 200 OK

HTTP 버전과 응답 코드를 뜻함.

여기서 200 은 성공을 뜻함.


(2) Server

웹 서버 정보를 나타냄.

위의 정보에서는 Microsoft IIS 5.1 을 뜻함.


(3) Date

현재 날짜를 나타냄.


(4) Content-Type

요청한 파일의 MIME 타입을 나타냄.

text/html 은 text 중 html 파일임을 나타냄.


(5) Last-Modified

요청한 파일의 최종 수정일을 나타냄.


(6) Content-Length

헤더 이후 이어지는 데이터의 길이을 뜻함. (바이트 단위)

이어지는 데이터란 요청한 파일의 데이터라 보시면 됨.


(7) ETag

캐쉬 업데이트 정보를 위한 임의의 식별 숫자을 뜻함.


아래에 링크로 가시면 HTTP 1.1 기준의 Header 의 상세 정보를 보실 수 있음.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html


'Programing > JSP/Servlet' 카테고리의 다른 글

[JSP] 커넥션 풀  (2) 2014.12.19
[Servlet] 서블릿 이벤트  (0) 2014.12.18
[Servlet] 서블릿 필터  (0) 2014.12.10
[Servlet] 서블릿 기초  (0) 2014.12.10
[Servlet] 데이터 저장 영역  (0) 2014.12.10

[Java] enum


enum


1. enum

enum은 열거형(enumerated type)이라고 부른다. 열거형은 서로 연관된 상수들의 집합(String과 같은 데이터 타입의 일종)이라고 할 수 있다.(배열은 서로 연관된 값들의 집합) 위의 예제에서는 Fruit와 Company가 말하자면 열거인 셈이다. 이러한 패턴을 자바 1.5부터 문법적으로 지원하기 시작했는데 그것이 열거형이다. 이전 코드를 enum으로 바꿔보자.


enum Fruit{

    APPLE, PEACH, BANANA;

}

//class Fruit{

//    public static final Fruit APPLE  = new Fruit();

//    public static final Fruit PEACH  = new Fruit();

//    public static final Fruit BANANA = new Fruit();

//}--> 위의 코드와 같은 의미


enum Company{

    GOOGLE, APPLE, ORACLE;

}

 

public class ConstantDemo {

     

    public static void main(String[] args) {

        /*

        if(Fruit.APPLE == Company.APPLE){

            System.out.println("과일 애플과 회사 애플이 같다.");

        }

        */

        Fruit type = Fruit.APPLE;

        switch(type){

            case APPLE://Fruit.APPLE로 명시할 시 에러(상수만 적도록 약속)

                System.out.println(57+" kcal");

                break;

            case PEACH:

                System.out.println(34+" kcal");

                break;

            case BANANA:

                System.out.println(93+" kcal");

                break;

        }

    }

}


실행결과)

57 kcal

위의 코드를 하나씩 살펴보자.

enum Fruit{

    APPLE, PEACH, BANANA;

}

enum은 class, interface와 동급의 형식을 가지는 단위다. 하지만 enum은 사실상 class이다. 편의를 위해서 enum만을 위한 문법적 형식을 가지고 있기 때문에 구분하기 위해서 enum이라는 키워드를 사용하는 것이다. 


위의 코드는 아래 코드와 사실상 같다.

class Fruit{

    public static final Fruit APPLE  = new Fruit();

    public static final Fruit PEACH  = new Fruit();

    public static final Fruit BANANA = new Fruit();

    private Fruit(){}

}

생성자의 접근 제어자가 private이다. 그것이 클래스 Fruit를 인스턴스로 만들 수 없다는 것을 의미한다. 다른 용도로 사용하는 것을 금지하고 있는 것이다. 이에 대해서는 뒤에서 다시 설명하겠다. enum은 많은 곳에서 사용하던 디자인 패턴을 언어가 채택해서 문법적인 요소로 단순화시킨 것이라고 할 수 있다.


아래 코드는 컴파일 에러가 발생한다.

/*

if(Fruit.APPLE == Company.APPLE){

    System.out.println("과일 애플과 회사 애플이 같다.");

}

*/

enum이 서로 다른 상수 그룹에 대한 비교를 컴파일 시점에서 차단할 수 있다는 것을 의미한다. 상수 그룹 별로 클래스를 만든 것의 효과를 enum도 갖는다는 것을 알 수 있다.


enum을 사용하는 이유를 정리하면 아래와 같다.

- 코드가 단순해진다.

- 인스턴스 생성과 상속을 방지한다.

- 키워드 enum을 사용하기 때문에 구현의 의도가 열거임을 분명하게 나타낼 수 있다.


2. enum과 생성자

enum은 사실 클래스다. 그렇기 때문에 생성자를 가질 수 있다. 아래와 같이 코드를 수정해보자.


enum Fruit{

    APPLE, PEACH, BANANA;

    Fruit(){

        System.out.println("Call Constructor "+this);//생성자에 대한 정보 출력

    }

}

 

enum Company{

    GOOGLE, APPLE, ORACLE;

}

 

public class ConstantDemo {

     

    public static void main(String[] args) {

        Fruit type = Fruit.APPLE;

        switch(type){

            case APPLE:

                System.out.println(57+" kcal");

                break;

            case PEACH:

                System.out.println(34+" kcal");

                break;

            case BANANA:

                System.out.println(93+" kcal");

                break;

        }

    }

}

실행결과)

Call Constructor APPLE

Call Constructor PEACH

Call Constructor BANANA

57 kcal

Call Constructor가 출력된 것은 생성자 Fruit가 호출되었음을 의미한다. 이것이 3번 호출되었다는 것은 필드의 숫자만큼 호출되었다는 뜻이다. 즉 enum은 생성자를 가질 수 있다.


하지만 코드를 아래와 같이 바꾸면 컴파일 에러가 발생한다.

enum Fruit{

    APPLE, PEACH, BANANA;

    public Fruit(){

        System.out.println("Call Constructor "+this);

    }

}

이것은 enum의 생성자가 접근 제어자 private만을 허용하기 때문이다. 덕분에 Fruit를 직접 생성할 수 없다. 그렇다면 이 생성자의 매개변수를 통해서 필드(APPLE..)의 인스턴스 변수 값을 부여 할 수 있다는 말일까? 있다.


enum Fruit{

    APPLE("red"), PEACH("pink"), BANANA("yellow");

    public String color;

    Fruit(String color){

        System.out.println("Call Constructor "+this);

        this.color = color;

    }

}

 

enum Company{

    GOOGLE, APPLE, ORACLE;

}

 

public class ConstantDemo {

     

    public static void main(String[] args) {

 

        Fruit type = Fruit.APPLE;

        switch(type){

            case APPLE:

                System.out.println(57+" kcal, "+Fruit.APPLE.color);

                break;

            case PEACH:

                System.out.println(34+" kcal"+Fruit.PEACH.color);

                break;

            case BANANA:

                System.out.println(93+" kcal"+Fruit.BANANA.color);

                break;

        }

    }

}

실행결과)

Call Constructor APPLE

Call Constructor PEACH

Call Constructor BANANA

57 kcal, red


아래 코드는 Fruit의 상수를 선언하면서 동시에 생성자를 호출하고 있다.

APPLE("red"), PEACH("pink"), BANANA("yellow");


아래 코드는 생성자다. 생성자의 매개변수로 전달된 값은 this.color를 통해서 5행의 인스턴스 변수의 값으로 할당된다.

Fruit(String color){

    System.out.println("Call Constructor "+this);

    this.color = color;

}


아래처럼 호출하면 APPLE에 할당된 Fruit 인스턴스의 color 필드를 반환하게 된다.

System.out.println(57+" kcal, "+Fruit.APPLE.color);


열거형은 메소드를 가질수도 있다. 아래 코드는 이전 예제와 동일한 결과를 출력한다.

enum Fruit{

    APPLE("red"), PEACH("pink"), BANANA("yellow");

    private String color;

    Fruit(String color){

        System.out.println("Call Constructor "+this);

        this.color = color;

    }

    String getColor(){

        return this.color;

    }

}

 

enum Company{

    GOOGLE, APPLE, ORACLE;

}

 

public class ConstantDemo {

     

    public static void main(String[] args) {

        Fruit type = Fruit.APPLE;

        switch(type){

            case APPLE:

                System.out.println(57+" kcal, "+Fruit.APPLE.getColor());

                break;

            case PEACH:

                System.out.println(34+" kcal"+Fruit.PEACH.getColor());

                break;

            case BANANA:

                System.out.println(93+" kcal"+Fruit.BANANA.getColor());

                break;

        }

    }

}


enum은 맴버 전체를 열거 할 수 있는 기능도 제공한다.

enum Fruit{

    APPLE("red"), PEACH("pink"), BANANA("yellow");

    private String color;

    Fruit(String color){

        System.out.println("Call Constructor "+this);

        this.color = color;

    }

    String getColor(){

        return this.color;

    }

}

 

enum Company{

    GOOGLE, APPLE, ORACLE;

}

 

public class ConstantDemo {

     

    public static void main(String[] args) {

        for(Fruit f : Fruit.values()){

            System.out.println(f+", "+f.getColor());

        }

    }

}

열거형의 특성을 정리해보자. 열거형은 연관된 값들을 저장한다. 또 그 값들이 변경되지 않도록 보장한다. 뿐만 아니라 열거형 자체가 클래스이기 때문에 열거형 내부에 생성자, 필드, 메소드를 가질 수 있어서 단순히 상수가 아니라 더 많은 역할을 할 수 있다.


'Programing > Java' 카테고리의 다른 글

[Java] 예외 만들기  (0) 2014.12.25
[Java] 예외 처리 기본  (0) 2014.12.25
[Java] for-each문  (0) 2014.12.23
[Java] 오토박싱  (0) 2014.12.23
[Java] 익명클래스  (0) 2014.12.23

[JavaScript] 이벤트 타입


이벤트 타입


아래는 onclick 이벤트 타입의 예제다. 이벤트 타입이라는 것은 이벤트의 종류라고 할 수 있다. 사용자 정보가 유효한지 여부를 확인하기 위해 이벤트를 많이 사용한다.

<input type="button" onclick="alert(1);" />

웹브라우저는 많은 종류의 이벤트 타입을 제공한다. 하위 토픽에서는 주요한 이벤트 타입을 중심으로 어떤 이벤트 타입이 있는지 알아보겠다.


1. 폼

폼과 관련된 이벤트 타입을 알아보자.


(1) submit

- submit은 폼의 정보를 서버로 전송하는 명령인 submit시에 일어난다.

- form 태그에 적용된다.

아래 예제는 전송 전에 텍스트 필드에 값이 입력 되었는지를 확인한다. 만약 값이 입력되지 않았다면 전송을 중단한다.

<form id="target" action="result.html">

    <label for="name">name</label> <input id="name" type="name" />

    <input type="submit" />

</form>

<script>

var t = document.getElementById('target');

t.addEventListener('submit', function(event){<!-- 첫번째 인자의 이벤트가 발생하면 두번째 인자인 익명함수가 실행된다. -->

    if(document.getElementById('name').value.length === 0){

        alert('Name 필드의 값이 누락 되었습니다');

        event.preventDefault(); <!-- submit이 안 된다.(action 프로퍼티로 전송되는 것을 방지한다.) 기본 동작의 취소-->

    }

});

</script>


(2) change

- change는 폼 컨트롤(value의 값)의 `값이 변경 되었을 때 발생하는 이벤트다.

- input(text,radio,checkbox), textarea, select 태그에 적용된다.

<p id="result"></p>

<input id="target" type="name" />

<script>

var t = document.getElementById('target');

t.addEventListener('change', function(event){

    document.getElementById('result').innerHTML=event.target.value;

});

</script>


(3) blur, focus

- focus는 엘리먼트에 포커스가 생겼을 때(input의 text 프로퍼티 테두리 내부를 클릭했을때), blur은 포커스가 사라졌을 때 발생(input의 text 프로퍼티 테두리 외부를 클릭했을 때)하는 이벤트다. 

- 다음 태그를 제외한 모든 태그에서 발생한다. <base>, <bdo>, <br>, <head>, <html>, <iframe>, <meta>, <param>, <script>, <style>, <title>

<input id="target" type="name" />

<script>

var t = document.getElementById('target');

t.addEventListener('blur', function(event){

    alert('blur');  

});

t.addEventListener('focus', function(event){

    alert('focus'); 

});

</script>


2. 문서 로딩

자바스크립트를 실행할 때 어떤 타이밍에 실행을 해야지만 문서에 있는 엘리먼트에 정확하게 문제없이 명령을 실행하느냐의 문제가 문서 로딩 part에서 다루는 부분이다.

웹페이지를 프로그래밍적으로 제어하기 위해서는 웹페이지의 모든 요소에 대한 처리가 끝나야 한다. 이것을 알려주는 이벤트가 load, DOMContentLoaded이다.

아래 코드의 실행결과는 null이다. <p id="target">Hello</p>가 로딩되기 전에 자바스크립트가 실행되었기 때문이다.

<html>

    <head>

        <script>

        var t = document.getElementById('target');

        console.log(t);

        </script>

    </head>

    <body>

        <p id="target">Hello</p>

    </body>

</html>

실행결과)

null

- null 인 이유: 자바스크립트를 통해서 id값이 target인 엘리먼트를 찾고 있는 시점에서는 p태그가 만들어져 있지 않기 때문이다.

(존재하지 않는 대상에 대해서 참조하려고 했기 때문에 document.getElementById('target')의 리턴값이 null이다.)


이를 해결하기 위한 방법은 아래와 같이 스크립트를 문서 끝에 위치시키는 것이다.(위에서 아래로 순차적으로 로딩된다.)

<p id="target">Hello</p>

<script>

    var t = document.getElementById('target');

    console.log(t);

</script>


또 다른 방법은 load 이벤트를 이용하는 것이다.

<head>

    <script>

        window.addEventListener('load', function(){

            var t = document.getElementById('target');

            console.log(t);

        })

    </script>

</head>

<body>

    <p id="target">Hello</p>

</body>

그런데 load 이벤트는 문서내의 모든 리소스(이미지, 스크립트)의 다운로드가 끝난 후에 실행(onload: 다운로드 끝날때까지 호출되지 않는다.)된다. 이것을 에플리케이션의 구동이 너무 지연되는 부작용을 초래할 수 있다.

DOMContentLoaded는 문서에서 스크립트 작업을 할 수 있을 때 실행되기 때문에 이미지 다운로드를 기다릴 필요가 없다.

<html>

    <head>

        <script>

            window.addEventListener('load', function(){

                console.log('load');

            })

            window.addEventListener('DOMContentLoaded', function(){<!--DOM에 해당하는 Content가 모두 로드 끝난후 발생하는 이벤트-->

                console.log('DOMContentLoaded');

            })

        </script>

    </head>

    <body>

        <p id="target">Hello</p>

    </body>

</html>

DOMContentLoaded 이벤트는 IE9을 포함한 모든 브라우저에서 지원하고 있다.


3. 마우스


(1) 이벤트 타입

웹브라우저는 마우스와 관련해서 다양한 이벤트 타입을 지원한다.

1) click

클릭했을 때 발생하는 이벤트. 

2) dblclick

더블클릭을 했을 때 발생하는 이벤트

3) mousedown

마우스를 누를 때 발생

4) mouseup

마우스버튼을 땔 때 발생

5) mousemove

마우스를 움직일 때

6) mouseover

마우스가 엘리먼트에 진입할 때 발생

7) mouseout

마우스가 엘리먼트에서 빠져나갈 때 발생

8) contextmenu

컨텍스트 메뉴가 실행될 때 발생


(2) 키보드 조합

마우스 이벤트가 호출될 때 특수키(alt, ctrl, shift)가 눌려진 상태를 감지해야 한다면 이벤트 객체의 프로퍼티를 사용한다. 이 때 사용하는 프로퍼티는 아래와 같다.

- event.shiftKey

- event.altKey

- event.ctrlKey


(3)  마우스 포인터 위치

마우스 이벤트와 관련한 작업에서는 마우스 포인터의 위치를 알아내는 것이 중요할 때가 있는데 이런 경우 이벤트 객체의 clientX와 clientY를 사용한다.


(4) 예제

아래 예제는 지금까지 살펴본 이벤트와 관련된 기능을 종합적으로 보여준다. 

<html>

    <head>

        <style>

            body{

                background-color: black;

                color:white;

            }

            #target{

                width:200px;

                height:200px;

                background-color: green;

                margin:10px;

            }

            table{

                border-collapse: collapse;

                margin:10px;

                float: left;

                width:200px;

            }

            td, th{

                padding:10px;

                border:1px solid gray;

            }

        </style>

    </head>

    <body>

        <div id="target">

 

        </div>

        <table>

            <tr>

                <th>event type</th>

                <th>info</th>

            </tr>

            <tr>

                <td>click</td>

                <td id="elmclick"></td>

            </tr> 

            <tr>

                <td>dblclick</td>

                <td id="elmdblclick"></td>

            </tr>

            <tr>

                <td>mousedown</td>

                <td id="elmmousedown"></td>

            </tr>         

            <tr>

                <td>mouseup</td>

                <td id="elmmouseup"></td>

            </tr>         

            <tr>

                <td>mousemove</td>

                <td id="elmmousemove"></td>

            </tr>         

            <tr>

                <td>mouseover</td>

                <td id="elmmouseover"></td>

            </tr>         

            <tr>

                <td>mouseout</td>

                <td id="elmmouseout"></td>

            </tr>

            <tr>

                <td>contextmenu</td>

                <td id="elmcontextmenu"></td>

            </tr>         

        </table>

        <table>

            <tr>

                <th>key</th>

                <th>info</th>

            </tr>

            <tr>

                <td>event.altKey</td>

                <td id="elmaltkey"></td>

            </tr>

            <tr>

                <td>event.ctrlKey</td>

                <td id="elmctrlkey"></td>

            </tr>

            <tr>

                <td>event.shiftKey</td>

                <td id="elmshiftKey"></td>

            </tr>

        </table>

        <table>

            <tr>

                <th>position</th>

                <th>info</th>

            </tr>

            <tr>

                <td>event.clientX</td>

                <td id="elemclientx"></td>

            </tr>

            <tr>

                <td>event.clientY</td>

                <td id="elemclienty"></td>

            </tr>

        </table>

        <script>

        var t = document.getElementById('target');

        function handler(event){

            var info = document.getElementById('elm'+event.type);<!--type프로퍼티로 이벤트 종류를 알 수 있다.-->

            var time = new Date();

            var timestr = time.getMilliseconds();<!--500이면 0.5초 -->

            info.innerHTML = (timestr);

            if(event.altKey){

                document.getElementById('elmaltkey').innerHTML = timestr;

            }

            if(event.ctrlKey){

                document.getElementById('elmctrlkey').innerHTML = timestr;

            }

            if(event.shiftKey){

                document.getElementById('elmshiftKey').innerHTML = timestr;

            }

            document.getElementById('elemclientx').innerHTML = event.clientX;

            document.getElementById('elemclienty').innerHTML = event.clientY;

        }

        t.addEventListener('click', handler);

        t.addEventListener('dblclick', handler);

        t.addEventListener('mousedown', handler);

        t.addEventListener('mouseup', handler);

        t.addEventListener('mousemove', handler);

        t.addEventListener('mouseover', handler);

        t.addEventListener('mouseout', handler);

        t.addEventListener('contextmenu', handler);

        </script>

    </body>

</html>


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 이벤트 등록방법  (0) 2014.12.25
[JavaScript] 이벤트  (0) 2014.12.25
[JavaScript] Text 객체  (0) 2014.12.23
[JavaScript] Document 객체  (0) 2014.12.23
[JavaScript] Node 객체  (1) 2014.12.23