ㅎㅇㅎㅇ

내용 정리할 시간이 너무 부족하네요 오랜만에 씁니다

 

blog 2 에서만들었던 빈깡통파일 list.jsp을 조금 채워봅시다.

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="../layout/header.jsp" %>

<div class="container">

	<div class="m-2">
		<form class="form-inline d-flex justify-content-end" action="/blog/board">
			<input type="hidden" name="cmd" value="search" />
			<input type="hidden" name="page" value="0" />

			<input type="text" name="keyword" class="form-control mr-sm-2" placeholder="Search">			
			<button class="btn btn-primary m-1">검색</button>

		</form>
	</div>

	<div class="progress col-md-12 m-2">
		<div class="progress-bar" style="width: 70%"></div>
	</div>

		<div class="card col-md-12 m-2">
			<div class="card-body">
				<h4 class="card-title">제목</h4>
				<a href="#" class="btn btn-primary">상세보기</a>
			</div>
		</div>

	<br />
	<ul class="pagination justify-content-center">
		<li class="page-item disabled"><a class="page-link" href="#">Previous</a></li>
		<li class="page-item"><a class="page-link" href="#">Next</a></li>
	</ul>
</div>

</body>
</html>

지금은 데이터가 있는 척~ 하면서 div - card 를 만들었지만 이후에, JSTL을 사용해서 글 목록을 불러와서 뿌릴겁니다.

 

 

글작성을 위한 페이지 작업

header.jsp

헤더부분에 summernote 를 사용하기위해 몇 줄 추가해줍니다.

<link
	href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css"
	rel="stylesheet">
<script
	src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cos 블로그</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<link
	href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css"
	rel="stylesheet">
<script
	src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
</head>
<body>

	<nav class="navbar navbar-expand-md bg-dark navbar-dark">
		<a class="navbar-brand" href="<%=request.getContextPath()%>/index.jsp">블로그</a>
		<button class="navbar-toggler" type="button" data-toggle="collapse"
			data-target="#collapsibleNavbar">
			<span class="navbar-toggler-icon"></span>
		</button>
		<c:choose>
			<c:when test="${sessionScope.principal != null}">
				<div class="collapse navbar-collapse" id="collapsibleNavbar">
					<ul class="navbar-nav">
						<li class="nav-item"><a class="nav-link"
							href="<%=request.getContextPath()%>/board?cmd=saveForm">글쓰기</a></li>
						<li class="nav-item"><a class="nav-link"
							href="<%=request.getContextPath()%>/user?cmd=updateForm">회원정보</a>
						</li>
						<li class="nav-item"><a class="nav-link"
							href="<%=request.getContextPath()%>/user?cmd=logout">로그아웃</a></li>
					</ul>
				</div>
			</c:when>
			<c:otherwise>
				<div class="collapse navbar-collapse" id="collapsibleNavbar">
					<ul class="navbar-nav">
						<li class="nav-item"><a class="nav-link"
							href="<%=request.getContextPath()%>/user?cmd=joinForm">회원가입</a></li>
						<li class="nav-item"><a class="nav-link"
							href="<%=request.getContextPath()%>/user?cmd=loginForm">로그인</a></li>
					</ul>
				</div>
			</c:otherwise>
		</c:choose>
	</nav>
	<br>

여기서 이미 JSTL이 사용되고 있었네요 파일 상단에

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

이렇게 선언을 해주시면 jsp에서 java문법과 유사한 JSTL을 사용하실 수 있습니다.

<c: choose> , <c:when> , <c:otherwise> 가 사용되었네요 이 놈들은 if - else 처럼 사용되고있습니다.

 

 

<c:when test = "${sessionScope.principal != null}">

test 가 조건문입니다.  (principal : 로그인 인증 주체)

principal 이 null 이면 로그인 안한 상태 -> 로그인, 회원가입이 있는 View를 보여줌

principal 이 null 이 아니면 로그인 한 상태 -> 로그아웃, 글작성이 있는 View를 보여줌

 

saveForm.jsp

<%@page import="com.cos.blog.domain.user.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="../layout/header.jsp" %>

<div class="container">
	<form action="#" method="POST">

		<form action="/blog/board?cmd=save" method="POST">
		<input type="hidden" name="userId" value="${sessionScope.principal.id}" />
			<label for="title">Title:</label>
			<input type="text" class="form-control" placeholder="title" id="title" name="title">
		</div>

		<div class="form-group">
			<label for="content">Content:</label>
			<textarea id="summernote" class="form-control" rows="5" id="content" name="content"></textarea>
		</div>

		<button type="submit" class="btn btn-primary">글쓰기 등록</button>
	</form>
</div>

  <script>
  	$('#summernote').summernote({
        placeholder: '글을 쓰세요.',
        tabsize: 2,
        height: 400
      });
  </script>
</body>
</html>

 

 

 

 

 

 

글작성준비 완료

제법 그럴싸해보이죠

이것이 라이브러리의 힘??

 

 

 

saveForm의 action에 cmd=save 를 해줬으니 Controller에 cmd.equals("save")의 기능을 만들어줘야합니다.

 

BoardController.java (Servlet 파일입니다)

package com.cos.blog.web;

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 javax.servlet.http.HttpSession;

import com.cos.blog.domain.board.dto.SaveReqDto;
import com.cos.blog.domain.user.User;
import com.cos.blog.service.BoardrService;
import com.cos.blog.util.Script;

// http://localhost:8080/blog/board
@WebServlet("/board")
public class BoardController extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public BoardController() {
        super();
    }
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		String cmd = request.getParameter("cmd");
		BoardrService boardService = new BoardrService();
		// http://localhost:8080/blog/board?cmd=saveForm
		HttpSession session = request.getSession();
		if(cmd.equals("saveForm")) {
			User principal = (User) session.getAttribute("principal");
			if(principal != null) {
				response.sendRedirect("board/saveForm.jsp");
			}else {
				response.sendRedirect("user/loginForm.jsp");
			}	
		}else if(cmd.equals("save")) {
			int userId = Integer.parseInt(request.getParameter("userId"));
			String title = request.getParameter("title");
			String content = request.getParameter("content");

			SaveReqDto dto = new SaveReqDto();
			dto.setUserId(userId);
			dto.setTitle(title);
			dto.setContent(content);
			int result = boardService.글쓰기(dto);
			if(result == 1) { //정상
				response.sendRedirect("index.jsp");
			}else {
				Script.back(response, "글쓰기실패");
			}
		}
	}



}

SaveReqDto.java (글 저장'만'을 위한 Data Transfer Object)

package com.cos.blog.domain.board.dto;

import lombok.Data;

@Data
public class SaveReqDto {
	private int userId;
	private String title;
	private String content;
}

 

BoardDao.java (DB 작업)

package com.cos.blog.domain.board;

import java.sql.Connection;
import java.sql.PreparedStatement;

import com.cos.blog.config.DB;
import com.cos.blog.domain.board.dto.SaveReqDto;
import com.cos.blog.domain.user.dto.JoinReqDto;

public class BoardDao {

	public int save(SaveReqDto dto) { // 회원가입
		String sql = "INSERT INTO board(userId, title, content, createDate) VALUES(?,?,?, now())";
		Connection conn = DB.getConnection();
		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, dto.getUserId());
			pstmt.setString(2, dto.getTitle());
			pstmt.setString(3, dto.getContent());
			int result = pstmt.executeUpdate();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 무조건 실행
			DB.close(conn, pstmt);
		}
		return -1;
	}
}

BoardService.java

package com.cos.blog.service;

import com.cos.blog.domain.board.BoardDao;
import com.cos.blog.domain.board.dto.SaveReqDto;
import com.cos.blog.domain.user.UserDao;

public class BoardrService {

	private BoardDao boardDao;

	public BoardrService() {
		boardDao = new BoardDao();
	}

	public int 글쓰기(SaveReqDto dto) {
		return boardDao.save(dto);
	}
}

 

 

 

글 작성의 흐름 설명

1. 사용자(새 클라이언트)가 블로그를 방문합니다

2. 회원가입 로그인을 이미 마친 상태이고, 글쓰기 버튼을 누릅니다. 

3. cmd=saveForm 이기 때문에 Controller의 cmd.equals("saveForm") 기능으로 분기됩니다. (글쓰기 페이지로 이동)

4. 로그인을 했으므로 userId 가 기본적으로 있고, 제목(title) , 내용 (content)를 작성하고 글작성완료 버튼을 누릅니다.

이때 cmd=save 이기 때문에 Controller의 cmd.equals("save") 기능으로 분기됩니다.

 

jsp에서 <form> 안에 있는 양식을 submit으로 웹 서버에 전송하게 되면 input타입에 name속성이 붙여진 값들을 getParameter함수로 값을 받아서 변수로 사용할 수 있게 됩니다.

 

saveForm.jsp

<form action="/blog/board?cmd=save" method="POST">
		<input type="hidden" name="userId" value="${sessionScope.principal.id}" />
			<label for="title">Title:</label>
			<input type="text" class="form-control" placeholder="title" id="title" name="title">
		</div>

		<div class="form-group">
			<label for="content">Content:</label>
			<textarea id="summernote" class="form-control" rows="5" id="content" name="content"></textarea>
		</div>

		<button type="submit" class="btn btn-primary">글쓰기 등록</button>
	</form>

input 타입의 name속성 : UserId, title, content

전송하고 싶은 값인데, 보이지 않았으면 좋겠다 -> type="hidden" 을 사용합니다.

 

BoardController.java

else if(cmd.equals("save")) {
			int userId = Integer.parseInt(request.getParameter("userId"));
			String title = request.getParameter("title");
			String content = request.getParameter("content");

			SaveReqDto dto = new SaveReqDto();
			dto.setUserId(userId);
			dto.setTitle(title);
			dto.setContent(content);
			int result = boardService.글쓰기(dto);
			if(result == 1) { //정상
				response.sendRedirect("index.jsp");
			}else {
				Script.back(response, "글쓰기실패");
			}
		}

 

request.getParameter( [form 안에있는 input의 name 값] ) 을 변수에 넣어서

내맘대로 사용할 수 있습니다.

글쓰기만을 위한 SaveReqDto에 넣어서 new SaveReqDto를 만들어주고 

boardService의 글쓰기함수에서 바로 방금만든 dto를 인수로 받아 사용합니다.

 

글쓰기 함수는 save(SaveReqDto)를 호출합니다

BoardService.java

package com.cos.blog.service;

import com.cos.blog.domain.board.BoardDao;
import com.cos.blog.domain.board.dto.SaveReqDto;
import com.cos.blog.domain.user.UserDao;

public class BoardrService {

	private BoardDao boardDao;

	public BoardrService() {
		boardDao = new BoardDao();
	}

	public int 글쓰기(SaveReqDto dto) {
		return boardDao.save(dto);
	}
}

save함수를 보겠습니다

BoardDao.java

package com.cos.blog.domain.board;

import java.sql.Connection;
import java.sql.PreparedStatement;

import com.cos.blog.config.DB;
import com.cos.blog.domain.board.dto.SaveReqDto;
import com.cos.blog.domain.user.dto.JoinReqDto;

public class BoardDao {

	public int save(SaveReqDto dto) { // 회원가입
		String sql = "INSERT INTO board(userId, title, content, createDate) VALUES(?,?,?, now())";
		Connection conn = DB.getConnection();
		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, dto.getUserId());
			pstmt.setString(2, dto.getTitle());
			pstmt.setString(3, dto.getContent());
			int result = pstmt.executeUpdate();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		} finally { // 무조건 실행
			DB.close(conn, pstmt);
		}
		return -1;
	}
}

방금 만든 dto값으로 sql문을 만들어서 DB INSERT작업을 합니다.

INSERT의 결과값은 성공했으면 1 실패했다면 1 이외의 값을 return 하게 됩니다.

 

 

 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

+ Recent posts