가끔 뻑날 때는 / 때문일 때가 있다.
이거 빼고 새로 해보면 좋다.
footer도 jsp 파일을 뺀다.
회사 정보 / 정보보안 책임자 / 연락처(사업장 소재지) / 주소
Login.java 파일
이 부분을 외워야.
//세션만들기 -> 겁나 어려울 것. (너무 중요해서 외우자.)
HttpSession session = request.getSession(); //세션만들기의 시작
session.setAttribute("mname", dto.getMname()); //mname이라는 이름으로 세션 만듦
session.setAttribute("mid", dto.getMid()); //mid라는 이름으로 세션 만듦
board.jsp 파일
${sessionScope.mname }님 반갑습니다. <!-- mname이라고 한다 -->
sessionScope.뭐뭐
<- 이거를 외우라고 하심.
menu.jsp 파일
얘도 외운다. 로그인한 사람에게는 로그아웃이라고 보이게 하기.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<nav>
<ul>
<li onclick="url('./')">홈</li>
<li onclick="url('./board')">게시판</li>
<li onclick="url('./qna')">문의게시판</li>
<li onclick="url('./notice')">공지사항</li>
<li onclick="url('./login')">로그인</li>
<li onclick="url('./logout')">로그아웃</li>
<li onclick="url('./info')">info</li>
</ul>
</nav>
로그아웃은 서블릿만 있으면 되고 jsp는 필요 없다.
로직을 거기다 써주기만 하면 됨.
write, update, login도 POST
로그아웃은 GET
누르면 /logout 이렇게 바로 가니까.
POST 처리 안해준 건 다 GET임.
Logout.java 서블릿
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//response.getWriter().append("Served at: ").append(request.getContextPath());
System.out.println("get으로 들어왔어요");
//세션 종료, 세션 삭제
/*
* 세션 쿠키 (서로 반대됨)
* 세션 : 서버(우리는 톰캣)에 저장됨. 필요할 때마다 서버에서 불러다 써서 보안에 강력
* - 로그인 정보
* - 자바
* - 은닉형태. 서버가 느려질 순 있음.
*
* 쿠키 : 클라이언트(브라우저)에 저장됨. 쿠키를 조작하면 조작된 쿠키가 서버에 올라감. 보안에 취약. 수억~군데에서 관리
* - 쇼핑정보, 장바구니, 방문내역, 로그인 정보 같은 것도 있다.
* - 스크립트(계열들이 만들어서 저장. JS같은..)
* - 오픈형태. 브라우저 방문하면 해당? 쿠키 볼 수 있음.
*
* 요즘은 JWT(javascript web token) 토큰이라는 것도 쓴다.
*/
HttpSession session = request.getSession(); //세션이라는 객체 만들고 if문으로 불러올 것.
if(session.getAttribute("mname") != null) { //세션이 있으면 -> 종료
System.out.println("세션 유효시간 : " + session.getMaxInactiveInterval()); //세션이 만든지 얼마나 됐는지, 남은 시간은? 기본적으로 30분(1800). web xml에서 조정가능.
System.out.println("mname : " + session.getAttribute("mname"));// 만들어 둔 이름을 알아야 뽑아볼 수 있다.
}
if(session.getAttribute("mid") != null) { //세션이 2개. 근데 어차피 종료하러 들어왔으니 if로 물을 것도 없이 로그아웃
System.out.println("mid : " + session.getAttribute("mid"));
}
//login 페이지로 보내기
response.sendRedirect("./login");
}
get으로 들어왔어요
세션 유효시간 : 1800
https://interconnection.tistory.com/74
https://wickedmagic.tistory.com/132
menu.jsp
<% if(session.getAttribute("mname") == null) { %>
<li onclick="url('./login')">로그인</li>
<% } else { %>
<li onclick="url('./logout')">로그아웃</li>
<% } %>
일단 이렇게 테스트.
<c:import>
까지 사실 세 가지
https://m.blog.naver.com/halowd/221686425368
<%@ include file="menu.jsp" %>
일단 파일에 붙여넣고, 자바를 실행시킨다.
board.jsp에서는 jstl로 써둔 menu.jsp가 잘 나옴.
(menu.jsp에서 jstl 상단에 taglib 줄을 없애서 와서 실행??)
<jsp:include page="menu.jsp"></jsp:include>
최종 결과를 파일에 붙여넣는다.
다시 전자로 바꾼다.
이렇게 차이가 난 이유는.. menu.jsp에서 taglib을 빼서임. (어차피 갖다쓰면 중복되니까..)
-> 근데 / url에서 해결이 안 돼서(/index랑 같은 거라 index.jsp 손봤는데도 ㅠ)
menu.jsp에 taglib 다시 씀.
taglib prefix부분을 뒤로 보내면 된다고 한다.
=> https://blog.naver.com/aladdin76/221033241746
서블릿에서
로그인이 됐을 때 이미 로그인했다~ 하고 알려줄 것.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
HttpSession session = request.getSession();
RequestDispatcher rd = null;
if (session.getAttribute("mname") != null) {
rd = request.getRequestDispatcher("already.jsp");
} else {
rd = request.getRequestDispatcher("login.jsp");
}
rd.forward(request, response);
}
로그인한 사람한테만 글쓰기 버튼 보여주기 (jstl)
<c:if test="${sessionScope.mname ne null }">
<button onclick="url('./write')">글쓰기</button>
</c:if>
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
HttpSession session = request.getSession();
if(session.getAttribute("mname") == null) {
response.sendRedirect("./login");
} else {
RequestDispatcher rd = request.getRequestDispatcher("write.jsp");
rd.forward(request, response);
}
}
관리자 사이트는 따로 파기도 한다.
이제는 자기 글에만 수정, 삭제 보이도록 할 것.
원래 이렇게 있던 것을
board_writer 열을 삭제하고
mno 열을 새로 추가함. (null 허용 X)
여기까지 하고 저장 먼저 한다.
ALTER 코드 (기존 데이터가 있어서 이렇게...)
ALTER TABLE `board`
ADD CONSTRAINT `FK_board_member` FOREIGN KEY (`mno`) REFERENCES `member` (`mno`) ON UPDATE NO ACTION ON DELETE NO ACTION;
ALTER TABLE `board`
ADD COLUMN `mno` INT NOT NULL AFTER `board_content`,
DROP COLUMN `board_write`;
SELECT b.board_no, b.board_title,
m.mname,
b.board_date, b.board_count
FROM board b JOIN member m
ON (b.mno=m.mno)
ORDER BY b.board_no DESC
LIMIT 0, 10
select `b`.`board_no` AS `board_no`,
`b`.`board_title` AS `board_title`,
`m`.`mname` AS `mname`,
if(date_format(current_timestamp(),'%Y-%m-%d') =
date_format(`b`.`board_date`,'%Y-%m-%d'),
date_format(`b`.`board_date`,'%h:%i'),
date_format(`b`.`board_date`,'%m-%d')) AS `board_date`,
`b`.`board_count` AS `board_count`
from (`board` `b` join `member` `m` on(`b`.`mno` = `m`.`mno`))
order by `b`.`board_no` desc limit 0,10
실습땜에 이렇게 됐지만 처음부터 join 염두에 두고 뷰를 짜는 게 좋다.
BoardDTO에 mid도 만든다.
session에 mname과 함께 mid를 올려둔 이유가 이거 하려고.
DAO에서는 이렇게 바뀜.
public BoardDTO detail(int no) {
BoardDTO dto = new BoardDTO();
Connection con = DBConnection.getInstance().getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "SELECT b.board_no, b.board_title, b.board_content, m.mname AS board_write, m.mid, "
+ "b.board_date, b.board_count "
+ "FROM board b JOIN member m ON b.mno=m.mno "
+ "WHERE b.board_no=?";
try {
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, no);
rs = pstmt.executeQuery();
// 글 하나니까 while아니고 if
if(rs.next()) {
dto.setNo(rs.getInt("board_no"));
dto.setTitle(rs.getString("board_title"));
dto.setContent(rs.getString("board_content"));
dto.setWrite(rs.getString("board_write"));
dto.setDate(rs.getString("board_date"));
dto.setCount(rs.getInt("board_count"));
dto.setMid(rs.getString("mid"));
}
} catch (SQLException e) {
e.printStackTrace();
}
return dto;
}
detail.jsp에서
${detail.write } / ${detail.mid } / ${sessionScope.mid }
를 하면 순서대로 글쓴사람, 글쓴사람id, 로그인한사람id가 보인다.
글쓰기
public int write(BoardDTO dto) {
int result = 0;
Connection con = DBConnection.getInstance().getConnection();
PreparedStatement pstmt = null;
String sql = "INSERT INTO board (board_title, board_content, mno) " //외래키 mno 넣고, 서브쿼리 날릴 것.
+ "VALUES (?, ?, (SELECT mno FROM member WHERE mid=?))"; //mid 갖다가 mno로 insert
try {
pstmt = con.prepareStatement(sql);
pstmt.setString(1, dto.getTitle());
pstmt.setString(2, dto.getContent());
pstmt.setString(3, dto.getMid());//수정완
result = pstmt.executeUpdate();//영향받은 행을 result에 저장한다.
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(null, pstmt, con);
}
return result;
}
detail.jsp에서 로그인 세션의 mid와 글쓴 mid가 일치하는 사람한테만 글삭제, 글수정 띄우기
<c:if test="${detail.mid eq sessionScope.mid }">
<img alt="delete" src="./img/delete.png" onclick="del()">
<img alt="edit" src="./img/write_pencil.png" onclick="update()">
</c:if>
Write.java 서블릿에서
한 번 더 거른다.
https://www.postman.com/
같은 곳은...