회원제 게시판(02)
1. BoardDao.java에 나머지 메소드들 채워줌. (findBy, modity, remove)
public Board findBy(Integer boardno) {
Board result = null;
Connection conn = DBConn.getConnection();
String sql = "SELECT BOARDNO, TITLE, CONTENT, USERID, REGDATE, HITCOUNT, PARENTNO, CATEGORY\r\n" +
"FROM BOARD\r\n" +
"WHERE BOARDNO = ?\r\n";
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardno);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
int idx = 1;
result = new Board();
result.setBoardno(rs.getInt(idx++));
result.setTitle(rs.getString(idx++));
result.setContent(rs.getString(idx++));
result.setUserid(rs.getString(idx++));
result.setRegdate(rs.getString(idx++));
result.setHitcount(rs.getInt(idx++));
result.setParentno(rs.getInt(idx++));
result.setCategory(rs.getInt(idx++));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public void modify(Board board) {
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "UPDATE BOARD SET\r\n" +
" TITLE = ?,\r\n" +
" CONTENT = ?,\r\n" +
" REGDATE = SYSDATE\r\n" +
"WHERE BOARDNO = ?";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setString(idx++, board.getTitle());
pstmt.setString(idx++, board.getContent());
pstmt.setInt(idx++, board.getBoardno());
// 실행
pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
}
- 쿼리문 가져와서 ""에 붙여넣기하고 ?로 바꿀 때 ?, 콤마 잘 확인하기!
- 수정 되는 부분 : 제목, 내용, 글번호
public int remove(Integer boardno) {
int ret = 0;
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "DELETE BOARD WHERE BOARDNO = ?";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setInt(idx++, boardno);
// 실행
ret = pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
return ret;
}
- void remove였던 걸 int remove로 바꿈.
- 왜 !?
- try catch 때문에 바로 return pstmt.executeUpdate();하면 안 되고 int ret = 0; 을 해서 ret에 담아야 함.
작성 후 실행을 했을 때 오류가 났는데, pstmt.executeUpdate(); 에서 오류가 난 건 저 메소드를 실행하려고 할 때 전처리 문장에서 오류가 난 것 이었음. ,를 쓰지 말아야 할 곳에 썼었던 것.
(수정) write 메소드
public void write(Board board) {
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "INSERT INTO BOARD(BOARDNO, TITLE, CONTENT, USERID, PARENTNO, CATEGORY)\r\n" +
"VALUES (SEQ_BOARD.NEXTVAL, ?, ?, ?, ?, ?)";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setString(idx++, board.getTitle());
pstmt.setString(idx++, board.getContent());
pstmt.setString(idx++, board.getUserid());
pstmt.setObject(idx++, board.getParentno());
pstmt.setInt(idx++, board.getCategory());
// 실행
pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
}
- Parentno가 null 값이 될 수 있어서 null 처리를 해야 했는데 setObject로 수정했음.
BoardDao.java (오늘의 최종)
package board.dao;
import java.sql.Connection;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import board.vo.Board;
import member.vo.Member;
import util.DBConn;
public class BoardDao {
public void write(Board board) {
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "INSERT INTO BOARD(BOARDNO, TITLE, CONTENT, USERID, PARENTNO, CATEGORY)\r\n" +
"VALUES (SEQ_BOARD.NEXTVAL, ?, ?, ?, ?, ?)";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setString(idx++, board.getTitle());
pstmt.setString(idx++, board.getContent());
pstmt.setString(idx++, board.getUserid());
pstmt.setObject(idx++, board.getParentno());
pstmt.setInt(idx++, board.getCategory());
// 실행
pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
BoardDao dao = new BoardDao();
// Board board = new Board("자바에서 쓴 글 제목", "자바에서 쓴 글 내용", "javava", 1, 1);
// dao.write(board);
System.out.println("====목록조회====");
dao.list(1).forEach(System.out::println);
System.out.println("====상세조회====");
System.out.println(dao.findBy(1));
System.out.println(dao.findBy(3));
System.out.println("====수정확인====");
dao.modify(new Board(2, "자바에서 수정된 글 제목", "자바 내용"));
System.out.println(dao.findBy(2));
System.out.println("====삭제 후 반영 행 개수 확인====");
System.out.println(dao.remove(3));
System.out.println(dao.remove(4));
System.out.println("====목록조회====");
dao.list(1).forEach(System.out::println);
}
public List<Board> list(Integer category) {
ArrayList<Board> result = null;
Connection conn = DBConn.getConnection();
String sql = "SELECT BOARDNO, TITLE, CONTENT, USERID, CASE\r\n" +
" WHEN SYSDATE - REGDATE < 1 THEN TO_CHAR(REGDATE, 'HH24:MI:SS')\r\n" +
" ELSE TO_CHAR(REGDATE, 'YY/MM/DD')\r\n" +
"END REGDATE, HITCOUNT, PARENTNO, CATEGORY\r\n" +
"FROM BOARD\r\n" +
"WHERE CATEGORY = ? AND BOARDNO > 0\r\n" +
"ORDER BY 1 DESC";
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, category);
ResultSet rs = pstmt.executeQuery();
result = new ArrayList<Board>();
while(rs.next()) {
int idx = 1;
Board board = new Board();
board.setBoardno(rs.getInt(idx++));
board.setTitle(rs.getString(idx++));
board.setContent(rs.getString(idx++));
board.setUserid(rs.getString(idx++));
board.setRegdate(rs.getString(idx++));
board.setHitcount(rs.getInt(idx++));
board.setParentno(rs.getInt(idx++));
board.setCategory(rs.getInt(idx++));
result.add(board);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public Board findBy(Integer boardno) {
Board result = null;
Connection conn = DBConn.getConnection();
String sql = "SELECT BOARDNO, TITLE, CONTENT, USERID, REGDATE, HITCOUNT, PARENTNO, CATEGORY\r\n" +
"FROM BOARD\r\n" +
"WHERE BOARDNO = ?\r\n";
try {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardno);
ResultSet rs = pstmt.executeQuery();
while(rs.next()) {
int idx = 1;
result = new Board();
result.setBoardno(rs.getInt(idx++));
result.setTitle(rs.getString(idx++));
result.setContent(rs.getString(idx++));
result.setUserid(rs.getString(idx++));
result.setRegdate(rs.getString(idx++));
result.setHitcount(rs.getInt(idx++));
result.setParentno(rs.getInt(idx++));
result.setCategory(rs.getInt(idx++));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public void modify(Board board) {
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "UPDATE BOARD SET\r\n" +
" TITLE = ?,\r\n" +
" CONTENT = ?,\r\n" +
" REGDATE = SYSDATE\r\n" +
"WHERE BOARDNO = ?";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setString(idx++, board.getTitle());
pstmt.setString(idx++, board.getContent());
pstmt.setInt(idx++, board.getBoardno());
// 실행
pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
}
public int remove(Integer boardno) {
int ret = 0;
Connection connection = DBConn.getConnection();
// 문장 작성
try {
// 전처리 문장을 선언
String sql = "DELETE BOARD WHERE BOARDNO = ?";
// 전처리 문장 생성
PreparedStatement pstmt = connection.prepareStatement(sql);
int idx = 1;
pstmt.setInt(idx++, boardno);
// 실행
ret = pstmt.executeUpdate();
}
catch (SQLException e) {
e.printStackTrace();
}
return ret;
}
}
2. list.jsp
jsp를 노출시키지 않으려고 파일 경로를 WebContent밑이 아닌 WEB-INF안에 둠.
-> (서블릿으로만 접근 가능함.) 컨트롤러를 통해서만 접근 가능.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<jsp:include page="../../../template/header.jsp"/>
${list}
<jsp:include page="../../../template/footer.jsp"/>
- 브라우저에 헤더 풋터 사이에 게시판 목록이 잘 뜨는지 확인.
- 만들어 둔 css를 적용하려면 header.jsp에 css 링크 수정.
<link rel="stylesheet" href="/member_board/assets/css/common.css">
3. board.controller.BoardList.java
package board.controller;
import java.io.IOException;
import java.util.List;
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 board.service.BoardService;
import board.service.BoardServiceImpl;
import board.vo.Board;
@WebServlet("/board/list")
public class BoardList extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BoardService service = new BoardServiceImpl();
List<Board>list = service.list(1); // 자유게시판 목록
// System.out.println(list); 로그 찍는 작업
req.setAttribute("list", list);
req.getRequestDispatcher("../WEB-INF/jsp/board/list.jsp").forward(req, resp);
}
}
- service.list(1)이 아직 return null;이기 때문에 채워주러 감!
- List<Board>list가 담길 곳은 req.setAttribute
(req 요청하는 동안에만 해당 attribute를 지정. 무엇을? "list"이름의 list 타입을)
3-1. BoardServiceImpl.java
package board.service;
import java.util.List;
import board.dao.BoardDao;
import board.vo.Board;
public class BoardServiceImpl implements BoardService{
private BoardDao boardDao = new BoardDao();
@Override
public void write(Board board) {
boardDao.write(board);
}
@Override
public List<Board> list(Integer category) {
return boardDao.list(category);
}
@Override
public Board findBy(Integer boardno) {
return boardDao.findBy(boardno);
}
@Override
public void modify(Board board) {
boardDao.modify(board);
}
@Override
public void remove(Integer boardno) {
boardDao.remove(boardno);
}
}
- 후에 fileDao도 써야 하기 때문에 BoardDao 타입의 변수명을 dao가 아닌 풀네임을 써주자!
14. JSTL(JSP Standard Tag Library)과 EL(Expression Langueage)
(jstl과 lombok 라이브러리 사용)
EL의 개요
JSP 스크립트 태그(<%=%>)를 대신하여 JSP 값들을 좀 더 편리하게 출력하기 위해 제공되는 언어.
목적 : 영역 객체에 저장된 변수에 접근하기 위해 사용.
결국 JSP에서 자바코드를 없애기 위해서 사용하며 JSP 실행 시 EL 인터프리터에 의해 번역되어 실행됨.
자바클래스의 메소드에 대한 호출 가능.
가장 큰 장점 : null 처리
사용법 : test 변수를 표현 할 때 -> ${test}
EL의 내장 객체
pageScope
requestScope
sessionScope
applicationScope
pageContext
↓맵형 객체(key,value) 쌍으로 저장하는 객체
param
paramValues
header
headerValues
cookie (※ 쿠키를 굽는 건 Servlet, 확인은 jsp)
intParam
EL의 연산자
.
[]
()
x ? a : b
empty : 값이 NULL이거나 컬렉션의 사이즈가 0일 경우 true를 반환.
+ - * / %
&& (and), || (or), ! (not)
== (eq)
!= (ne)
< (lt)
> (gt)
<= (le)
>= (ge)
el.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>2021. 3. 19. 오후 12:49:57</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<%
String str = "hello";
pageContext.setAttribute("page", "페이지값");
request.setAttribute("req", "요청값");
session.setAttribute("sess", "세션값");
application.setAttribute("app", "어플값");
pageContext.setAttribute("key", "페이지값");
request.setAttribute("key", "요청값");
session.setAttribute("key", "세션값");
application.setAttribute("key", "어플값");
%>
<p><%=str %></p>
<p>${str}</p> <!-- 안 나옴. -->
<p><%=pageContext.getAttribute("page") %></p>
<p>${page}</p>
<p>${req}</p>
<p>${sess}</p>
<p>${app}</p>
<h3>${key}</h3>
<h3>${sessionScope.key}</h3>
<form>
<input type="text" name="name">
소고기 <input type="checkbox" name="meat" value="beef">
돼지고기 <input type="checkbox" name="meat" value="pork">
닭고기 <input type="checkbox" name="meat" value="chicken">
<button>전송</button>
</form>
<h2>표현식을 사용하였을 때</h2>
<h3>이름: <%=request.getParameter("name") %></h3>
<%--<h3>고기들: <%=request.getParameterValues("meat")[0] %></h3>
<h3>고기들: <%=request.getParameterValues("meat")[1] %></h3>
<h3>고기들: <%=request.getParameterValues("meat")[2] %></h3> --%>
<h2>표현 언어를 사용하였을 때</h2>
<h3>이름: ${param.name}</h3>
<h3>고기들: ${paramValues["meat"][0]}</h3>
<h3>고기들: ${paramValues.meat[1]}</h3>
<h3>고기들: ${paramValues.meat[2]}</h3>
<h3>저장된 쿠키: ${cookie.idsave}</h3> <!-- 챕터 14라 쿠키가 없음ㅋㅋ -->
<h4>\${5+7} : ${5+7}</h4>
<h4>\${5-7} : ${5-7}</h4>
<h4>\${5*7} : ${5*7}</h4>
<h4>\${5/7} : ${5/7}</h4> <!-- 정수가 아닌 실수로 나옴. -->
<h4>\${5%7} : ${5%7}</h4>
</body>
</html>
- ${key} 같은 변수가 여러 개면 가장 좁은 범위로 출력됨. -> 결과 : 페이지값
- 특정 범위를 지정하려면 변수 앞에 ${범위.변수}
- 배열 내용 확인는 법 : 인덱스 사용
연관배열도 됨!! ${paramValues["meat"][0]}
- 자바에서 배열을 사용 할 때 인덱스 범위를 벗어나는 오류를 피하기 위해 고군분투 했는데 EL에선 이 부분이 자유로움.
JSTL core
등록 방법
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
종류
출력 태그 : <c:out> 少 (escape 처리 땐 必)
변수 설정 및 삭제 태그 :<c:set>, <c:remove> 특정 영역
예외 처리 태그 : <c:catch>
조건 처리 태그 : <c:if>, <c:choose> 多, <c:when>, <c:otherwise>
반복 처리 태그 : <c:forEach>, <c:forTokens>
페이지 처리 태그 : <c:import> (include), <c:redirect>, <c:url>, <c:param>
<c:set var="변수명" value="설정값" target="객체" property="값" scope="범위"></c:set>
<c:if test="조건" var="변수명" scope="범위">
<c:choose>
<c:when test="조건"> </c:when>
<c:otherwise></c:otherwise>
</c:choose>
<c:forEach begin="시작 인덱스" end="끝 인덱스" items="객체명" step="증감식" var="변수명" varStatus="상태 변수">
Emp.java
package chapter14;
import lombok.Data;
@Data
public class Emp {
private String ename;
private int sal;
private int deptno;
}
jstl1.jsp
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.HashMap"%>
<%@page import="chapter14.Emp"%>
<%@ 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="ko">
<head>
<meta charset="UTF-8">
<title>2021. 3. 19. 오후 2:28:12</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
</head>
<body>
<%
Emp emp = new Emp();
emp.setEname("SMITH");
emp.setDeptno(101);
emp.setSal(5000);
request.setAttribute("emp", emp);
%>
<jsp:useBean id="emp2" class="chapter14.Emp"/>
<jsp:setProperty property="ename" name="emp2" value="SCOTT"/>
<c:set var="myStr" scope="request" value="Hello World"/>
<pre>
${emp}
${emp.ename}
${emp.sal}
${emp.deptno}
${emp2}
${emp2.ename}
${emp2.sal}
${emp2.deptno}
${myStr}
<c:remove var="emp2"/>
${emp2}
<c:set var="" value="" target="" property="" scope=""></c:set>
</pre>
<h2><c:if>문</c:if></h2>
<c:if test="${5 > 7}">
<h3>5 > 7</h3>
</c:if>
<c:if test="${5 < 7}">
<h3>5 < 7</h3>
</c:if>
<c:set var="score" value="85"/>
<c:choose>
<c:when test="${score >= 90 }">
<h3>A학점</h3>
</c:when>
<c:when test="${score >= 80 }">
<h3>B학점</h3>
</c:when>
<c:when test="${score >= 70 }">
<h3>C학점</h3>
</c:when>
<c:when test="${score >= 60 }">
<h3>D학점</h3>
</c:when>
<c:otherwise><h3>F학점</h3></c:otherwise>
</c:choose>
<%
HashMap<String, String> map = new HashMap<>();
map.put("A", "가");
map.put("B", "나");
map.put("C", "다");
map.put("D", "라");
request.setAttribute("map", map);
ArrayList<Integer> list = new ArrayList<>();
list.add(15);
list.add(5);
list.add(1);
list.add(3);
list.add(20);
request.setAttribute("list", list);
%>
<c:forEach begin="2" end="9" var="i">
<c:forEach var="j" begin="1" end="9">
<h4>${i } * ${j } = ${i*j}</h4>
</c:forEach>
</c:forEach>
<c:forEach items="${map }" var="m">
<h4>${m }</h4>
</c:forEach>
<c:forEach items="${list}" var="l">
<h4>${l}</h4>
</c:forEach>
<c:forTokens items="a, b, c, d, e, f, g, h" delims=", " var="a">
<h4>${a}</h4>
</c:forTokens>
<%-- <%
Emp emp; //c:set과 같은 말.
%> --%>
</body>
</html>
- <pre>는 자동 줄바꿈 태그
회원제 게시판(02) 이어서
- 이 list는 BoardList.java에서 만든
- 23번 줄의 list를 쓴 것. request 상태인 lit.jsp에서 확인하는 것!!
4. list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:include page="../../../template/header.jsp"/>
<table>
<tr>
<th>글번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th>조회수</th>
</tr>
<c:forEach items="${list}" var="board">
<tr>
<td>${board.boardno}</td>
<td><a href="detail?boardno=${board.boardno}">${board.title}</a></td>
<td>${board.userid}</td>
<td>${board.regdate}</td>
<td>${board.hitcount}</td>
</tr>
</c:forEach>
</table>
<jsp:include page="../../../template/footer.jsp"/>
5. 게시글 작성 시간이 하루를 넘기면 날짜를, 넘기지 않으면 작성 시간을 표시하도록.
DB에서 작업 후 BoardDao.java로 가져와서 sql쪽 수정.
-- 목록조회
SELECT BOARDNO, TITLE, CONTENT, USERID,
CASE
WHEN SYSDATE - REGDATE < 1 THEN TO_CHAR(REGDATE, 'HH24:MI:SS')
ELSE TO_CHAR(REGDATE, 'YY/MM/DD')
END REGDATE,
HITCOUNT, PARENTNO, CATEGORY
FROM BOARD
WHERE CATEGORY = 1 AND BOARDNO > 0
ORDER BY 1 DESC;
※ INDEX 꿀팁!
고유 인덱스를 만들 때 BOARDNO 뿐만 아니라 CATEGORY도 같이 건 다음
CREATE UNIQUE INDEX IDX_BOARD_CATEGORY ON BOARD(BOARDNO, CATEGORY);
목록 조회 쿼리에서
WHERE CATEGORY = 1 AND BOARDNO > 0
를 추가해주면
목록 조회 시, 계획 설명을 보면 COST가 줄어 있는 걸 볼 수 있음!
6. Detail.java
package board.controller;
import java.io.IOException;
import java.util.List;
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 board.service.BoardService;
import board.service.BoardServiceImpl;
import board.vo.Board;
@WebServlet("/board/detail")
public class Detail extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BoardService service = new BoardServiceImpl();
Board board = service.findBy(Integer.parseInt(req.getParameter("boardno")));// 자유게시판 목록
req.setAttribute("board", board);
req.getRequestDispatcher("../WEB-INF/jsp/board/detail.jsp").forward(req, resp);
}
}
- req.getParameter()의 타입이 String이고 findBy()의 인자 타입을 int로 바꾸기 위해 Integer.partInt를 해 줌 -> 해당 메소드를 호출한 타입은 Board타입.
6-1. detail.jsp (상세 보기. 글 하나.)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<jsp:include page="../../../template/header.jsp"/>
<table>
<tr>
<th>제목</th>
<td colspan="5">${board.title}</td>
</tr>
<tr>
<th>작성자</th>
<td>${board.userid}</td>
<th>작성일</th>
<td>${board.regdate}</td>
<th>조회수</th>
<td>${board.hitcount}</td>
</tr>
<tr>
<td colspan="6">
${board.content}
</td>
</tr>
</table>
<jsp:include page="../../../template/footer.jsp"/>
7. (수정) header.jsp
<form method="post" action="<%=request.getContextPath()%>/login">
<ul>
<c:if test="${empty member}">
<li><label>아이디 <input type="text" name="id" value="${cookie.idsave.value}"></label></li>
<li><label>비밀번호 <input type="password" name="pw"></label></li>
<li><button>로그인</button></li>
<li>
<label>아이디 저장
<input type="checkbox" name="idsave" ${empty cookie.idsave.value ? '' : 'checked'}>
</label>
</li>
</c:if>
<c:if test="${!empty member}">
<li>${member.name}님 환영합니다. <button formaction="<%=request.getContextPath()%>/logout">로그아웃</button></li>
</c:if>
</ul>
</form>
<script>
$("<input>").attr({type:"hidden", name:"uri", value:location.pathname+location.search}).appendTo("form");
</script>
- id와 idsave에도 value 값이 있어야 함.
- form 태그 action에 <%=request.getContextPath()%>를 하면 프로젝트 이름인 member_board가 나옴.
- 로그인/로그아웃 서블릿을 이용하고 나면 이전 페이지로 와야 함. -> form 태그 밑에 jQuery문 써 줌.
- value 값 의미 : 상대경로와 쿼리스트링이 포함 된 것.
- attr(속성 세 개)를 담은 <input>이 <form> 태그 다음에 붙는 것.(appendTo) - </ul>과 </form> 사이.
8. (수정) Login.java, Logout.java
resp.sendRedirect(req.getParameter("uri"));
- 두 곳 다 sendRedirect 부분을 "uri"로 해 줌.
- 로그인/로그아웃 하고 폼으로 보내서 그 곳으로 sendRedirect.
- 게시글 상세조회 페이지에서 로그인/로그아웃 해도 그대로 상세조회 페이지에 있음.
(원래는 무조건 index.jsp로 갔었음.)
'JSP & Servlet' 카테고리의 다른 글
Part 인터페이스, 회원제 게시판(파일 첨부)(04) 21. 03. 23. (0) | 2021.03.23 |
---|---|
회원제 게시판(03), 파일첨부 21. 03. 22. (0) | 2021.03.22 |
자바빈, 예외처리, 파일 업로드, 회원제 게시판 만들기(01) 21. 03. 18. (0) | 2021.03.18 |
index 페이지에서 로그인, 로그아웃 처리 21. 03. 17. (0) | 2021.03.17 |
회원가입, 로그인, 로그아웃 21. 03. 16. (0) | 2021.03.16 |