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

 - contentType  속성 : JSP파일 출력시 문자코드 및 Content-Type 헤더에 

                                출력할 문자코드명을 지정 


  - pageEncoding 속성 : JSP파일 작성시의 문자코드를 지정 

자바가상머신(JVM)의 내부에서는 모든 문자열이 Unicode로 표현된다. 
그러므로 서블릿 콘테너는 JSP파일을 JVM에 읽어들일 때 JSP파일의 
문자코드(예를들어 EUC-KR)에서 Unicode로 변환한다. 
그리고 웹브라우저에 HTML문서를 출력할 때는 Unicode로부터 출력파일의 
문자코드로 변환한다. 

  

■ contentType 속성의 역할 


contentType 속성은 "JSP파일 출력시의 문자코드", "Content-Type 헤더에 
지정할 문자코드"의 양쪽을 지정하는 기능을 갖는다. 
상기 코드와 같이 기술하면 서블릿 콘테너는 콘텐츠를 EUC-KR로 
Encode하여 출력한다. 
또한 동시에 Content-Type 헤더를 통하여 문자코드 종류를 웹브라우저에 
전달한다. 

  

■ pageEncoding 속성의 역할 


pageEncoding 속성은 "JSP파일 작성시의 문자코드"를 지정하기 위한 
속성으로서 JSP 1.2사양(Tomcat 4.0) 이후부터 지원된다. 
예를들어, 윈도우즈에서 작성한 JSP파일이면 EUC-KR를 지정하면 된다. 
UNIX의 일본어 에디터로 작성한 것이라면 EUC-JP를 지정하면 바르게 처리될 
것이다. 

pageEncoding 속성을 생략한 경우, JSP 1.2 사양에서는 
"contentType 속성에서 지정된 문자코드로 JSP파일을 읽어들임" 
이라고 규정되어 있다. 
그러므로 보통은 생략해도 문자깨짐이 발생할 염려는 없다. 
그렇지만 EUC-KR -> Unicode -> EUC-KR 의 문자코드 변환은 
기억해 둬야 한다. 
또한 include 된 JSP파일에서는 contentType 속성을 기술할 수 없으므로 
pageEncoding 속성을 이용할 필요가 있다. 
이 문제에 대해서는 다음회에 설명할 예정이다. 
덧붙여, contentType 속성과 pageEncoding 속성에는 각기 다른 문자코드를 
지정할 수도 있다. 
예를들어 ShiftJIS로 작성한 JSP파일을 EUC-JP,UTF-8등으로 출력하는 것도 
가능하다.

'Development > JSP & Servlet' 카테고리의 다른 글

jsp - *.jsp를 WEB-INF 아래에 숨겨라  (0) 2012.03.23
request.setCharacterEncoding  (0) 2012.03.23
JSP  (0) 2012.02.05
서블릿 Invoker  (0) 2011.12.29
JSP와 HTTP 주석  (0) 2010.12.12
Posted by linuxism
,

프로그램에서 단 하나의 인스턴스(Instance)만 존재하게 하고 싶을 때 사용하는 패턴입니다.
어디서든지 그 인스턴스에 접근할 수 있기 때문에 전역 변수 등을 관리할 때 상당히 편리합니다.


싱글톤 패턴의 간단한 예는 다음과 같습니다. (다만, 아래의 코드는 멀티 쓰레드 환경에서 문제가 발생합니다.)

01.public class MyClass
02.{
03.private static MyClass m_MyClass = null;
04. 
05.private MyClass() {}
06. 
07.public static MyClass getInstance()
08.{
09.if (m_MyClass == null)
10.{
11.m_MyClass = new MyClass();
12.}
13. 
14.return m_MyClass;
15.}
16.}
위와 같은 경우는 멀티 쓰레드(Multi-Thread) 환경에서는 getInstace() 메소드가 끝나기 전에
각각의 쓰레드에서 접근이 가능하기 때문에 운이 없으면 인스턴스가 여러 개 생성될 수도 있습니다.


이 경우 해결 방법은 getInstance() 메소드를 synchronized로 동기화시키는 방법이 있습니다.
01.public static synchronized MyClass getInstance()
02.{
03.if (m_MyClass == null)
04.{
05.m_MyClass = new MyClass();
06.}
07. 
08.return m_MyClass;
09.}
하지만, 함수 전체에 synchronized는 동기화 과정에서 속도 문제가 발생할 수 있습니다.


좀 더 효과적으로 하려면 함수 전체에 synchronized를 거는 것이 아니라 함수 내부의 특정 구간에만 거는 방법입니다.
01.public static MyClass getInstance()
02.{
03.if (m_MyClass == null)
04.{
05.synchronized(MyClass.class)
06.{
07.if (m_MyClass == null)
08.{
09.m_MyClass = new MyClass();
10.}
11.}
12.}
13. 
14.return m_MyClass;
15.}


그리고 코드를 좀 더 깔끔하고 쉽게 가져가기 위해서는
 아예 처음부터 인스턴스를 생성해버리는 방법입니다.
01.public class MyClass
02.{
03.private static MyClass m_MyClass = new MyClass();
04. 
05.private MyClass() {}
06. 
07.public static MyClass getInstance()
08.{
09.return m_MyClass;
10.}
11.}
이 경우는 프로그램이 처음 실행되면서 바로 인스턴스가 생겨버리기 때문에 불필요한 부분에서 인스턴스가
메모리를 차지해버린다는 단점이 있지만, 멀티 쓰레드 동기화 문제에서 자유로울 수 있고 코드가 간결해진다는
장점이 있습니다. 

그리고 어차피 한 번은 메모리에 올라갈 인스턴스이기 때문에 미리 메모리에 실어 놓는 것도 나쁘지는 않겠죠. ^^; 

출처 - http://snowbora.com/442


=======================================================================


Singleton Pattern - 디자인 패턴

패턴 정의 #6 - Singleton Pattern

1. synchronized 키워드를 사용한다.

  1. public class Singleton {  
  2.     private static Singleton uniqueInstance;  
  3.    
  4.     // other useful instance variables here  
  5.    
  6.     private Singleton() {}  
  7.    
  8.     public static synchronized Singleton getInstance() {  
  9.         if (uniqueInstance == null) {  
  10.             uniqueInstance = new Singleton();  
  11.         }  
  12.         return uniqueInstance;  
  13.     }  
  14.    
  15.     // other useful methods here  
  16. }  

2. 인스턴스를 필요할 때 생성하지 말고, 처음부터 만들어 버린다.

  1. public class Singleton {  
  2.     private static Singleton uniqueInstance = new Singleton();  
  3.    
  4.     private Singleton() {}  
  5.    
  6.     public static Singleton getInstance() {  
  7.         return uniqueInstance;  
  8.     }  
  9. }  

3. DCL(Double Checking Locking)을 써서 getInstance()에서 동기화 되는 부분에 대한 체크를 줄입니다.

  1. public class Singleton {  
  2.     private volatile static Singleton uniqueInstance;  
  3.    
  4.     private Singleton() {}  
  5.    
  6.     public static Singleton getInstance() {  
  7.         if (uniqueInstance == null) {  
  8.             synchronized (Singleton.class) {  
  9.                 if (uniqueInstance == null) {  
  10.                     uniqueInstance = new Singleton();  
  11.                 }  
  12.             }  
  13.         }  
  14.         return uniqueInstance;  
  15.     }  
  16. }  

I. Singleton 이란?

아마 GOF의 32가지 패턴 중 가장 쉬우면서도 가장 자주 쓰이게 되며, 가장 문제가 될 소지를 가지는 패턴을 말하면 Singleton을 말할 수 있지 않을까 합니다.

먼저 Singleton 패턴의 용도는 하나의 프로그램 내에서 하나의 인스턴스만을 생성해야만 하는 상황. 예를 들어 환경설정을 관리하는 클래스나
Connection Pool, Thread Pool과 같이 풀(Pool) 형태로 관리되는 클래스의 경우 프로그램 내에서 단 하나의 인스턴스로 관리되는 것이 일반적이며, 이 때 Singleton 패턴을 적용하는 것이 일반적인 경우라고 볼수 있겠습니다. 그럼 세부적인 구현 형태를 살펴 보도록 하겠습니다.

II. Singleton 구현

Singleton 패턴의 가장 일반적인 형태는 다음과 같습니다.

singleton.bmp 

<일반적인 Singleton class diagram>

중요하게 보아야 할 곳은 생성자가 private으로 선언되어 있다는 것이죠. 이유는 간단하게도 클래스 외부에서 이 클래스를 직접 new 키워드로 생성하지 못하게 막겠다는 의미가 되겠습니다. Singleton 패턴은 설명보다는 코드로 보는 것이 훨씬 간결하므로 다음 코드를 보도록 하겠습니다.

  1. Singleton 패턴 

  2. class Singleton { 

  3. private static Singleton instance;

  4. private Singleton(){ 

  5. public static Singleton getInstance(){ 

  6. if (instance == null) 

  7. instance = new Singleton();  

  8. return instance; 

  9. }

 

   위 코드에서 파란색으로 표기된 선언부에 집중해야 합니다. Singleton 클래스의 인스턴스를 외부에서 사용하기 위해서는 항상 getInstance 메소드를 호출해야만 하도록 강제된 것을 확인하실 수 있습니다.  위와 같은 경우 getInstance가 호출될 때 객체가 생성되는데 최초 로딩 시에 객체를 생성해 두는 것이 효율적인 경우에는 다음과 같이 멤버 변수를 선언하는 곳에서 직접 생성하는 방법을 이용할 수 있습니다.

 

  1. ClassLoader에 의해 미리 인스턴스를 생성하는 방법 
  2. class Singleton { 
  3. private static Singleton instance = new Singleton(); 
  4. private Singleton(){} 
  5. public static Singleton getInstance(){ 
  6. if (instance == null) 
  7. instance = new Singleton(); 
  8. return instance; 

위의 코드에서 붉은색으로 표기된 멤버 변수 선언부를 보면 new 키워드에 의해 static으로 선언된 멤버 변수의 인스턴스를 미리 생성하는 것을 볼 수 있습니다.

다중 쓰레드 프로그래밍에 필요한 것이 아니라면 위의 코드만으로도 완성된 코드라고 볼수 있겠습니다. 미리 인스턴스를 생성할 필요가 없는 경우에는 이전의 방법을 이용하는데 그런한 방식을 lazy(게으른) 방식이라고 이야기 합니다.

다중 쓰레드 프로그래밍에서는 동기화를 이용한 적절한 수정이 필요한데 많은 커뮤니티에서 그에 따른 예제 코드가 잘 나와있습니다.

(Singleton의 다양한 형태 : http://www.anfamily.net/mcsong/70)

위의 블로그에 방문하시면 싱글톤 패턴의 다양한 종류와 그에 따른 장단점이 잘 분류되어 있습니다.

다만 좀더 자세히 내용을 들여다 보면 가장 간단한 방법이 오히려 득이 되는 경우를 찾을 수 있을 것 입니다. 다음 코드를 봐주세요.

  1. Instance의 생성은 단 한번만

  2. class Singleton{

  3. private static Singleton instance = new Singleton();

  4. private Singleton(){}

  5. public static Singleton getInstance(){

  6. return instance;

  7. }

  8. }

위의 코드의 녹색으로 표시된 부분을 봐주세요. Simple is best 라는 말 처럼 위의 코드는 Thread-safe하게 잘 만들어진 코드라고 할 수 있겠습니다.

이 클래스는 전체 라이프 타임 중에서 단 한번만 객체를 생성하고 다시는 생성하지 않습니다. 여러개의 쓰레드가 접근을 한다고 하더라도 인스턴스가 두개 이상 생성되거나 Null값을 리턴 받을 염려도 생성자가 두번 호출 되는 경우도 없죠. 

 

III. 결론

하나의 패턴은 다양한 형태로 표현되는 경우가 많습니다. 어쩔 때는 경계가 모호한 형태로 패턴이 구현되는 경우도 있지요.

이번 싱글톤 패턴은 목적과 형태가 분명한 패턴으로 항상 머리에 넣어두고 사용해야할 중요한 패턴이라고 말할 수 있습니다.

 

참고문헌


출처 -  http://sakula99.egloos.com/2971297 
 

===================================================================================


싱글톤(Singleton) Pattern 이란?



객체지향형언어(OOP)에 대해 조금이라도 파고든 사람이라면 싱글톤 패턴이라는 

말을 들어봤을 것이다. 못들어봤다면 이제부터 들었다고 해라. 싱글톤이란 생성하고자 

하는 인스턴스의 수를 오직 하나로 제한하는 디자인 패턴이다.



그렇다면 왜 싱글톤 패턴을 사용해야하는 것일까? 라는 질문에 대게 답하는 것이

여러개의 인스턴스를 생성하게 되면 가끔 프로그래머도 당혹스럽게 되는 서로의

인스턴스에 간섭을 하는 경우가 있다. 정말 재수 없는 일이 아닐 수가 없다.





public class Singleton

{

private static Singleton singleton = new Singleton();

protected Singleton()

{

System.out.println("Maked Singleton");

}

public static Singleton getInstance()

{

return singleton;

}

}



싱글톤의 기본형이다. singleton 멤버변수는 static 이어야한다는 것과 Singleton 클래스의

생성자는 private / protected 이어야한다는 것을 꼭 유념해야한다. private 일 경우는 결코

new 를 이용하여 인스턴스의 중복 생성을 방지하는 셈이기도 하나 상속이 되지 않는다는

단점이 있어 protected로 대게 선언한다.



뭐~ 싱글톤 패턴이 만들어졌나 아닌가 확인할 것이라면 Test 클래스를 만들어보자.



public class Test

{

public static void main(String [] args)

{

System.out.println("Singleton pattern");

Singleton sg1=Singleton.getInstance();

Singleton sg2=Singleton.getInstance();

if( sg1 == sg2 )

{

System.out.println("Equal");

}

else

{

System.out.println("Not Equal");

}

}

}



여기서 보면 Singleton 의 인스턴스를 생성하기 위해 getInstance() 메소드를 이용한다.

왜 그럴까? Singleton 클래스의 private static Singleton singleton = new Singleton(); 

부분을 유심히 바라보기 바란다. 이 singleton은 static으로 선언된다. 즉 하나의 인스턴스

singleton 만 생성하는 셈이다. 아마 결과도 Equal로 출력될 것이다.


출처 - http://coolx.net/cboard/read.jsp?db=develop&mode=read&num=261







singleton 이란?

프로그래밍 세계에 OOP 의 개념이 생기면서 객체 자체에 대한 많은 연구와 패턴(pattern)들이 생겨났다. singleton pattern은 인스턴스가 사용될 때에 똑같은 인스턴스를 만들어 내는 것이 아니라, 동일 인스턴스를 사용하게끔 하는 것이 기본 전략이다. 프로그램상에서 동일한 커넥션 객체를 만든다던지, 하나만 사용되야하는 객체를 만들때 매우 유용하다. singleton pattern은 4대 디자인 패턴에 들어갈 정도로 흔히 쓰이는 패턴이다. 물론 core java(java.lang.Runtime, java.awt.Desktop 등등)에서도 singleton pattern이 사용된다.

Eager initialization

아래가 가장 기본적인 singleton pattern이다. 전역 변수로 instance를 만드는데 private static을 이용한다. static이 붙은 클래스변수는 인스턴스화에 상관없이 사용이 가능하게 된다. 하지만 앞의 private 접근제어자로 인해EagerInitialization.instance로의 접근은 불가능하다. 이런 상태에서 생성자를 private로 명시한다. 생성자를private로 붙이게되면, new 키워드를 사용할 수 없게된다. 즉 다른 클래스에서 EagerInitialization instance = new EagerInitialization(); 이런 방법을 통한 인스턴스 생성은 불가능해진다. 결국 외부 클래스가 EagerInitialization 클래스의 인스턴스를 가질 수 있는 방법은 11번째 라인에 있는 getInstance() method를 사용하는 수 밖에 없다.

public class EagerInitialization {
	// private static 로 선언.
	private static EagerInitialization instance = new EagerInitialization();
	// 생성자
	private EagerInitialization () {
		System.out.println( "call EagerInitialization constructor." );
	}
	// 조회 method
	public static EagerInitialization getInstance () {
		return instance;
	}
	
	public void print () {
		System.out.println("It's print() method in EagerInitialization instance.");
		System.out.println("instance hashCode > " + instance.hashCode());
	}
}

위의 단순한 singleton pattern은 리소스가 작은 프로그램일때엔 고도화 대상이 아니다. 하지만 프로그램의 크기가 커져서 수 많은 클래스에서 위와 같은 singleton pattern을 사용한다고 가정해보자. 3번째 라인의 new EagerInitialization();으로 인해 클래스가 load 되는 시점에 인스턴스를 생성시키는데 이마저도 부담스러울 수가 있다. 또한 이 소스는 EagerInitialization 클래스가 인스턴스화 되는 시점에 어떠한 에러처리도 할 수가 없다.

static block initialization

public class StaticBlockInitalization {
	private static StaticBlockInitalization instance;
	private StaticBlockInitalization () {}
	
	static {
		try {
			System.out.println("instance create..");
			instance = new StaticBlockInitalization();
		} catch (Exception e) {
			throw new RuntimeException("Exception creating StaticBlockInitalization instance.");
		}
	}
	
	public static StaticBlockInitalization getInstance () {
		return instance;
	}
	
	public void print () {
		System.out.println("It's print() method in StaticBlockInitalization instance.");
		System.out.println("instance hashCode > " + instance.hashCode());
	}
	
}

static 초기화블럭을 이용하면 클래스가 로딩 될 때 최초 한번 실행하게 된다. 특히나 초기화블럭을 이용하면 logic을 담을 수 있기 때문에 복잡한 초기변수 셋팅이나 위와 같이 에러처리를 위한 구문을 담을 수 있다. 첫 번째 패턴보다 좋아보이지만 인스턴스가 사용되는 시점에 생성되는 것은 아니다.

lazy initialization

이제 클래스 인스턴스가 사용되는 시점에 인스턴스를 만드는 singleton pattern을 배워보도록 하자. 아래 소스의 lazy initialization pattern은 필요할때 인스턴스를 생성시키는 것이 핵심이다.

public class LazyInitialization {
	
	private static LazyInitialization instance;
	private LazyInitialization () {}
	
	public static LazyInitialization getInstance () {
		if ( instance == null )
			instance = new LazyInitialization();
		return instance;
	}
	
	public void print () {
		System.out.println("It's print() method in LazyInitialization instance.");
		System.out.println("instance hashCode > " + instance.hashCode());
	}
}

new LazyInitialization(); 가 어디에 선언되었는지 주목해보자. getInstance() method 안에서 사용되었다. if문을 이용해 instance가 null 인 경우에만 new를 사용해 객체를 생성하였다. 최초 사용시점에만 인스턴스화 시키기 때문에 프로그램이 메모리에 적재되는 시점에 부담이 많이 줄게된다. 하지만 여전히 문제는 남아있다. 만약 프로그램이 muilti thread 방식이라면 위와 같은 singleton pattern은 안전하지 않다. 동일 시점에 getInstance() method를 호출하면 인스턴스가 두번 생길 위험이 있다.

thread safe initalization

위에서 문제가 되었던 muilit thread문제를 해결하기 위해 synchronized(동기화)를 사용하여 singleton pattern을 구현한다. 여러 thread들이 동시에 접근해서 인스턴스를 생성시키는 위험은 없어졌다. 하지만 수 많은 thread 들이 getInstance()method 를 호출하게 되면 높은 cost 비용으로 인해 프로그램 전반에 성능저하가 일어난다.

public class ThreadSafeInitalization {
	
	private static ThreadSafeInitalization instance;
	private ThreadSafeInitalization () {}
	
	public static synchronized ThreadSafeInitalization getInstance () {
		if (instance == null)
			instance = new ThreadSafeInitalization();
		return instance;
	}
	
	public void print () {
		System.out.println("It's print() method in ThreadSafeInitalization instance.");
		System.out.println("instance hashCode > " + instance.hashCode());
	}
	
}

initialization on demand holder idiom

미국 메릴랜드 대학의 컴퓨터 과학 연구원인 Bill pugh 가 기존의 java singleton pattern이 가지고 있는 문제들을 해결 하기 위해 새로운 singleton pattern을 제시하였다. Initialization on demand holder idiom기법이다. 이것은 jvm 의 class loader의 매커니즘과 class의 load 시점을 이용하여 내부 class를 생성시킴으로 thread 간의 동기화 문제를 해결한다.

public class InitializationOnDemandHolderIdiom {
	
	private InitializationOnDemandHolderIdiom () {}
	private static class Singleton {
		private static final InitializationOnDemandHolderIdiom instance = new InitializationOnDemandHolderIdiom();
	}
	
	public static InitializationOnDemandHolderIdiom getInstance () {
		System.out.println("create instance");
		return Singleton.instance;
	}
}

initialization on demand holder idiom 역시 lazy initialization이 가능하며 모든 java 버젼과, jvm에서 사용이 가능하다. 현재 java 에서 singleton 을 생성시킨다고 하면 거의 위의 방법을 사용한다고 보면 된다.

enum initialization

Joshua Bloch가 작성한 effective java 책에서 enum singleton 방법이 소개 되었다.

public enum EnumInitialization {
	INSTANCE;
	static String test = "";
	public static EnumInitialization getInstance() {
		test = "test";
		return INSTANCE;
	}
}

enum 이 singleton pattern 으로 사용될 수 있는 이유는 아래와 같다.

  • INSTANCE 가 생성될 때, multi thread 로 부터 안전하다. (추가된 methed 들은 safed 하지 않을 수도 있다.)
  • 단 한번의 인스턴스 생성을 보장한다.
  • 사용이 간편하다.
  • enum value는 자바 프로그램 전역에서 접근이 가능하다.

using reflection to destroy singleton

위에서 여러 방법으로 singleton을 만들어 보았으니 이번엔 java의 reflection을 이용하여 singleton을 깨뜨려 보는법도 배워보자. 누군가 작성한 코드를 원본 수정없이 작업해야 할때 이용될 수 있을 것이다.

public class UsingReflectionToDestroySingleton {
	
	public static void main (String[] args) {
		EagerInitialization instance = EagerInitialization.getInstance();
		EagerInitialization instance2 = null;
		
		try {
			Constructor[] constructors = EagerInitialization.class.getDeclaredConstructors();
			for ( Constructor constructor : constructors ) {
				constructor.setAccessible(true);
				instance2 = (EagerInitialization)constructor.newInstance();
			}
		} catch (Exception e) {
			
		}
		
		System.out.println(instance.hashCode());
		System.out.println(instance2.hashCode());
		
	}
}

위의 코드를 실행해보면 아래 System.out.println();의 두 라인에서 찍히는 hachCode()값이 다른 것을 확인 할 수 있다. java의 reflection은 매우 강력하다. 설령 class 의 생성자가 private 일지라도 강제로 가져와서 새로운 인스턴스 생성이 가능하다. 결국 singleton pattern을 깨뜨리는 것이다. 이 외에도 reflection을 여러곳에서 사용할 수 있으니 알아두는 것이 좋다.



출처 - https://blog.seotory.com/post/2016/03/java-singleton-pattern







Posted by linuxism
,


meta 요소

정의

metadata; meta 요소는 title 요소나 base 요소link 요소style 요소script 요소로 표현할 수 없는 다양한 메타데이터를 표시합니다. 내장 스크립트와 CSS 정보, 스크립트와 CSS 파일 링크 정보뿐만 아니라 검색 엔진을 위한 해당 문서의 검색 키워드 정보도 담을 수 있습니다.

이 요소는 메타데이터에 속합니다.

마크업 규칙

FlowInteractiveMetadataPhrasingEmbeddedHeadingSectioning

기본 문법은 다음과 같습니다.

  1. <head>
  2. <meta charset="utf-8">
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4. <meta name="author" content="honggil-dong">
  5. </head>

속성

속성명설명
전역 속성공통 속성
name문서의 메타데이터를 설정합니다.
http-equiv전처리구문 지시자입니다.
contentname 속성이나 http-equiv 속성을 썼을 때. 이 속성의 의미는 때에 따라 다릅니다.
charset문서에서 사용하는 문자 인코딩 방식을 명시합니다. XML문서에서는 반드시 UTF-8을 써야 합니다.

메모

HTML4/XHTML1과의 차이점, 접근성, 보충 내용 그리고 편집자 의견 등을 포함하고 있습니다.

참조

기준 명세를 바탕으로 명세 번역과 레퍼런스 제작이 이루어졌습니다. 최근 내용은 최신 명세를 확인해 주세요.

관련 요소

출처 - http://html5ref.clearboth.org/doku.php?id=html5:element:meta

==================================================================================


메타 태그(Meta Tag)란?

이름에서 짐작할 수 있듯 (x)html 태그 중 하나이고 '메타', 즉, 문서 그 자체를 설명하는 태그를 메타 태그라 합니다. 일반 (x)html 태그는 문서 내용물을 어떻게 보이게 하는가를 규정하기 위해 마크 업을 합니다. 이와 달리 메타 태그는 (x)html 문서가 어떤 내용을 담고 있고, 그 문서의 핵심어는 무엇이며, 누가 만들었는지, 문자 세트는 어떤 것을 사용하는지 등의 메타 정보를 담고 있습니다.

메타 태그는,

  1. "empty tag" 중의 하나입니다. <b>볼드체</b>처럼 열고 닫는 태그가 다 있는것이 아니라 닫는 태그는 없습니다. 즉,</meta>라는 태그는 없습니다. 그러므로 xhtml의 경우 <meta ... />처럼 자체 내에서 /로 닫으면서 마무리되어야 합니다.
  2. 반드시 <head>~</head> 사이에 놓입니다.

메타 태그의 형태

메타 태그는,

<meta 속성="값" content="내용물" />

의 형태를 갖습니다.

예를 들면,

  • <meta name="author" content="이명헌" />
  • <meta name="title" content="메타 태그란?" />
  • <meta http-equiv="refresh" content="5;url=http://www.abc.com/" />

"속성 = 값", 그리고 "content = 내용물"입니다. 자주 들르는 웹 페이지의 '소스 보기'를 해보면 문서 서두에 있는 메타 태그를 확인해 볼 수 있습니다. 지금 이 페이지를 확인해 볼 수도 있습니다.

메타 태그의 용도

기본적으로 (x)html 문서를 만들 때는 항상 메타 태그를 써주는 것이 좋습니다. 그 문서가 어떤 내용을 담고 있는지, 키워드는 무엇인지를 요약해 둔 내용이 있다면 검색을 하는 데 많은 도움이 되기 때문입니다. 대개 다음의 용도로 많이 쓰입니다.

검색 엔진에 등록할 때


<meta name="keywords" content="코미디 역사 코메디 발생 기원 희극" />
<meta name="description" content="코미디의 역사를 소개하는 글" />

예를 들어, 코미디의 역사를 소개하는 웹페이지라면 위와 같이 그 문서의 키워드인 '코미디', '역사' 같은 단어를 "keywords" 메타 태그에 담고 '코미디의 역사를 소개하는 글'이라는 (x)html 문서 소개를 "description" 메타 태그에 담습니다. 이들 메타 태그를 그 (x)html 문서의 <head>~</head> 사이에 넣어 두는 것입니다. 검색 엔진이 웹 문서를 검색할 때 이들 "keywords", "description" 메타 태그를 통해 검색하는 경우가 있기 때문입니다. 검색엔진에서 검색어를 입력하고 엔터를 치면 검색엔진은 입력한 검색어와 같은 단어가 keywordsdescription 메타 태그 내에 등장하는 문서를 찾아내서 검색 결과를 통해 보여줍니다.

성인물을 다루는 사이트의 경우 메타 태그를 남용해서 keywords에 sex 관련 단어를 많이 넣어 두기도 합니다. 그렇게 하면 sex 관련 단어 검색 시 자신의 페이지가 결과로 뜰 것이라고 믿기 때문입니다. 하지만 이제는 이런 용도의 메타 테그 활용은 거의 의미가 없습니다. 메타 태그를 상업적으로 '악용'한 페이지가 너무 많아서 제대로 된 검색 결과를 얻지 못한다는 점을 깨달은 검색엔진 회사들이(특히 구글처럼 링크 구조(Link structure) 기반의 자동화된 검색엔진) 메타 태그를 거의 무시하고 있기 때문입니다.

그런 한계에도 불구하고 메타 태그가 없는 것보다는 있는 쪽이 검색에 더 도움이 되므로 적절히 사용하는 것이 좋습니다. 이런 점은 주의해야 합니다. description 메타 태그 내에 페이지 요약을 넣을 때 가급적 20단어를 넘지 않아야 합니다. 검색 엔진은description을 적당한 크기까지만 읽고 나머지는 임의로 무시합니다. 그리고, 검색 엔진은 메타 태그와 함께 웹 페이지의 제목(<title>에 담긴) 역시 중요하게 취급합니다. (x)html 문서 제목을 결정할 때 가급적 신중하게 하세요. URL도 마찬가지입니다. 한글 싸이트와 직접적 연관은 없긴 하지만 keywords 메타 태그의 경우 대소문자를 별개로 취급하기 때문에 구분해서 실을수록 좋습니다.

검색 엔진 피하기

검색엔진 회사가 사용하는 웹 크롤러(Web crawler)는 웹 상의 여러 문서들을 긁어서 문서를 적당한 형태로 저장합니다. 이 때keywords와 description 등이나 문서 길이, url, 제목 등의 메타 정보를 따로 관리하며 저장하지만 (x)html 문서 자체도 모두 긁어서 저장합니다.

일반적인 램보다 속도가 훨씬 빠른 캐쉬 메모리(cache memory)가 자주 하는 작업을 저장하고 있다가 cpu에서 요청이 오면 즉각 보내서 컴퓨터 작업 속도를 늘려주는 것처럼, 웹 크롤러가 긁어 온 웹 페이지 내용 역시 검색엔진의 모처에 캐쉬 형태로 저장해서 매 검색 시마다 웹 전체를 뒤지지 않고 저장된 캐쉬를 검색해서 빠른 속도로 검색 결과를 보여줍니다.(구글의 '캐쉬'가 그것입니다.) 검색엔진 회사는 이렇게 웹 페이지를 긁어 오는 작업을 정기적으로 하고 있으며 크롤링을 자주 하는 곳일수록 캐쉬 내에 최근 내용이 저장되어 있으므로 보다 최신의 검색결과를 보여줍니다.

문제는 웹에 이런 웹 크롤러(web crawler)들이 아주 많이 떠돌아 다니고 있어서 외부에 노출하고 싶지 않은 문서까지 공개되고 심지어 저장될 수 있다는 사실입니다. 그것을 해결하는 것이 robots라는 메타 태그입니다.

<meta name="robots" content="noindex, nofollow" />

name= 자리에 robots가 들어가 있고 content에는 noindexnofollow라고 되어 있습니다. 이것에 대해 자세하게 알아 보기 전에 웹 크롤러가 어떻게 동작하는지 간단하게 알아 봅시다. 웹 크롤러가 최초 웹 서버에 도착하면 그 웹 서버 문서 디렉토리의 최상위(/)에 "robots.txt" 라는 문서가 있는지 점검 합니다. 만약 robots.txt라는 문서가 있고, 그 문서 안에


User-agent: *
Disallow: /

라는 내용이 담겨 있다면 /(문서 루트 디렉토리) 밑으로는 disallow, 즉, 허락하지 않는 것이므로 그 사이트의 문서를 긁지 않고 떠납니다.

그런데 이것은 실용성이 떨어집니다. 감추고 싶은 문서도 있긴 하지만 검색 엔진에 올려 두고 싶은 문서가 훨씬 더 많을 수 있으니까요. 제일 상위인 / 디렉토리에서 웹 크롤러를 차단하는 것은 사이트 전체를 건너 뛰게 하므로 실용성이 없습니다. 또 하나 문제가 되는 것은 독립적인 웹 서버를 사용하지 않고 웹호스팅 서비스나 계정을 사용하고 있는 경우 "Document Root"에 robots.txt 문서를 넣어두기는 힘들다는 점입니다.

그럴 때 사용하는 것이 robots 메타 태그입니다. robots 메타 태그는 웹크롤러가 긁어갈 것인지 말 것인지를 개별 문서 별로 설정할 수 있습니다. 사용법은 간단합니다. robots 메타 태그의 content가 index이면 그 페이지는 긁어 갑니다. contentfollow면 그 페이지에 나온 모든 링크를 찾아 가서 링크된 문서도 긁어 갑니다. noindex면 그 페이지는 긁어가지 않습니다.nofollow면 링크를 확인해서 긁어가는 것을 건너 뜁니다.

즉, 다음과 같은 네 가지의 조합이 나옵니다. 목적에 맞게 사용하면 됩니다.


<meta name="robots" content="index,follow" /> 
: 이 문서도 긁어가고 링크된 문서도 긁어감. <meta name="robots" content="noindex,follow" />
: 이 문서는 긁어가지 말고 링크된 문서만 긁어감. <meta name="robots" content="index,nofollow" />
: 이 문서는 긁어가되, 링크는 무시함. <meta name="robots" content="noindex,nofollow" />
: 이 문서도 긁지 않고, 링크도 무시함.

웹 문서 주소가 바뀐 경우

<meta http-equiv="refresh" content="5;url=http://www.abc.com/" />

이런 것 많이 보았을 것입니다.

"이 페이지는 10초 후에 자동으로 새 페이지로 이동합니다. 아무 변화가 없으면 밑의 링크를 클릭하세요."

이것을 할 때 메타 태그를 사용합니다. 위 코드에서 content= 다음에 몇 초만에 넘어가게 할 것인가 숫자를 적고 콜론(;)을 한 다음 url=에 이동할 페이지의 url을 적으면 됩니다. 간단하죠? 이 한줄을 예전 (x)html 문서 <head>~</head> 사이에 넣어 두면 지정된 시간 경과후 새 url로 자동으로 넘어갑니다. 시간은 0.1, 0.5등 1초 미만도 가능합니다. 즉시 넘어 가게 할 때는 1초 미만으로 하면 됩니다.

만약 url을 원래 페이지와 똑같이 해 놓으면 어떻게 될까요? 몇 초마다 그 페이지가 '다시보기'(reload)됩니다. 그럴 필요가 있을 지는 모르겠지만 원한다면 그렇게 사용할 수도 있습니다.

한글 페이지라는 사실을 알릴 때

<meta http-equiv="content-type" content="text/html; charset=euc-kr" />

웹 페이지를 디스플레이 하는 문자 세트(character set)를 지정할 때 메타 태그를 사용합니다. 사용자 웹 브라우져에서 인코딩 방식을 특별히 한글로 해놓지 않더라도 위와 같은 메타 태그가 들어있는 웹 페이지는 한글 문자 세트를 이용해서 한글로 보여집니다. 이 메타 태그 역시 필수적으로 넣어두면 좋습니다. 특히 외국에서 영문 웹 브라우져로 접속하는 사람들을 위해서입니다. 영어 웹 사이트를 위주로 써핑하는 사람의 경우 브라우져 문자 세트를 영어로 해 놓고 있을 가능성이 높습니다.

http-equiv란?

위에서 http-equiv라는 것이 나왔는데 이게 무엇일까요? http로 나누는 대화라는 글에서 http 헤더에 관해 자세하게 설명할 때, 서버가 클라이언트로부터 온 http request를 접수한 다음 http response를 다시 웹 브라우져로 보내 준다는 얘기가 있었습니다. 그 http response의 헤더를 각 (x)html 문서 별로 따로 설정할 수 있는 것이 http-equiv 메타 태그라고 이해하면 됩니다.

일반적인 순서는 다음과 같습니다.

사용자가 특정 문서로의 링크를 클릭
--> 웹 브라우져에서 생성된 http request를 웹 서버로 보냄
--> 웹 서버에서 접수한 뒤 http response와 함께 (x)html 파일(또는 그래픽, 싸운드...)을 TCP/IP를 이용해 전달
--> 웹 브라우져에서는 http response에 설정된 대로 전달받은 파일을 염.

이 때 전달받은 파일을 http 리스판스 헤더에 설정된 대로 열면서 개별 (x)html 문서에서 설정해 둔 http-equiv 메타 태그에 있는 내용 역시 써버에서 보낸 http 헤더에 첨가합니다.

<meta http-equiv="content-type" content="text/html; charset=euc-kr" />

라면 웹 서버에서 클라이언트로 보내는 http 헤더에 있는 Content-type 이라는 마임 타입을 설정하는 부분을 http-equiv 메타 태그를 활용해서 개별 문서 별로 설정하는 것입니다.

참조  - http://www.emh.co.kr/xhtml/metatag.html

===================================================================================


.http-equiv 속성을 이용하면 정해진 시간 후 자동으로 다른 웹 문서로 이동하게 할 수 있다.

 

예>

 <meta http-equiv=refresh content="3; url=http://www.daum.net">

 

위의 예는 3초가 지나면 자동으로 다음 사이트로 이동하게 된다.

주로 홈페이지의 주소가 변경되었을 때, 과거의 주소로 방문했을 경우 잠시 후 새로운 주소로 이동하게 할 때 이용된다.

출처 - http://blog.naver.com/bebejune?Redirect=Log&logNo=70128836381















'Development > HTML' 카테고리의 다른 글

Tag들  (0) 2012.03.01
html - <meta> http-equiv Attribute  (0) 2012.02.11
정중앙 위치 시키기  (0) 2011.01.31
html - div란?  (0) 2011.01.31
MIME type  (0) 2011.01.09
Posted by linuxism
,