[F-Lab 모각코 페이백 14일차] JSP, Encoding, UTF-8, Character Set
학습 목표
- JSP
TIL
- JSP
- UTF-8
- UTF-16
- 스크립틀릿
JSP
JSP(JavaServer Pages)는 자바(JAVA)를 사용하여 웹 페이지를 구성하고, 동적인 웹 페이지를 생성하는데 사용되는 서버 사이드 스크립트 언어입니다.
JSP는 HTML 코드 내에 자바 코드를 삽입하는 방식으로 작동하며, 웹 서버가 이를 해석하고 실행하여 동적인 웹 페이지를 생성합니다. 클라이언트의 요청에 따라 내용이 변경되는 웹 페이지나, 데이터베이스에 접근해 정보를 보여주는 등의 작업에 적합합니다.
JSP는 기본적으로 HTML과 유사하지만, <% %> 또는 <%= %>와 같은 태그를 사용하여 자바 코드를 포함시킬 수 있습니다. 이러한 기능 덕분에 JSP는 웹 개발에서 동적인 기능을 구현하는 데 매우 유용합니다.
또한, JSP는 MVC(Model-View-Controller) 디자인 패턴을 사용하여 어플리케이션을 모듈화하고 관리하는데도 자주 사용됩니다. 이러한 접근 방식은 웹 어플리케이션의 확장성과 유지보수성을 향상시킵니다.
JSP(JavaServer Pages)의 동작 과정
JSP(JavaServer Pages)의 동작 과정은 다음과 같습니다:
- JSP 페이지 요청: 웹 브라우저나 다른 클라이언트가 JSP 페이지를 요청합니다. 이 요청은 HTTP를 통해 웹 서버에 전달됩니다.
- JSP 페이지 컴파일: 웹 서버(예: 톰캣)는 요청 받은 JSP 페이지를 서블릿으로 변환합니다. 이 변환 과정은 JSP 컴파일러에 의해 이루어지며, 첫 요청 시에만 이루어집니다. JSP 페이지가 이미 서블릿으로 변환되어 있다면 이 단계는 생략됩니다.
- 서블릿 로드와 실행: 변환된 서블릿은 웹 서버에 의해 로드되고, 서블릿의 service() 메소드가 호출됩니다. 이 메소드는 HTTP 요청을 처리하고, 동적인 HTML을 생성합니다.
- 응답 반환: 생성된 HTML은 HTTP 응답으로 클라이언트에게 전송됩니다. 클라이언트는 이 응답을 받아 웹 브라우저에 표시합니다.
- 서블릿 유지: 변환된 서블릿은 웹 서버에 계속 유지되며, 동일한 JSP 페이지에 대한 후속 요청을 처리할 수 있습니다. 만약 JSP 페이지가 변경되면, 웹 서버는 변경된 JSP 페이지를 다시 컴파일합니다.
위의 과정을 통해, JSP는 동적인 웹 컨텐츠를 생성하는데 사용될 수 있습니다. 사용자의 요청에 따라 동적으로 변경되는 HTML을 생성하거나, 데이터베이스에서 데이터를 검색하여 웹 페이지에 표시하는 등의 기능을 구현할 수 있습니다.
서버 사이드 스크립트
서버 사이드 스크립트 언어(server-side scripting language)는 클라이언트의 요청에 따라 서버에서 실행되는 프로그래밍 언어를 말합니다. 이 언어를 사용해 작성된 코드는 웹 서버에서 직접 실행되며, 결과적으로 동적인 웹 페이지를 생성하게 됩니다.
서버 사이드 스크립트 언어의 주요 목적은 웹 페이지의 콘텐츠를 동적으로 생성하고, 데이터베이스와 상호작용하는 것입니다. 이를 통해 사용자가 입력한 정보를 처리하거나, 사용자마다 다르게 콘텐츠를 제공하는 등의 동적인 기능을 구현할 수 있습니다.
이러한 서버 사이드 스크립트 언어에는 여러 종류가 있으며, 각각의 언어가 제공하는 기능과 사용 방법에는 차이가 있습니다. 대표적인 서버 사이드 스크립트 언어로는 PHP, Python, Ruby, Node.js(JavaScript), ASP.NET(C#), JSP(Java) 등이 있습니다.
예를 들어, PHP는 웹 개발에 널리 사용되는 서버 사이드 스크립트 언어로, HTML 코드 안에 PHP 코드를 삽입하여 동적인 웹 페이지를 만드는 데 사용됩니다. Python은 Django, Flask 등의 웹 프레임워크를 사용하여 웹 애플리케이션을 개발하는데 사용됩니다. Node.js는 JavaScript를 서버 사이드에서 실행할 수 있게 해주는 플랫폼입니다. ASP.NET은 Microsoft의 .NET 프레임워크를 기반으로 한 웹 개발 기술이며, C# 언어를 사용합니다. JSP는 앞서 설명한 바와 같이 Java를 사용하여 동적인 웹 페이지를 생성하는데 사용됩니다.
JSP 컴파일러
JSP 컴파일러: JSP 컴파일러는 웹 서버 내에 포함되어 있는 컴포넌트로, JSP 파일(.jsp)을 서블릿 코드(.java)로 변환하는 역할을 합니다. 이 변환 과정을 통해 JSP 페이지에 작성된 HTML과 자바 코드가 하나의 자바 파일로 변환되며, 이후 이 파일은 일반적인 자바 컴파일러에 의해 컴파일되어 클래스 파일(.class)이 생성됩니다. 이 클래스 파일은 자바의 가상 머신(JVM)에서 실행될 수 있습니다.
서블릿
서블릿: 서블릿은 Java EE 스펙의 일부로, 웹 서버에서 동작하는 자바 클래스입니다. 서블릿은 웹 브라우저 등 클라이언트로부터의 요청을 처리하고, 결과를 HTTP 응답으로 반환하는 역할을 합니다. 즉, 서블릿은 웹 서버 상에서 실행되는 자바 프로그램으로, 클라이언트의 요청에 따라 동적인 컨텐츠를 생성하거나 데이터를 처리하는 등의 역할을 합니다. JSP 페이지는 처음 요청이 들어오면 JSP 컴파일러에 의해 서블릿 코드로 변환되며, 이후 이 서블릿 코드가 실행되어 웹 페이지를 생성하게 됩니다.
페이지 디렉티브(page directive)
페이지 디렉티브(page directive)는 JSP(JavaServer Pages)에서 특정 페이지에 대한 정보를 제공하거나 설정하는 데 사용되는 지시자입니다. 페이지 디렉티브는 <%@ page ... %> 형식으로 표현되며, 웹 컨테이너에게 페이지에 대한 특정 정보를 전달합니다.
페이지 디렉티브는 다음과 같은 속성을 포함할 수 있습니다:
- language: 사용할 스크립팅 언어를 지정합니다. 기본값은 "java"입니다.
- extends: 자동으로 생성되는 서블릿이 확장할 서블릿 클래스를 지정합니다.
- import: 페이지에서 사용할 자바 클래스를 지정합니다.
- session: 세션을 사용할지 여부를 지정합니다. 기본값은 "true"입니다.
- buffer: 출력 버퍼의 크기를 지정합니다.
- autoFlush: 출력 버퍼가 꽉 찼을 때 자동으로 비워질지 여부를 지정합니다.
- isThreadSafe: 페이지가 스레드로부터 안전한지 지정합니다.
- info: 페이지에 대한 설명을 제공합니다.
- errorPage: 예외가 발생했을 때 이동할 에러 페이지를 지정합니다.
- isErrorPage: 현재 페이지가 에러 페이지인지 지정합니다.
- contentType: 응답의 MIME 유형과 문자 인코딩을 설정합니다.
페이지 디렉티브를 사용하면, 개발자는 JSP 페이지가 어떻게 동작하고 처리되어야 하는지를 더욱 세밀하게 제어할 수 있습니다.
MIME(Multipurpose Internet Mail Extensions)
MIME(Multipurpose Internet Mail Extensions)는 인터넷에서 전송되는 파일과 메시지의 형식과 방식을 정의하는 인터넷 표준입니다. 원래는 이메일에서 비텍스트 데이터를 전송하기 위해 개발되었지만, 현재는 웹에서도 널리 사용되고 있습니다.
MIME은 메시지가 어떤 형식의 데이터를 포함하고 있는지를 설명하는 "콘텐츠 타입"을 정의합니다. 콘텐츠 타입은 주 타입(main type)과 부 타입(subtype)으로 구성되며, 둘은 슬래시(/)로 구분됩니다. 예를 들어, "text/html", "image/jpeg", "application/json" 등의 MIME 타입이 있습니다.
웹에서는 HTTP 응답 헤더의 'Content-Type' 필드에서 MIME 타입이 사용됩니다. 이를 통해 브라우저는 응답에 포함된 콘텐츠가 어떤 형식인지를 알 수 있으며, 이에 따라 적절한 방식으로 콘텐츠를 처리하게 됩니다. 예를 들어, "text/html" MIME 타입을 가진 콘텐츠는 HTML 문서로, "image/jpeg" MIME 타입을 가진 콘텐츠는 JPEG 이미지로 처리됩니다.
JSP Encoding
JSP 페이지의 인코딩은 JSP 파일에서 사용하는 문자 인코딩 방식을 의미합니다. 문자 인코딩은 텍스트 데이터를 바이트로 변환하는 방식을 정의하며, ASCII, ISO-8859-1, UTF-8 등 다양한 인코딩 방식이 있습니다.
JSP 페이지의 인코딩 방식은 'pageEncoding' 속성을 통해 지정할 수 있습니다. 'pageEncoding' 속성은 페이지 디렉티브(page directive)의 일부로, JSP 페이지에 사용되는 인코딩 방식을 웹 컨테이너에게 알려줍니다.
예를 들어, 아래와 같은 코드는 JSP 페이지의 인코딩 방식이 UTF-8임을 나타냅니다:
<%@ page pageEncoding="UTF-8" %>
'pageEncoding' 속성을 사용하면 JSP 파일에서 사용하는 문자 인코딩을 명확하게 지정할 수 있습니다. 이를 통해 다양한 언어와 문자를 정확하게 표현하고, 인코딩 변환으로 인한 오류를 방지할 수 있습니다.
또한 'pageEncoding' 속성은 JSP 페이지가 생성하는 응답에 대한 'Content-Type' 헤더의 문자 인코딩 부분을 설정하는 데에도 영향을 미칩니다. 예를 들어, 'pageEncoding'이 "UTF-8"로 설정된 경우, 응답 헤더의 'Content-Type' 필드는 "text/html; charset=UTF-8"와 같이 됩니다. 이는 브라우저에게 응답의 콘텐츠가 UTF-8로 인코딩되었다는 것을 알려주는 역할을 합니다.
페이지 인코딩의 중요성과 BOM
페이지 인코딩은 매우 중요합니다. 웹 페이지는 텍스트 데이터를 전송하는 매체이기 때문에, 어떤 문자 인코딩 방식을 사용하는지는 매우 중요한 문제입니다. 문자 인코딩은 텍스트 데이터를 바이트로 변환하는 방식을 정의하며, 서로 다른 인코딩 방식을 사용하면 동일한 텍스트가 다르게 표현될 수 있습니다.
특히, 다양한 언어와 문자를 지원하는 웹에서는 문자 인코딩 문제가 더욱 중요해집니다. 예를 들어, 한글, 일본어, 중국어 등의 문자를 정확하게 표현하려면 해당 문자를 지원하는 문자 인코딩 방식을 사용해야 합니다. 이를 위해 많은 웹 페이지에서는 UTF-8 등의 유니코드 인코딩 방식을 사용합니다.
BOM(Byte Order Mark)은 유니코드 인코딩에서 사용하는 특수한 코드입니다. BOM은 인코딩된 텍스트 스트림의 바이트 순서(byte order)와 인코딩 방식을 표시하는 데 사용됩니다. BOM은 유니코드 인코딩, 특히 UTF-16과 UTF-32에서 중요한 역할을 하지만, UTF-8에서는 필수적이지 않습니다.
그러나 일부 상황에서는 UTF-8 인코딩된 텍스트에 BOM을 포함시키는 것이 유용할 수 있습니다. 예를 들어, BOM이 포함된 UTF-8 인코딩된 텍스트는 해당 텍스트가 UTF-8로 인코딩되었다는 것을 명확하게 나타내므로, 인코딩을 자동으로 감지하는 소프트웨어에게 유용한 정보를 제공합니다. 하지만 BOM이 없는 UTF-8 인코딩도 광범위하게 사용되며, BOM이 없는 UTF-8 인코딩을 기대하는 소프트웨어에서는 BOM이 있는 UTF-8 인코딩된 텍스트를 올바르게 처리하지 못할 수도 있습니다.
최근 UTF-8와 UTF-16 선호도 (2023)
웹 개발에서는 UTF-8 인코딩이 가장 널리 사용되고 있습니다. UTF-8은 모든 유니코드 문자를 표현할 수 있으면서도 ASCII 문자는 1바이트로 표현한다는 이점이 있습니다. 이는 웹 상에서 영문과 숫자, 기본 구두점 등을 주로 사용하는 경우 데이터를 효율적으로 전송할 수 있다는 뜻입니다.
UTF-16은 UTF-8보다 많은 바이트를 사용하여 ASCII 범위의 문자를 인코딩하므로, 대부분의 웹 콘텐츠에서는 UTF-8이 더 효율적입니다. 또한, UTF-16은 바이트 순서 문제(byte order issue)를 가지고 있어서 추가적인 처리가 필요할 수 있습니다.
또한, UTF-8은 많은 웹 기술 및 프로그래밍 언어에서 기본 문자 인코딩으로 지정되어 있습니다. HTML5와 HTTP/1.1 표준은 기본 문자 인코딩으로 UTF-8을 권장하고 있으며, Python 3와 Rust와 같은 최신 프로그래밍 언어도 소스 코드의 기본 문자 인코딩으로 UTF-8을 사용합니다.
따라서 현재 웹 개발 트렌드에서는 UTF-8 인코딩이 UTF-16 인코딩보다 더 널리 사용되고 있습니다.
캐릭터셋(Character Set)
캐릭터셋(Character Set): 특정한 문자 집합을 의미합니다. 예를 들어, ASCII는 128개의 문자를, ISO-8859-1은 256개의 문자를, Unicode는 전 세계의 모든 문자를 표현할 수 있는 매우 큰 캐릭터셋입니다.
인코딩(Encoding)
인코딩(Encoding): 캐릭터셋의 문자를 바이트로 변환하는 방법을 의미합니다. 예를 들어, UTF-8, UTF-16, ISO-8859-1 등은 인코딩 방식입니다. 동일한 캐릭터셋이라도 다른 인코딩을 사용하면 다른 바이트 시퀀스로 변환됩니다.
그런데 일반적으로 웹에서 말하는 "캐릭터셋"은 실제로는 인코딩을 의미하는 경우가 많습니다. 예를 들어, HTML의 Content-Type 헤더에서 charset=UTF-8이라고 명시하면, 이는 UTF-8 인코딩을 사용한다는 의미입니다.
페이지의 인코딩과 웹 서버가 전송하는 캐릭터셋을 다르게 설정할 수는 있지만, 이렇게 하면 문제가 발생할 수 있습니다. 웹 브라우저는 웹 서버로부터 받은 HTTP 헤더를 통해 전달받은 캐릭터셋(실제로는 인코딩)을 기반으로 페이지의 인코딩을 판단합니다. 만약 페이지의 실제 인코딩과 웹 서버가 전송하는 캐릭터셋이 다르다면, 브라우저는 페이지를 잘못 해석하게 될 수 있습니다.
따라서 일반적으로는 페이지의 실제 인코딩과 웹 서버가 전송하는 캐릭터셋을 동일하게 설정해야 합니다. 이렇게 하면 브라우저가 페이지를 올바르게 해석하고, 사용자에게 제대로 된 콘텐츠를 표시할 수 있습니다.
스크립틀릿
스크립트릿(scriptlet)은 JSP(JavaServer Pages)에서 사용되는 개념으로, Java 코드를 HTML 내에 직접 삽입할 수 있게 해주는 기능을 말합니다.
스크립트릿은 <% %> 태그 사이에 위치한 Java 코드입니다. 이 코드는 JSP 페이지가 요청되면 서버에서 실행됩니다. 이를 통해, 개발자는 HTML을 동적으로 생성하거나, 데이터베이스에서 데이터를 검색하거나, 사용자 입력을 처리하는 등의 서버 측 로직을 HTML 페이지 내에서 직접 작성할 수 있습니다.
스크립트릿 예시는 다음과 같습니다:
<% int x = 10; %>
<% out.println("x의 값은 " + x + "입니다."); %>
위의 스크립트릿은 변수 x를 선언하고 초기화한 후, 이 값을 웹 페이지에 출력합니다. 이 코드는 JSP 페이지가 요청될 때마다 서버에서 실행되므로, 웹 페이지는 항상 최신의 정보를 반영할 수 있습니다.
그러나 너무 많은 Java 코드를 스크립트릿으로 작성하는 것은 권장되지 않습니다. 이렇게 하면 HTML과 Java 코드가 혼합되어 코드의 가독성과 유지 관리성이 떨어질 수 있습니다. 따라서 복잡한 로직은 서블릿이나 자바 클래스로 분리하고, JSP 페이지에서는 주로 프레젠테이션 로직(화면에 보여주는 로직)을 담당하는 것이 일반적입니다.