본문 바로가기
백엔드/웹 개발

8(JSTL + 게시판 만들기)

by study_yeon 2023. 6. 22.

2023.06.19 수업

교재 : 자바 웹 개발 워크북


복습 

* 스프링은 서블릿 기반 

* 프로토콜주소:// 주소:포트(기본은 생략 가능)/폴더(=웹앱)/쿼리스트링

* ? 데이터 : 쿼리스트링(query String)
키=값(변수=저장데이터)

* 요청한 서버주소를 제외한 이후의 경로를 요청경로라고 함 
루트이하 웹서비스이름을 통해 클라이언트의 요구를 알 수 있음

* 서블릿의 위치 src\main\java\패키지

* jsp의 위치 src\main\webapp
-> WEB-INF에 넣기(보안상의 이유)


● EL(Expression Language) 

- jsp 코드에서 사용한 '${}'는 EL의 표현식임

- 복잡한 자바 언어 대신 간단하게 사용할 수 있는 EL언어

◎ EL을 이용한 출력
- EL을 이용하는 경우에 자동으로 getter를 호출
- EL은 표현식을 이용하기때문에 내부적으로 자바로 동작함 
- 출력전용 
- {}내부에서는 private 처리된 변수도 바로 접근 가능


● JSTL(JavaServer Pages Standard Tag Library)

- jsp에서 동작하는 새로운 태그들의 묶음
- 뷰(HTML) 전용 라이브러리
- 라이브러리가 필요하므로 build.gradle 파일에 의존성라이브러리 추가
- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 를 추가해주어야 사용 가능


◎ Java 코드를 바로 사용하지 않고 HTML 태그(<>) 형태로 직관적인 코딩을 지원하는 라이브러리 
- HTML 코드 내에 java 코드인 스크립틀릿 <%= student %>를 ${student}로, <%=if %>문을 <c:if>, <%=for%>문을 <c:forEach>로 대체하여 사용

◎ 사용방식
1) 라이브러리 등록

* 라이브러리 다운 mvnrepository에서 jstl 검색
2번째의 1.2ver jar파일 다운



다운로드 jar파일 경로 옮기기 
C:\app\java\JavaWeb\src\main\webapp\WEB-INF\lib


2) 선언(core를 header에 추가)

- 태그 라이브러리 지시자

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

3) 사용 <c:out ~~/> 


▶ 실습
jsp 만들기 : hello_jstl.jsp
▷ 태그 라이브러리 지시자 작성 (선언)

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

▷ core 태그 사용연습(HTML body부분에 작성)
1. 화면출력하기
<c:out value="출력값"  />

<body>
	<c:out value="안녕하세요 JSTL입니다" /><br />
</body>

 

2. 변수 설정하기

- 변수 범위 설정하지 않으면 'page'가 기본
<c:set var="변수명" value="설정값" scope="변수 범위" />

<body>
	<c:set var="price" value="10000" scope="page" />
	${ price }<br />
</body>

 

※scope
- JSP변수의 유효범위
* page(디폴트 값) : 해당 페이지에서만 사용 가능
* request : response할 때까지
* session : 로그아웃, 클라이언트 종료시 소멸
* application : 웹 어플리케이션 서비스가 종료될 때까지
- 변수의 발견순서 : page > request > session > application

3. 변수 삭제하기
<c:remove var="변수명" />
- scope로 영역을 지정하지 않으면 모든 변수가 삭제됨
- 삭제된 부분은 공백으로 출력

	${ price }<br />
	<c:remove var="price"/>
	${ price }<br />
	${ price }<br />
	${ price }<br />

공백


4. 에러 발생시 try catch와 비슷
<c:catch var="변수명">처리결과 작성</c:catch>
<c:if test="${ "변수명"!= null }">에러메시지 : ${ "변수명".message }</c:if>
- c:if 태그 : test 속성내의 EL의 결과가 참이면 실행
- !== : 문자열 또는 숫자가 다르면 참
* 예외가 발생하면 변수에 값이 할당됨

	<c:catch var="e">
		<!-- 0으로 나누는 경우 예외가 발생 -->
		<%
			int num1 = 100;
			int num2 = 0;
			int result = num1 / num2;  // 0으로 나누는 경우
		%>
		결과는? <%= result %>
	</c:catch>
	<c:if test="${ e!= null }">
		<!-- 실제 에러처리 -->
		에러메세지 : ${ e.message }<br />
	</c:if>


5-1. if문

<c:if test="조건식"></c:if>

test 속성값에는 true/false로 나올 수 있는 식이나 변수 등이 들어갈 수 있다

	<!-- 반복연습 -->
	<c:set var="price" scope="page" value="10000" />
	<!-- price키의 값이 500보다 큰가?
		- 출력방식 2개
		<c:if test="조건식"></c:if>
	-->
	<c:if test="${ price > 500 }">값이 큽니다.</c:if><br />
	
	<c:if test="${ price > 500 }" var="priceCheck" scope="page" />
	<c:out value="${ priceCheck }" /><br />

-> if에는 else에 대한 처리가 없으므로 c:choose 활용


5-2. 선택조건문 if~else if와 비슷
c:choose
<c:when> : 조건에 맞을 경우
<c:otherwise> : 조건에 맞지 않을 경우

	<c:set var="price" value="10000" scope="page" />
	<!-- jsp판 switch/if -->
	<c:choose>
		<c:when test = "${ price <= 10000 }" >
			${ price }가 10000보다 작거나 같습니다.<br />
		</c:when>
		<c:when test = "${ price > 10000 }" >
			${ price }가 10000보다 큽니다.<br />
		</c:when>
		<c:otherwise>
		</c:otherwise>
	</c:choose>		
	
	<!-- 3의 배수인가? -->
	<c:set var = "a" value="${256}" scope="page" />
	<c:set var = "result" value="${a % 3}" scope="page" />
	
	<c:choose>
		<c:when test="${result == 1 || salary == 2 }">
			${a}은 3의 배수가 아니다<br />
		</c:when>
		<c:otherwise>
			${a}은 3의 배수이다<br />
		</c:otherwise>
	</c:choose>

6. 반복문
</c:foreach var="변수명" items="" >
- 반복문의 경우 begin/end를 이용하여 범위 지정 가능

	<c:forEach var="dto" items="${ list }" >
		<li>${ dto }</li>
	</c:forEach>

● 게시판 만들기 

▷ JSTL 활용하여 목록 출력하기 - list.jsp 수정

- 라이브러리 추가

- 반복문 작성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>제목은 여기에</title>
</head>
<h1>List Page</h1>
<body>
	<c:forEach var="dto" items="${ list }" >
		<li>${ dto }</li>
	</c:forEach>
</body>
</html>

 

- w1의 ToDoListController에서 실행하여 확인

실행결과


▷Todo 조회

- 식별할 수 있는 값(식별키)를 get방식으로 요청

 

○ w1의 TodoService에 내용 추가

- 특정한 번호의 조회 기능

package org.zerock.w1.todo.service;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.zerock.w1.todo.dto.TodoDTO;

// 상수 클래스
public enum TodoService {

	// 각각의 식별할 변수이름
	INSTANCE; // 각각의 값에 대한 식별키(변수), 값을 적지 않으면 순차적 부여

	// toString()의 가장 가까운 메소드, 구현하지 않았다면 부모의 것을 가져옴
	public void log(TodoDTO todoDTO) {
		System.out.println("DEBUG.........." + todoDTO.toString());
	}
	
	// 디비에 저장된 할일 목록을 가져온다
	public List<TodoDTO> getList() {
		// todoDTO의 목록이 리턴되어야 함
		
		List<TodoDTO> todoDTOS = 
			IntStream.range(0, 10).mapToObj(i -> {
				
				TodoDTO dto = new TodoDTO();
				dto.setTno((long)i);
				dto.setTitle("Todo ..." + i);
				dto.setDueDate(LocalDate.now());
				return dto;
		// collect를 통해 모아서 list 함수로 변환해라
		}).collect(Collectors.toList()); 
		
		return todoDTOS; // getList()로 돌아감
		
	}

	//(추가) 일렬번호를 넘겨주면 해당하는 레코드 정보를 가져올 수 있다
	public TodoDTO get(Long tno) {
		TodoDTO dto = new TodoDTO();
		dto.setTno(tno);
		dto.setTitle("Sample Todo");
		dto.setDueDate(LocalDate.now());
		dto.setFinished(true);

		return dto;
	}

}

 

○ 추가된 get() 메소드는 특정한 번호의 TodoDTO를 구성하는 기능이지만 샘플용 TodoDTO 객체를 생성해서 반환해주도록 구현하기

* 서블릿 만들기

org.zerock.w1.todo
TodoReadController 

- doGet 구현

- tno라는 이름의 파라미터 처리 기능

package org.zerock.w1.todo;

import java.io.IOException;
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 org.zerock.w1.todo.dto.TodoDTO;
import org.zerock.w1.todo.service.TodoService;

/**
 * Servlet implementation class TodoReadController
 */
@WebServlet(name = "todoReadController", urlPatterns = "/todo/read")
public class TodoReadController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("TodoReadController >> doGet() || todo/read");
		
		// /todo/read?tno=123
        // getParameter는 문자열로 결과가 나와서 타입 변환 필요
		Long tno = Long.parseLong(request.getParameter("tno"));
		
		TodoDTO dto = TodoService.INSTANCE.get(tno);
		
		request.setAttribute("dto", dto);
		
		// read.jsp파일 읽어 실행하기
		request.getRequestDispatcher("/WEB-INF/todo/read.jsp").forward(request, response);		
	}
}

TodoDTO dto = TodoService.INSTANCE.get(tno);를 통해 나온 객체가 jsp에게 전달


○ read.jsp 만들기

- TodoReadController 에서 보내준 TodoDTO객체를 dto라는 이름으로 받아 EL을 통해서 출력

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div>${ dto.tno }</div>
	<div>${ dto.title }</div>
	<div>${ dto.dueDate }</div>
	<div>${ dto.finished }</div>
</body>
</html>


-> 프로젝트를 실행하고 /todo/read?tno=123를 입력하면 TodoDTO객체의 내용을 볼 수 있음

 

'백엔드 > 웹 개발' 카테고리의 다른 글

10 (JDBC 프로그래밍 준비)  (0) 2023.06.23
9 (EL 표현식)  (0) 2023.06.23
7 (게시판 만들기)  (0) 2023.06.22
6(MVC 방식 + 게시판 만들기)  (0) 2023.06.21
5(웹 프로젝트의 기본 구조)  (0) 2023.06.20