시작 페이지 화면에서 뉴스 목록을 보여주고
뉴스를 선택해 세부내용 보기/삭제를 할수있게 구성할것이다.
뉴스 등록 부분은 별도 페이지로 구성이 가능하나
뉴스 목록 아래에 등록 버튼을 두고 눌렀을때 입력 양식을 보여주고 등록하도록 구성하겠다.
디자인은 부트스트랩을 사용하고 분제 발생시 에러 메시지를 출력하는 부분이 포함되어있다.
데이터 출력은 EL과 JSTL을 사용할것이다.
1️⃣ newList.jsp
기본구조
메인화면으로 뉴스 목록을 보여주는 화면이다.
[webapp]에 ch10 폴더 생성후 newsList.jsp를 만들어주자.
그후 부트스트랩에 접속하자. 그리고 CSS와 JS를 복사해주자.
복사한 내용은 <head>태그에 넣어주자.
목록출력
전체 화면 영역을 부트스트랩 컨테이너로 묶고 가로 크기를 75%로 지정할것이다.
상단 마진설정과 함께 가운데 배치를 위해 mx-auto로 좌우 마진을 동일하게 설정할것이다.
<div class="container w-75 mt-5 mx-auto">
<h2>뉴스 목록</h2>
<hr>
</div>
목록을 보여주는 부분은 <ul>, <li>를 사용하여 목록형식으로 구성할것이다.
JSTL의 <c:forEach>를 이용해 목록 형식으로 구성하고 JSTL의 <c:forEach>를 이용해
request에 저장된 newList를 가져와 반복 출력할것이다.
화면에 보이는 뉴스 번호는 실제 aid가 아니라 {status.count}다.(순차번호)
<div class="container w-75 mt-5 mx-auto">
<h2>뉴스 목록</h2>
<hr>
<ul class="list-group">
<c:forEach var="news" items="${newslist}" varStatus="status">
<li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<a href="news.nhn?action=getNews&aid=${news.aid}" class="text-decoration-none">
[${status.count}] ${news.title}, ${news.date}
</a>
<a href="news.nhn?action=deleteNews&aid=${news.aid}">
<span class="badge bg-secondary"> ×</span>
</a>
</li>
</c:forEach>
</ul>
</div>
- 뉴스 제목의 하이퍼링크에 밑줄이 나타나지 않도록 text-decoration-none 사용함.
<li><a href="">[번호] 뉴스 제목, 등록일</a><a href="">삭제 버튼</a></li>
- 뉴스제목 링크는 컨트롤러인 news.nhn을 호출하면서 action, aid가 파라미터로 전달되며 삭제 버튼도 같다.
- X는 삭제 버튼의 X 표시를 위한 표기다. 삭제 버튼은 <span>태그를 사용해 badge 컴포넌트로 만듬.
에려 출력
뉴스 목록 아래에는 에러 메시지를 출력하는 부분을 추가할것이다.
에러메시지는 request에 "error"가 저장된 경우에만 보여야한다.
따라서 JSTL의 if 태그를 사용해 부트스트랩의 alert 컴포넌트로 출력할것이다.
뉴스 삭제와 유사하게 삭제 버튼을 추가해 에러메시지를 닫을수있도록 할것이다.
<c:if test="${error != null}">
<div class="alert alert-danger alert-dismissible fade show mt-3">
에러 발생: ${error}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
</c:if>
뉴스 등록 양식
뉴스를 등록하기 위한 버튼을 만들고
눌렀을때 입력양식이 보이도록 할것이다.
부트스트랩의 버튼가 Collapse 컴포넌트로 이벤트가 발생했을때만 보이는 영역으로 구성할것이다.
버튼과 Collapse 컴포넌트는 data-bs-toggle, data-bs-target 속성으로 연결한다.
<button class="btn btn-outline-info mb-3" type="button" data-bs-toggle="collapse" data-bs-target="#addForm"
aria-expanded="false" aria-controls="addForm">뉴스 등록</button>
- data-bs-target, aria-controls 속성값은 양식영역인 <div>의 id로 설정된 addForm과 이름이 동일해야한다.
- 뉴스 양식으로 보일 부분을 <div></div> 사이에 넣어야한다.
Collapse 부분에 들어갈 입력 양식은 일반적인 html <form>으로 구현할것이다.
입력 양식은 부트스트랩의 form-label, form-control로 구성하고 입력 양식을 테두리가 있는 박스 형태로 만들기 위해 card를 적용한다.
<div class="card card-body">
<form method="post" action="/news.nhn?action=addNews" enctype="multipart/form-data">
<label class="form-label">제목</label>
<input type="text" name="title" class="form-control">
<label class="form-label">이미지</label>
<input type="file" name="file" class="form-control">
<label class="form-label">기사내용</label>
<textarea cols="50" rows="5" name="content" class="form-control"></textarea>
<button type="submit" class="btn btn-success mt-3">저장</button>
</form>
</div>
submit 버튼을 클릭하면 <form>의 action에 지정된 url로 입력값이 전달된다.
이때 컨트롤러를 호출하면서 action파라미터를 addNews로 전달한다.
또한 등록 양식이기 때문에 get이 아닌 post방식을 사용한다.
전체 <div>구조의 닫는 태그가 잘들어가 있는지 확인해주자.
아래는 전체 코드다.
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>뉴스관리 앱</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</head>
<body>
<div class="container w-75 mt-5 mx-auto">
<h2>뉴스 목록</h2>
<hr>
<ul class="list-group">
<c:forEach var="news" items="${newslist}" varStatus="status">
<li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<a href="news.nhn?action=getNews&aid=${news.aid}" class="text-decoration-none">
[${status.count}] ${news.title}, ${news.date}
</a>
<a href="news.nhn?action=deleteNews&aid=${news.aid}">
<span class="badge bg-secondary"> ×</span>
</a>
</li>
</c:forEach>
</ul>
<hr>
<!--에러 출력부 -->
<c:if test="${error != null}">
<div class="alert alert-danger alert-dismissible fade show mt-3">
에러 발생: ${error}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
</c:if>
<!--뉴스 등록 양식 -->
<button class="btn btn-outline-info mb-3" type="button" data-bs-toggle="collapse" data-bs-target="#addForm"
aria-expanded="false" aria-controls="addForm">뉴스 등록</button>
<div class="collapse" id="addForm">
<div class="card card-body">
<form method="post" action="/news.nhn?action=addNews" enctype="multipart/form-data">
<label class="form-label">제목</label>
<input type="text" name="title" class="form-control">
<label class="form-label">이미지</label>
<input type="file" name="file" class="form-control">
<label class="form-label">기사내용</label>
<textarea cols="50" rows="5" name="content" class="form-control"></textarea>
<button type="submit" class="btn btn-success mt-3">저장</button>
</form>
</div>
</div>
</div>
</body>
</html>
2️⃣ newsView.jsp
newsList.jsp에서 뉴스 제목을 클릭했을때 뉴스를 보여주는 화면 이었다.
기본 jsp 구조는 newsList.jsp와 동일하며 여기서는 화면구성과 관련된 부분만 설명할것이다.
뉴스 제목과 사진, 기사 내용, 등록 날짜/시간 등은 EL을 이용해 출력할것이다.
박스 형태의 화면구성을 위해 부트스트랩의 card, card-img-top, card-body, card-title, card-text등을 활용했다.
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>뉴스 관리 앱</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</head>
<body>
<div class="container w-75 mt-5 mx-auto">
<h2>${news.title}</h2>
<hr>
<div class="card w-75 mx-auto">
<img class="card-img-top" src="${news.img}">
<div class="card-body">
<h4 class="card-title">Date: ${news.date}</h4>
<p class="card-text">Content: ${news.content}</p>
</div>
</div>
<hr>
<a href="javascript:history:back()" class="btn btn-primary"> << Back </a>
</div>
</body>
</html>
[메인으로 돌아가기]
'Java Spring > 책공부 1 (JSP와 스프링)' 카테고리의 다른 글
22. 필터 (0) | 2022.07.15 |
---|---|
21. 리스너 (0) | 2022.07.15 |
19. 컨트롤러 구현 (0) | 2022.07.14 |
18. 모델 구현 (0) | 2022.07.14 |
17. 뉴스기사 관리 서비스 설계 (0) | 2022.07.14 |