본문 바로가기

수업 복습하기/개인 페이지 만들기

[포트폴리오] 개인페이지 제작기 04

728x90
728x90

= 위에 navBar에다가 memberList보는 페이지도 추가해보도록 합시다!

 

navBar.tag에 아래 식 추가!

<c:url value="/member/list" var="memberListUrl"></c:url>

	<li class="nav-item active">
		<a class="nav-link" href="${memberListUrl }">회원목록보기</a>
	</li>

여기서, 회원목록보기는 로그인세션이 있을 때만 작용하게 했다.

 

멤버리스트는 MemberController에서 작업해봅시다.

회원 정보를 조회해서, 모델에 담은 다음에 포워드 해올 수 있게 하는 일을 하게 하자.

 

메핑되는 값이랑 jsp값이 같으면, 그냥 놔둬도 되니까. 이렇게 두줄만 있으면 된다.

모델에 담아서, 값을 가져올 거니까 model 파라미터 필요해서 list옆에 삽입 완료.

= list.jsp

위치 : ex00\src\main\webapp\WEB-INF\views\member\list.jsp

이제 멤버의 list.jsp를 만들어서 페이지 구성 시작!

우선 navbar써야되니까 젤 위쪽에 taglib추가하고, body에 navBar추가

grid와 table을 이용해서, 회원정보 나타나게 식을 짜보도록 합시다~

 

c:forEach에서 items="memberList"쓸건데 이건 membercontroller에서 getmapping에서 모델에서 전달할 때,

list를 memberList라는 값으로 넘겼기 때문이다.

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<link rel="stylesheet" href="<%=request.getContextPath()%>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

<title>Insert title here</title>
</head>
<body>
	<b:navBar></b:navBar>

	<!-- .container>.row>.col>h1{회원 목록} -->
	<div class="container">
		<div class="row">
			<div class="col">
				<h1>회원 목록</h1>
				<!-- table.table>thead>tr>th*5^^tbody -->
				<table class="table">
					<thead>
						<tr>
							<th>아이디</th>
							<th>패스워드</th>
							<th>이메일</th>
							<th>주소</th>
							<th>가입일시</th>
						</tr>
					</thead>
					<tbody>
						<c:forEach items="memberList" var="member">
							<tr>
								<td>${member.id }</td>
								<td>${member.password }</td>
								<td>${member.email }</td>
								<td>${member.address }</td>
								<td>${member.inserted }</td>
							</tr>
						</c:forEach>
					</tbody>
				</table>
			</div>
		</div>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>

 

로그인 후에, 회원목록은 이런식으로 볼 수 있다.

근데, 회원목록보기는 로그아웃한 상태에서 url 주소치면 바로 사이트에 접근 할 수 있는데,

이런걸 원하지 않기 때문에, memberController선택해서,

로그인이 되어있지 않을 때, 로그인 화면으로 redirect 할 수 있게 하는 식을 추가하자.

위에 void ->String으로 바꾸는거 잊지말기

@GetMapping("/list")
	public String list(Model model, HttpSession session) {
		//로그인 된 상태가 아니라면 로그인화면으로 redirect
		MemberVO vo = (MemberVO) session.getAttribute("loggedInMember");

		// 로그아웃 상태
		if (vo == null) {
			return "redirect:/member/login";
		}
	
		List<MemberVO> list = service.getList();
		
		model.addAttribute("memberList", list);
		return null;
	}

 

= CheckLoginFilter.java

위치 : ex00\src\main\java\org\zerock\filter\CheckLoginFilter.java

메핑에서 로그인이 안된상태일 때, 로그인하면 로그인페이지로 이동하게 하는 기능을 필터를 사용해서 만들어보자

요청을 받으면, 특정 경로로 이동하게 하자. 이 때, 로그인화면으로 리다이렉트 시키자

 

파일에서 doFilter메소드가 작용한다~ 그 아래에 사용할 필터 작성하면 된다.

package org.zerock.filter;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.zerock.domain.project1.MemberVO;

/**
 * Servlet Filter implementation class CheckLoginFilter
 */
public class CheckLoginFilter implements Filter {

    /**
     * Default constructor. 
     */
    public CheckLoginFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

		//session attribute loggedInMember가 있으면 계속 진행
		HttpServletRequest req=(HttpServletRequest) request;
		HttpSession session = req.getSession();
		MemberVO vo = (MemberVO)session.getAttribute("loggedInMember");
		
		if(vo==null) {
			//없으면 /member/login으로 redirect
			String location = req.getContextPath() +  "/member/login";
			
			HttpServletResponse res = (HttpServletResponse) response;
			res.sendRedirect(location);
		}else {
			//있으면(로그인된 상태이면)
			chain.doFilter(request, response);
		}
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

web.xml

이제 위에서 filter를 사용하기 위한 특정 경로를 만들어 줄 것인데, 그걸 web.xml에서 건들여봅시다.

가보면 아래쪽에 이미 filter를 이클립스가 자동으로 알아서 넣어놨는데, 거기에 url-pattern부분을 건들여서, 

내가 필요한 부분에만 작용하게 했당.

  <filter>
    <display-name>CheckLoginFilter</display-name>
    <filter-name>CheckLoginFilter</filter-name>
    <filter-class>org.zerock.filter.CheckLoginFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>CheckLoginFilter</filter-name>
    <url-pattern>/member/list</url-pattern>
    <url-pattern>/member/remove</url-pattern>
    <url-pattern>/member/info</url-pattern>
  </filter-mapping>

필터를 삽입했기 때문에, 이제 기존에 controller에 있는 filter는 필요없다. 

삭제해도 되는데 우선 주석처리했다.


= 닉네임 추가하기

위치 : ex00\src\main\webapp\WEB-INF\sql\02member.sql

우선 nickname column을 추가했는데, 지금 null상태여서 업데이트 하기위해서

update랑 delete할 땐 이 설정 꼭 꺼줬다가, 하고싶은 일 하고 다시 클릭해줘야함

USE test;

CREATE TABLE Member(
	id VARCHAR(30) PRIMARY KEY,
	password VARCHAR(255) NOT NULL,
	email VARCHAR(255) NOT NULL,
    address VARCHAR(255) NOT NULL

);
DESC Member;

SELECT * FROM Member ORDER BY inserted DESC;

ALTER TABLE Member ADD COLUMN nickName VARCHAR(30); -- 컬럼 추가

UPDATE Member SET nickName = id; -- id 컬럼을 nickName 컬럼으로 추가 (disable safe update)	

ALTER TABLE Member MODIFY COLUMN nickName VARCHAR(30) UNIQUE NOT NULL; -- 제약 사항 추가 unique, not null

회원가입 할 때 닉네임, 회원정보 수정할 때 닉네임, 정보보기, 회원목록보기 등에서 관련된 화면 수정하고,

controller vo mapper service도 혼자 넣어서 수정해보기!

 

= 1단계) signup.jsp

닉네임 입력하기 위해서, 위에 아무 div나 복사한 후에, type, id, required name, value를 수정하면되는데,

우선 나중에 nickName으로 쓰기로 하고, 값을 적어넣으면 된다. 다른 곳에서 불러오기 위해서 required name 적는거다

	<div class="form-group">
		<label for="input2">닉네임</label>
		<input type="text" class="form-control" id="input5" required name="nickName" value="${member.nickName }">
	</div>

그리고 가입버튼을 넣으면 post 형식으로 전달이 될거다.

 

+) 이제 membercontroller로 해서, /signup으로 넘어갈거다. 거기에 MemberVO에 가서, String nickName을 추가해준다.

이부분이 많이 헷갈렷는데 f3버튼으로 바로바로 메소드를 쫓아가보자

memberController에서, /signup에서 service.register타곧 들어가서 -> MemberService로가서, 거기서 또 insert에서 f3을 눌러서 MemberMapper를봤는데, insert업무를 우리가 xml에서 다루고 있기 때문에, xml으로 들어가서 확인!

아오 거쳐거쳐서 가는 단계인데 ㅠㅠ 이렇게 헷갈릴 줄이야..

insert하기위해서 데이터베이스에서 가져와햐는 컬럼이 생겼으니까, 거길 다시 확인하는 단계이다.

쿼리를 보면, 새로운 컬럼인 nickName이 없으니까 그부분 추가해줘야되는거 까먹지 말기~

수정 완료~
회원가입에 닉네임창 생성 완료


= 2단계) info.jsp

회원정보보기 사이트에서 닉네임 보이게 하기 

info.jsp에도아래부분추가해놓고,

	<div class="form-group">
		<label for="input5">닉네임</label>
		<input type="text" required id="input5" class="form-control" name="nickName" value="${sessionScope.loggedInMember.nickName}">
	</div>

 session 에 로그인 기록이 있는 아이디로 보여줘야하기때문에, memberController에서 /login에서 vo를봐야하는데,

service.read에서 무슨 일을 해서 가져온거니까 거기서 read를 타고 넘어가보면!

read에서 select를사용했다. select를 타고 들어가면 아 이제 여기에 뭐 들어가잇는지 확인해볼 수 있다.

그러면 또 member.xml에 가서 쿼리를 수정해야하는 것 확인 가능하다.

쿼리 수정 완료
이렇게 회원정보에서도 닉네임칸이 보이게 된다.


= 닉네임 수정하기

닉네임을 바꿔봤는데, 수정도 적용되게해보려면

post형식으로 /info에 온다.

modify가 일을 하게 되는데, modify는 mapper.update를 하게되니까 따라서 memberMapper를 수정하게 된다.

nickName을 nicnName으로 오타가나서 오류가 계속 나서 ㅋㅋ ㅋ어디서 뭐가문제인가 계속 찾느라 시간보냇다 아효~

어쨋든 오타 찾아내서 회원 정보 수정도 완료~


+)

 아이디 삭제하는 것 자체는, 닉네임과 관련이 없기때문에 딱히 건들지 않아도 되고,

회원 목록보는거에 닉네임 추가해보자

 

= list.jsp

th에 닉네임 + ${member.nickName}추가해줬고, mapper에도 닉네임 추가해줬다.

이제 어떻게 어디에 넣어야할지 확실하게 안 느낌!

 

게시물 작성할 때, 작성자가 로그인된 닉네임으로 들어가게 해보자

이부분

 

이론상으로 어떤 테이블이, 다른 테이블에 있는 값을 참조해야한다면 참조한 값은 반드시 primary key여야한다는데,

실제로는 다르다고 한다 ㅋㅋㅋ (우선 writer를 나는 qwer1로 다 통일했다)

 

우선 게시물 작성페이지는 filter를 통해서, 로그인한 사람만 들어올수 있게 하고싶다면 우선

navBar에서, 글쓰기 위치를 c:if아래의 loggedInMember아래로 옮기고, 

post형식이어서 주소창을 입력하면 이 페이지로 넘어올 수 있으니, filter를 수정하도록 하자. -> web.xml에서

이 부분을 추가해서 작성하였다.

이렇게 되니까, 위에 navBar에 로그인 하지 않았을 때, 글쓰기 페이지 삭제되었다 두둥~

 


모든 곳에 작성자가 닉네임이 보이게 해보자.

게시물 목록부터, 글작성하고 수정하는 곳 까지!


= list.jsp

게시물 목록 보기

ㅁboardMapper.xml 

어떤걸 사용하면 될까 라고 물어보셨는데, join을 활용하면 된다고 하셨다

아, 닉네임은 member테이블에 있는 컬럼이라 그걸 board에 가져오려면 join 이 필요하다고 하신거구나 이제 이해 했다 ㅋㅋ 무슨 말인가 했는데, 생각해보니까 아예 따로 존재하던 애들이었구나 ㅎㅎ

이렇게 수정하고, nickName이 들어가기위해서는 properties가 BoardVO가 있어야한다.

그래서 BoardVO 에 private String nickName;을 넣었다.

그리고, list.jsp에 가서 작성자에 닉네임을 넣어보자. ${board.writer}를 ${board.nickName}으로 변경했다.

 


= get.jsp

게시물 하나씩 조회 

이부분에서 WHERE 부분에서, join때문에 id가 어느 테이블의 id인지 확인을 해야하는데, b.id인것을 확인해서 넣어줘야하는 부분이 포인트!

이제 jsp로 가서 수정해보자

get.jsp에 작성자 부분을 board.writer -> board.nickName으로 수정했다. 확실히 게시물 조회 하면서 작성자 부분 닉네임으로 변경 완료 확인!

이제 수정 삭제 버튼을 로그인한 사람과, 게시물의 작성할 때만 보이게 해야하니까, c:if를 사용해서, 코드를 짜보자.

get.jsp에서 수정했음.

다른 아이디로 로그인 했을 때, 아래와 같이 수정/삭제 버튼 안뜨는거 확인 완료

= registerjsp

작성자 부분을, 이제 원하는 닉네음으로 작성하게 해보자

name attribute 삭제하는거 까먹지 말기~

writer값이필요하긴한데, 보이면 안되니까 hidden으로 작성!

hidden으로 writer값이 넘어가기때문에, 굳이 쿼리는 수정이 필요가 없다.

 

register는 내가 로그인 후에 글을 적는거니까, 내 로그인 정보에서 nickname을 가져오고, writer는 값이있는데, 보이지 않아도 되니까 hidden으로 처리를 해서 값이있는데, 비어있지 않게 하는 것이다.

 

= modify.jsp

보이는건, 닉네임이 보이지만 전송되는건 아이디가 전송되야하는부분이라는거 까먹지말기

register.jsp와 같이 writer가 넘어오고, 보이는건 닉네임이라는거~

이제, 수정칸에도 닉네임이 제대로 뜬다!

아까 register는 session이었고, modify는 그냥 board.nickname인데 이게 왜 차이가 있는건지 잘 모르겠네 흠.

 

=> 같이 프로젝트 했던 오빠한테 물어봐서 답변

사실 게시물에 대한 정보자체는 board에서 불러오는게 정확하기 때문에, sessionScope로 불러오지 않고, 

게시물 자체의 db는 게시물로 가져오는거고, register는 게시글의 정보를 작성하는거니까 내꺼를 가져다가 적는 것이라고 생각하는게 낫다고 생각한다.


= join연습

회원목록보기에서 join연습만 하나 더~ 작성글 수라는 열을 넣어보자 

이름은 ${numberOfBoard}

각회원이 게시글을 몇개썼는지 확인하기위해 쿼리부터 작성 시작

mysql에서 미리 작성해서 테스트 해 본 후, memberMapper.xml로 가져가면 된다.

COUNT기능으로, b.id로 board에서 id가 몇개인지 센 후에, 그룹으로 memberid로 분리를 해주면 몇명이서 얼마나 글 썻는지 확인이 가능하다.

게시글을 작성하지 않은사람도 나와야하기 때문에, left join을 써야하고, 그리고 정렬을 제일 마지막에 가입한 사람이 아래쪽에 보이게 정렬.

MemberMapper.xml에 복사한 후에, COUNT(b.id)를 list.jsp에 썻던 이름을 활용하기 위해서,

생략가능하지만! as를 붙여서 작성하고, MemberVO에 numberOfBoard라는 프로퍼티가 있어야하기 때문에, 작성해주어야한다.

MemberVO에 아래와같이 코드 추가~

private Integer numberOfBoard;

 

 

오른쪽에 보면 밀려서, 작성글수가 나타나게 되었다~ 

 

 

오늘 수업은 여기까지, 아우힘들어 죽겠다 죽겄어~~

그래도 뜻하는바가 있으니 힘내자

 

 

 

 

728x90