국비 지원 IT(웹앱개발) 취업반 강의 49일차 (Spring)

BlackBird·2024년 8월 14일

개발자 취업 일지

목록 보기
79/116

로그인 로그아웃 구현부터 시작했는데, 난 이미 해 두어서 글 작성할 때, 로그인 하지 않으면 불가능하게끔, 그리고 유저 아이디를 넘겨서 글 작성자가 누군지 알 수 있게 만드는 작업부터 했다.

		// 로그인 상태 확인
        if (session.getAttribute("loginUser") == null) 
            return ResultData.from("F-0", "로그인 상태가 아닙니다.");

우선 이 코드는 로그아웃할 때 썻던 걸 그냥 doWrite 메서드에서 가져왔고,

Session을 사용해서 memberId 데이터를 가져올 필요가 있었기에 login 메서드를 약간 손을 봐서 memberId데이터를 저장할 수 있게 만들었다.

	@RequestMapping("/usr/member/doLogin")
	@ResponseBody
	public ResultData<Member> doLogin(HttpServletRequest request, String loginId, String loginPw) {
		HttpSession session = request.getSession();
		// 이미 로그인된 상태인지 확인
        if (session.getAttribute("loginUser") != null) {
            return ResultData.from("F-0", "이미 로그인된 상태입니다.");
        }
        
	    if (Ut.isEmptyOrNull(loginId)) 
	        return ResultData.from("F-1", "아이디를 입력해주세요.");
	    

	    if (Ut.isEmptyOrNull(loginPw)) 
	        return ResultData.from("F-2", "비밀번호를 입력해주세요.");
	    
	    
	    ResultData<Member> loginRd = memberService.doLogin(loginId, loginPw);

        if (loginRd.isFail()) return loginRd;
        
	    
     // 로그인 성공 시 세션에 사용자 정보 저장
        Member member = loginRd.getData1();
        session.setAttribute("loginUser", member);
        session.setAttribute("memberId", member.getId()); // memberId를 세션에 저장

	    return memberService.doLogin(loginId, loginPw);
	}

처음에 Member로 저장한게 아니라 Session 자체에 저장을 해서 데이터를 가져오지 못했다. 그래서 Member에 저장하게끔 수정하고, getId로 값을 가져온다.

	@RequestMapping("/usr/article/doWrite")
	@ResponseBody
	public ResultData doWrite(HttpSession session, String title, String body) {
		// 로그인 상태 확인
        if (session.getAttribute("loginUser") == null) 
            return ResultData.from("F-0", "로그인 상태가 아닙니다.");
        
		if (Ut.isEmptyOrNull(title)) {
			return ResultData.from("F-1", "제목을 입력해주세요");
		}
		if (Ut.isEmptyOrNull(body)) {
			return ResultData.from("F-2", "내용을 입력해주세요");
		}
		
		Integer memberId = (Integer) session.getAttribute("memberId");

		ResultData writeArticleRd = articleService.writeArticle(memberId ,title, body);

		int id = (int) writeArticleRd.getData1();

		Article article = articleService.getArticleById(id);

		return ResultData.from(writeArticleRd.getResultCode(), writeArticleRd.getMsg(), article);
	}

그리고 여기서 session을 불러와서 memberId를 꺼내오고,

	public ResultData writeArticle(int memberId, String title, String body) { 
				
		articleRepository.writeArticle(memberId, title, body);

		int id = articleRepository.getLastInsertId();

		return ResultData.from("S-1", Ut.f("%d번 글이 등록되었습니다", id), id);
	}

서비스에 전달하고

//	@Insert("INSERT INTO article SET regDate = NOW(), updateDate = NOW(), title = #{title}, `body` = #{body}")
	public void writeArticle(int memberId, String title, String body);
	<insert id="writeArticle">
		INSERT INTO article
		SET regDate = NOW(),
		updateDate = NOW(),
		title = #{title},
		`body` = #{body},
		memberId = #{memberId}
	</insert>

쿼리문에 memberId까지 추가해주면 된다.


로그인 상태가 아닐 때, 글 작성 막아둔 것도 잘 작동하고,

로그인 시 글 작성까지 해당 memberId를 남겨서 저장하는 것 까지 잘 작동한다.

다음으로는 게시물에 대한 권한 체크다. 삭제가 조금 더 접근하기 쉬워 보이니까 삭제부터 보자.

	@RequestMapping("/usr/article/doDelete")
	@ResponseBody
	public ResultData<Integer> doDelete(HttpSession session , int id) {
		// 로그인 상태 확인
		boolean isLogined = false;
		int loginedMemberId = 0;

		if (session.getAttribute("loginedMemberId") != null) {
			isLogined = true;
			loginedMemberId = (int) session.getAttribute("loginedMemberId");
		}
		if (isLogined == false) {
			return ResultData.from("F-A", "로그인 하고 써");
		}
	
		Article article = articleService.getArticleById(id);

		if (article == null) {
			return ResultData.from("F-1", Ut.f("%d번 게시물은 없습니다.", id));
		}
        // 권한체크
		if (article.getMemberId() != loginedMemberId) 
			return ResultData.from("F-B", "게시물에 대한 권한이 없습니다.");

		articleService.deleteArticle(id);

		return ResultData.from("S-1", Ut.f("%d번 게시물 삭제되었습니다.", id));
	}

게시물에서 MemberId를 가져와서 그 값이랑 session에서 가져온 memberId만 구분해주면 된다.

처음에 메서드를 만들어서 쿼리까지 쐈다가 강사님이 하시는 것 보고 바로 바꿨다.

만들고 보니까 코드 몇줄만 있으면 되는거라 같은 코드를 modify에도 넣고 하니까 잘 된다.

여기까지 하고 JSP를 셋팅했다.

JSTL을 알아보자.

JSTL(JavaServer Pages Standard Tag Library)은 JSP(JavaServer Pages)에서 사용되는 태그 라이브러리라고 한다.
JSTL 설정을 하는데 애를 좀 먹었다. 일단 설정을 끝내고 연결이 잘 되는 것도 확인했다.

	@RequestMapping("/usr/article/list")
	public String showList(Model model) {
		List<Article> articles = articleService.getArticles();

		model.addAttribute("articles", articles);
		return "/usr/article/list";
	}

기존 코드를 고치면서 List 먼저 화면 구성을 만지기 시작했고, Model 객체를 사용해서 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">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/static/css/style.css">
<title>Article List</title>
</head>
<body>
	<h1>게시물 목록</h1>
	
	<hr/>
	
	<table class="article-table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Registration Date</th>
                <th>Title</th>
                <th>Member ID</th>
            </tr>
        </thead>
        <tbody>
            <c:forEach var="article" items="${articles}">
                <tr>
                    <td>${article.id}</td>
                    <td>${article.regDate.substring(0, 10)}</td>
                    <td><a href="detail?id=${article.id}">${article.title}</a></td>
                    <td>${article.memberId}</td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
	
</body>
</html>

그리고 JSTL을 사용해서 게시물 목록을 볼 수 있게 화면을 구성했다.

다음 과제는 타이틀을 클릭했을 때 해당 게시물의 상세보기다.

	@RequestMapping("/usr/article/detail")
	public String detail(Model model, int id) {

		Article article = articleService.getArticleById(id);

		if (article == null) {
//			return ResultData.from("F-1", Ut.f("%d번 게시물은 없습니다.", id));
		}
		model.addAttribute("article", article);

		return "/usr/article/detail";
	}
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="pageTitle" value="게시물 상세보기"></c:set>
<%@ include file="../common/head.jspf"%>

	<hr/>

	<div class="article-detail">
		<div class="detail-item">
			<span class="label">번호:</span> ${article.id}
		</div>
		<div class="detail-item">
			<span class="label">날짜:</span> ${article.regDate}
		</div>
		<div class="detail-item">
			<span class="label">작성자:</span> ${article.memberId}
		</div>
		<div class="detail-item">
			<span class="label">제목:</span> ${article.title}
		</div>
		<div class="detail-item">
			<span class="label">내용:</span> ${article.body}
		</div>
		<div class="actions">
			<a href="delete" class="btn">게시물 삭제</a> <a href="modify" class="btn">게시물
				수정</a>
		</div>
	</div>

	<div class="navigation">
		<a href="../home/main" class="btn">메인 페이지로</a> <a href="list"
			class="btn">리스트로 돌아가기</a>
	</div>


</body>
</html>

잘 나온다.

JSP 코드를 보면 위가 날라가고 새로운 것이 들어와 있는게 보일건데, 공통된 헤드를 jspf파일로 나누어서 따로 관리한다.

<%@ 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">
<link rel="stylesheet" type="text/css"
	href="${pageContext.request.contextPath}/resource/common.css">
<script src="/resource/common.js" defer="defer"></script>
<title>${pageTitle}</title>
</head>
<body>
	<h1>${pageTitle}</h1>

이게 나눈 헤드.

여기까지!

profile
한영신의 벨로그입니다.

0개의 댓글