JSP 피피티 06강 JSTL
JSTL의 이해
JSP Standard Tag Library
- JSP 표준 태그 라이브러리
- HTML 태그와 비슷한 문법을 통해 JAVA 언어의 프로그래밍적 문법과 변수, 객체 등에 접근할 수 있는 기능을 제공한다.
- MVC패턴의 View에서 사용할 경우 JSP파일에서 Java문법을 완전히 제거할 수 있기 때문에
프로그래밍 부분과 UI 구현 부분을 독립적으로 분리할 수 있다. - Spring에서 View에 대한 기본 문법으로 채택하고 있다.
우리가 Spring을 배울꺼니까 View(JSP)에서 JAVA코드를 쓸일이 있다면 JSTL로 해~~ 라는소리겠지?
JSTL 사용하기
JSP파일 상단에 커스텀 태그의 사용 정의
- 기본문법구성
<% taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> - 확장함수 지원
<% taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> - 포멧터 지원(숫자 세자리마다 콤마 찍는거)
<% taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
pom.xml에 JSTL을 위한 의존성 라이브러리 설정
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
실습에 사용할 간단한 POJO 클래스 정의
POJO???
POJO란?
POJO (Plain Old Java Object)는 "평범한 구식 자바 객체"를 의미한다.
POJO의 역사적 배경
마틴 파울러가 2000년 가을 콘퍼런스의 발표를 준비하며 처음 만들어낸 용어
왜 사람들은 EJB (Enterprise Java Bean) 사용하는 것보다 단순한 자바 오브젝트에 도메인 로직을 사용하는 것이 더 많은 장점이 있는데 왜 이러한 오브젝트를 사용하지 않는 것일까?
이때 마틴 파울러는 평범한 자바 오브젝트를 대체할 마땅한 용어가 존재하지 않아서 사용하지 않는 것이라 판단하였고 해당 오브젝트에 POJO라는 이름을 붙였다.
마틴 파울러는 왜 EJB에 부정적인 견해를 던졌는가?
EJB가 무엇인지에 대한 의문에서부터 시작해보자
EJB가 등장하게 된 배경은 기업에서 IT 시스템에 대한 업무 비중이 높아지면서 기본적인 JDK에 대한 기술만으로는 충족시키기 어려운 점을 보완하여 나타났다.
그 당시에도 J2EE라는 기술이 존재하였지만 서블릿 , Jsp 레벨의 최소한의 서버 인터페이스만을 가지고는 복잡한 엔터프라이즈 애플리케이션을 대체하기엔 어려움이 따랐다.
-
비즈니스 로직의 복잡성
-
로우 레벨에 대한 고민 (멀티스레드, 트랜잭션 처리, 리소스 풀링, 보안...)
EJB는 이러한 문제점을 개선하기 위해 등장하였다. EJB의 모토는 아래와 같다.
"개발자들은 로우 레벨에 관심을 가질 필요가 없이 오직 애플리케이션 개발에만 집중하게 도와준다. "
EJB는 독립적으로 개발한 컴포넌트들을 서버에 자유롭게 배포하고 서로 연동해 사용하게 하는 컴포넌트 기반의 개발 모델을 제시할뿐더러, 여러 대의 서버에 분산되어있는 모듈 간의 리모팅 처리도 개발자들이 거의 신경 쓰지 않고 개발할 수 있게 했다. 더 나아가 벤더별로 제각각 발전시켜 혼란에 빠지기 쉬운 자바의 서버 기술을 일관성 있게 구현할 수 있도록 지원하므로 특정 서버에 종속되지 않고 서버 간의 이동성을 보장해준다고 약속했다.
너무 과도한 EJB
EJB의 실패 원인은 객체지향적인 특징과 장점을 포기했다는 점에 있다.
EJB의 여러 가지 문제점들이 있지만 제일 실패한 것은 객체지향적인 특징 즉 상속과 다형성을 포기했다는 점에 있다. 이로 인해서 프로그램의 수정이 어려워지고 결합도가 높고 응집도가 낮은 최악의 애플리케이션이 만들어지게 된다.
그럼에도 계속 EJB를 사용하였던 이유는 마땅한 대체 자원이 없었기 때문이었다. 또한 이전에 언급하였던 개발자들은 로우 레벨에 신경 쓰지 않고 비즈니스 로직만을 구현하면 된다 에 대한 모토를 EJB가 어느 정도는 성공하였기 때문이다.
즉 애플리케이션 개발의 복잡도를 줄여주었지만 더 많은 복잡도와 문제를 양산하였다.
결국 EJB는 성능적인 이슈, 불필요한 기술적인 복잡도에 대한 문제가 커지며 불신이 가중되었다. 이러한 까닭에 마틴 파울러는 이전의 POJO로 퓨어한 자바로 돌아가자 라고 한 것이다.
하지만 이전으로 돌아가자는 것은 로우 레벨을 다루는 것으로 돌아가자라는 말과 같기 때문에 적절한 또 다른 대안이 나와야 했다.
스프링 프레임워크의 등장
POJO를 이용한 애플리케이션 개발이 가진 특징과 장점을 살리면서 EJB가 제공하였던 엔터프라이즈 서비스와 기술을 그대로 사용할 수 있는 POJO 프레임워크가 등장하였다. (스프링, 하이버네이트)
스프링 프레임워크는 POJO 프레임 워크 중 하나이며 자바 애플리케이션 개발을 위한 structure를 제공하는 자바 플랫폼이다. 스프링을 사용하면 POJO 기반의 애플리케이션을 만들 수 있고 로우 레벨에 대한 서버스를 비 침투적으로 POJO에 적용할 수 있다.
Annotation-based Container Configuration의 등장
어노테이션 기반 Configuration이 등장하면서 어느 사람들은 더 이상 어노테이션 기반의 클래스는 POJO가 아니라는 사람들이 등장하였다.
이런 말이 나오는 배경에 대해서 어느 정도 이해가 간다. 어노테이션을 사용하면 스프링이 제공하는 라이브러리를 자바 코드에서 사용한다는 것인데 이는 스프링 프레임워크에 종속적인 클래스가 작성될 여지가 높기 때문이다.
POJO를 정리
-
특정 규약(contract)에 종속되지 않는다. (Java 언어와 꼭 필요한 API 외에 종속되지 않는다.)
-
특정 환경에 종속되지 않는다.
-
객체지향 원리에 충실해야 한다.
POJO를 사용하는 이유
-
코드의 간결함 (비즈니스 로직과 특정 환경/low 레벨 종속적인 코드를 분리하므로 단순하다.)
-
자동화 테스트에 유리 (환경 종속적인 코드는 자동화 테스트가 어렵지만, POJO는 테스트가 매우 유연하다.
-
객체지향적 설계의 자유로운 사용
출처: https://jwdeveloper.tistory.com/212 [JW- 개발일지]
src/study.jsp.model2.model/Member.java
Member.java
package study.jsp.model2.model;
import lombok.Data;
@Data
public class Member {
private String name;
private int age;
}
컨트롤러클래스 추가(서블릿)
SimpleJstl.java
package study.jsp.model2.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import study.jsp.model2.model.Member;
/**
* Servlet implementation class SimpleJstl
*/
@WebServlet("/SimpleJstl")
public class SimpleJstl extends HttpServlet {
private static final long serialVersionUID = 7169072422760914445L;
/**
* @see HttpServlet#HttpServlet()
*/
public SimpleJstl() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//브라우저에 전달되는 컨텐츠의 형식 지정
response.setContentType("text/html; charset=utf-8");
//브라우저로부터 전달받는 파라미터의 인코딩 형식 지정
request.setCharacterEncoding("utf-8");
//문자열 변수를 View에 전달함
String message = "Hello JSTL";
request.setAttribute("my_message", message);
//정수형 변수를 View에 전달함
int num1=7;
int num2=9;
request.setAttribute("my_num1", num1);
request.setAttribute("my_num2", num2);
//Pojo 클래스에 대한 객체를 View에 전달함
Member member = new Member();
member.setName("학생");
member.setAge(20);
request.setAttribute("my_member", member);
//현재 서블릿의 요청을 JSP에게 전달하는 객체 생성
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/views/simple_jstl.jsp");
//현재 서블릿의 프로그램 흐름을 "/jstl/simple_mvc.jsp" 페이지에게 넘긴다.
dispatcher.forward(request, response);
//request에서 가지고 있는 주소정보를 취득하는 메소드 중 contextPath가 반환하는 값...
//request.getContextPath()는 프로젝트의 Context path명을 반환한다.
//response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
JSTL을 활용한 변수값의 출력
simple_jstl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<h1>${my_message}</h1>
<h1>${my_num1} + ${my_num2} = ${my_num1+my_num2}</h1>
<h1>${my_member.name}</h1>
<h1>${my_member.age}</h1>
</body>
</html>
그니까 JSTL은 앞으로 배울 SPRING 프레임워크에서 MVC패턴(Model2)으로 작업을 하게 된다.
MVC가 동작하는게
Controller(SimpleJstl.java)로 request를 받아 doGet()에서 필요한 처리를 하고 dispatcher를 통해 결과를 View(simple_list.jsp)로 보내서 출력
doGet()에서 처리하는 중간에 필요한 Model(Member.java)을 쓸 일도 있었음
request하면 C에서 값을 처리 이과정에서 M을 쓰기도함 그리고 결과를 V로 출력
뭐 이렇게 이해하면 되겠지