본문 바로가기
실습/리눅스 서버 + 스프링 부트

Spring Boot + JSP

by 이민우 2023. 7. 2.
728x90
반응형

요즘 여러 회사의 채용공고들을 살펴보고 있는데, 느낀 점이 아직은 Spring Boot보다는 Spring Framework가 많이 사용되고, Thymeleaf 보다는 JSP가 많이 사용된다는 점이었다.

 

그래서 가만히 생각을 해보니, 회사에서 Thymeleaf만 사용하다보니 JSP를 전부 까먹었다는 사실을 알아냈다.

 

언제 jsp를 사용하게 될 지 모르므로, jsp의 사용법을 간단하게 기재해서 저장해놓고자 한다.

 

JSP

Java Server Pages (JSP)는 웹 개발을 위해 사용되는 자바의 기술이다. HTML과 Java를 결합해서 사용할 수 있는데, 서버에서 실행해서 생성된 결과를 html로 사용자에게 전달한다. 동적인 웹 페이지를 만들때 사용된다.

 

JSP를 사용함에 있어 장점과 단점은 아래와 같다.

  1. 코드와 디자인의 분리가 가능하다.
  2. 커스텀 태그, JSTL 및 EL을 통해 재사용 가능한 컴포넌트를 제공한다.
  3. MVC 패턴을 적용하기 좋아 개발과 유지보수에 용이하다.

 

  1. JSP 페이지는 첫 요청시 컴파일되어야 하기에 상대적으로 비효율적이고 느리다.
  2. JSP 페이지의 Java 코드는 오류를 찾고 디버깅하기 어렵다.

 

 

JSP 예제

이전에 작성했던 Thymeleaf 포스팅처럼 JSP에서의 코드를 간단하게 적어놓고자 한다.

 

우선 언제나 그랬듯 프로젝트부터 생성하고 시작한다. jsp 사용법만 만들 것이기에 Spring Web과 Lombok만 추가했다.

 

프로젝트가 생성됐으면 우선 pom.xml 파일에 아래 디펜던시를 추가한다. 템플릿 엔진인 JSP를 사용하기 위한 라이브러리이다.

<dependency>
  <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
  <scope>provided</scope>
</dependency>

 

추가 완료 후 메이븐을 이용해 프로젝트를 업데이트한다.

  • 프로젝트 우클릭 > Maven > Update Project

 

프로젝트가 갱신되었다면 /src/main/밑에 webapp 폴더와, 그 밑에 WEB-INF 폴더를 생성한다.

webapp 폴더는 스프링에서 웹의 root 폴더이며, WEB-INF는 J2EE 사양에 따라 정의된 표준 폴더 구조라고 한다.

참고 : https://7942yongdae.tistory.com/115

 

 

추가가 되었다면 이제 Thymeleaf 때처럼 jsp 파일의 위치와 확장자명을 application.properties에 추가해준다.

spring.mvc.view.prefix=classpath:/WEB-INF/
spring.mvc.view.suffix=.jsp

 

이제 테스트를 위한 Controller 클래스와, JSP 파일을 생성하자.

 

컨트롤러 클래스는 간단하게 작성한다. 일반 String, List, Map을 jsp에 반환하는 클래스이다.

package com.mwlee.jsp.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class CommonController {

	@GetMapping("/")
	public String mainPage(Model model) {

		String stringObj = "hello world";

		List<String> listObj = new ArrayList<>();
		listObj.add("hello");
		listObj.add("world");

		Map<Integer, String> mapObj = new HashMap<>();
		mapObj.put(1, "hello");
		mapObj.put(2, "world");
		
		// jsp에 데이터 반환
		model.addAttribute("stringObj", stringObj);
		model.addAttribute("listObj", listObj);
		model.addAttribute("mapObj", mapObj);
		
		// jsp 반환
		return "main";
	}
}

 

다음으로 데이터를 표출할 JSP를 작성한다.

우선 JSP는 가장 상단에 아래와 같은 설정이 입력되어 있어야 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 아래부터는 사용하는 태그에 따라 동적으로 추가 -->
<!-- c 태그 사용 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- fn 태그 사용 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!-- x 태그 사용 -->
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<!-- fmt 태그 사용 -->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!-- sql 태그 사용 -->
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

 

그리고 String을 다루는 부분은 아래와 같이 작성한다.

<h2>String Data: </h2>
<c:if test="${not empty stringObj}">
    ${stringObj}
    <!-- 이렇게도 가능하다. -->
    <c:out value="${stringObj}"/>
</c:if>

 

List는 forEach를 사용해서 하나씩 뽑아낸다.

<h2>List Data: </h2>
<c:if test="${not empty listObj}">
    <c:forEach var="item" items="${listObj}">
        ${item}<br/>
    </c:forEach>
</c:if>

 

마지막으로 Map도 마찬가지로 forEach를 사용해서 하나씩 뽑아내고, key와 value로 구분해서 사용한다.

<h2>Map Data: </h2>
<c:if test="${not empty mapObj}">
    <c:forEach var="entry" items="${mapObj}">
        ${entry.key} : ${entry.value}<br/>
    </c:forEach>
</c:if>

 

Java에서 전달한 변수를 반드시 HTML 내에서만 사용하란 법은 없다. 분명 JavaScript에서 사용될 일이 존재할 텐데, Java에서 전달한 변수는 아래와 같이 JavaScript에서 사용할 수 있다.

<script type="text/javascript">
	// String
	var stringObj = "${stringObj}";
	var stringObj2 = '<c:out value="${stringObj}"/>'

	// List
	var listObj = []; // 혹은 new Array()
	<c:if test="${not empty listObj}">
		<c:forEach var="item" items="${listObj}">
			listObj.push("${item}");
		</c:forEach>
	</c:if>

	// Map
	var mapObj = new Map();
	<c:forEach var="entry" items="${mapObj}" varStatus="loop">
		mapObj.set("${entry.key}", "${entry.value}")
	</c:forEach>
	// 이렇게도 사용 가능. 단 이 때는 object로 생성됨.
	var mapObj2 = {
		<c:forEach var="entry" items="${mapObj}" varStatus="loop">
			"${entry.key}": "${entry.value}"<c:if test="${!loop.last}">,</c:if>
		</c:forEach>
	};
		
	console.log(stringObj);
	console.log(listObj)
	console.log(listObj[0]);
	console.log(mapObj);
	console.log(mapObj.get('a'));
	console.log(mapObj2);
</script>

 

 

최종 jsp 파일은 아래와 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- c 태그 사용 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- fn 태그 사용 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
	<title>jsp 연습</title>
</head>
<body>
	<h2>String Data: </h2>
	<c:if test="${not empty stringObj}">
		${stringObj}
		<!-- 이렇게도 가능하다. -->
		<c:out value="${stringObj}"/>
	</c:if>

	<h2>List Data: </h2>
	<c:if test="${not empty listObj}">
		<c:forEach var="item" items="${listObj}">
			${item}<br/>
		</c:forEach>
	</c:if>

	<h2>Map Data: </h2>
	<c:if test="${not empty mapObj}">
		<c:forEach var="entry" items="${mapObj}">
			${entry.key} : ${entry.value}<br/>
		</c:forEach>
	</c:if>
    
	<script type="text/javascript">
		// String
		var stringObj = "${stringObj}";
		var stringObj2 = '<c:out value="${stringObj}"/>'
		
		// List
		var listObj = []; // 혹은 new Array()
		<c:if test="${not empty listObj}">
			<c:forEach var="item" items="${listObj}">
				listObj.push("${item}");
			</c:forEach>
		</c:if>
		
		// Map
		var mapObj = new Map();
		<c:forEach var="entry" items="${mapObj}" varStatus="loop">
			mapObj.set("${entry.key}", "${entry.value}")
		</c:forEach>
		// 이렇게도 사용 가능. 단 이 때는 object로 생성됨.
		var mapObj2 = {
			<c:forEach var="entry" items="${mapObj}" varStatus="loop">
				"${entry.key}": "${entry.value}"<c:if test="${!loop.last}">,</c:if>
			</c:forEach>
		};
		
		console.log(stringObj);
		console.log(listObj)
		console.log(listObj[0]);
		console.log(mapObj);
		console.log(mapObj.get('a'));
		console.log(mapObj2);
	</script>
    
</body>
</html>

 

 

마지막으로 c 태그 사용법을 기재하며 포스팅을 마무리한다.

태그 설명 사용
c:set 변수 선언 <c:set var="변수명" value="값" property="자바 객체" scope="범위/>
*공유범위는 page, request, session, application
c:remove 변수 제거 <c:remove var="변수명" scope="범위"/>
c:out 변수 출력 <c:out var="변수명" default="기본값 지정" excapeXML="true|false"/>
*excapeXML은 >, < 등을 %lt;, %gt; 등으로 변경하는 유무이다.
c:catch 예외처리 <c:catch var="에러 메시지로 ">
   에러 발생 가능성이 있는 로직 수행
</c:catch>
c:if 조건문 (else 없음에 유의) <c:if test="조건" var="변수명" scope="변수범위>
</c:if>
c:choose 조건문 (switch) <c:choose>
  <c:when test="조건"> ... </c:when>
  <c:when test="조건"> ... </c:when>
  <c:otherwise> ... </c:otherwise>
</c:choose>
c:when
c:otherwise
c:forEach 반복문 <c:forEach var="변수" items="데이터 내 아이템명" begin="시작값" end="종료 값" step="증가 값" varStatus="반복 상태 변수">
</c:forEach>
c:forTokens 구분자로 분할하는 반복문 <c:forTokens var="변수" items="데이터 내 아이템명" delims="구분자" begin="시작값" end="종료 값" step="증가 값" varStatus="반복 상태 변수">
</c:forEach>
c:url url <c:url var="변수" value="이동할 URL" scope="범위/>
c:param 파라미터 추가 <c:param name="파라미터명" value="값"/>
c:import 페이지 첨부 <c:import url="첨부 URL"/>
c:redirecrt 리다이렉트 <c:redirect url="이동할 URL"/>
728x90
반응형