서블릿을 이용한 회원가입 페이지 만들기
로그인 시 세부메뉴가 보이도록 페이지를 구성해보자. 서버 구조가 보이지 않도록 매핑데이터 web.xml 등록.
web.xml <!-- Servlet 회원가입 --> <servlet> <servlet-name>memberServlet</servlet-name> <servlet-class>com.join.MemberServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>memberServlet</servlet-name> <url-pattern>/join/*</url-pattern> </servlet-mapping> |
테이블 생성하기 (SQL문 작성)
create table mem (userId varchar2(10) not null, userPwd varchar2(10) not null, userName varchar2(20) not null, userBirth date, userTel varchar2(20), constraint pk_mem_userId primary key(userId)); |
DTO 생성하기
DTO생성시 반드시 Getter, Setter 존재해야 함.
EL로 작성시 메소드호출을 하지 않더라도 Getter, Setter를 찾아가 실행하는 것이므로 없으면 오류 발생함
MemberDTO.java package com.join; public class MemberDTO {
private String userId; private String userPwd; private String userName; private String userBirth; private String userTel; //getter/setter 중략 } |
서블릿 클래스 생성하기
MemberServlet.java public class MemberServlet extends HttpServlet{ private static final long serialVersionUID = 1L; protected void forward(HttpServletRequest req, HttpServletResponse resp, String url) throws ServletException, IOException { RequestDispatcher rd = req.getRequestDispatcher(url); rd.forward(req, resp); //포워드 메소드 } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); //doPost호출 } } |
DAO 생성하기(회원가입, 회원정보검색)
MemberDAO.java package com.join; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class MemberDAO { private Connection conn;
//생성자. 의존성주입 public MemberDAO(Connection conn){ this.conn = conn; }
//회원가입 public int insertData(MemberDTO dto){ int result =0; PreparedStatement pstmt = null; String sql; try {
sql = "insert into mem (userId,userPwd,userName, "; sql += "userBirth,userTel) values (?,?,?,?,?) ";
pstmt = conn.prepareStatement(sql); pstmt.setString(1, dto.getUserId()); pstmt.setString(2, dto.getUserPwd()); pstmt.setString(3, dto.getUserName()); pstmt.setString(4, dto.getUserBirth()); pstmt.setString(5, dto.getUserTel());
result = pstmt.executeUpdate(); pstmt.close();
} catch (Exception e) { System.out.println(e.toString()); } return result; }
//회원 데이터 가져오기 public MemberDTO getReadData(String userId){
MemberDTO dto = null; PreparedStatement pstmt = null; ResultSet rs = null; String sql; try {
sql = "select userId,userPwd,userName,userBirth,userTel "; sql += "from mem where userId=?";
pstmt = conn.prepareStatement(sql); pstmt.setString(1, userId);
rs = pstmt.executeQuery();
if(rs.next()){ dto = new MemberDTO(); dto.setUserId(rs.getString("userId")); dto.setUserPwd(rs.getString("userPwd")); dto.setUserName(rs.getString("userName")); dto.setUserBirth(rs.getString("userBirth")); dto.setUserTel(rs.getString("userTel")); }
rs.close(); pstmt.close(); } catch (Exception e) { System.out.println(e.toString()); } return dto; } } |
서블릿 클래스 생성(회원가입시 포워드 페이지 호출)
MemberServlet.java
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); Connection conn = DBCPConn.getConnection(); MemberDAO dao = new MemberDAO(conn);
String cp = req.getContextPath(); String uri = req.getRequestURI(); String url;
if(uri.indexOf("created.do")!=-1){
//회원가입시 포워드 페이지 url = "/member/created.jsp"; forward(req, resp, url);
}else if(uri.indexOf("created_ok.do")!=-1){
MemberDTO dto = new MemberDTO(); dto.setUserId(req.getParameter("userId")); dto.setUserPwd(req.getParameter("userPwd")); dto.setUserName(req.getParameter("userName")); dto.setUserBirth(req.getParameter("userBirth")); dto.setUserTel(req.getParameter("userTel"));
dao.insertData(dto);
//회원가입이 완료되면 인덱스페이지로 이동 url = cp+"/index.jsp"; resp.sendRedirect(url); } } } |
회원가입시 jsp 페이지(created.jsp)
created.jsp <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>회원 가입</title> <link rel="stylesheet" href="<%=cp %>/member/data/style.css" type="text/css"/> <link rel="stylesheet" href="<%=cp %>/member/data/created.css" type="text/css"/> <script type="text/javascript" src="<%=cp %>/member/data/util.js"></script> <script type="text/javascript"> function sendIt(){
var f = document.myForm; str = f.userId.value; if(!str){ alert("아이디를 입력하세요"); f.userId.focus(); return; } f.userId.value = str;
str = f.userPwd.value; if(!str){ alert("패스워드를 입력하세요"); f.userPwd.focus(); return; } f.userPwd.value = str;
str = f.userName.value; if(!str){ alert("이름을 입력하세요"); f.userName.focus(); return; } f.userName.value = str;
str = f.userBirth.value; if(!str){ alert("생년월일을 입력하세요"); f.userBirth.focus(); return; } f.userBirth.value = str;
str = f.userTel.value; if(!str){ alert("연락처를 입력하세요"); f.userTel.focus(); return; } f.userTel.value = str;
f.action = "<%=cp %>/join/created_ok.do"; //가입하기 버튼을 눌렀을 경우 넘어가는 페이지 f.submit(); } </script> </head> <body> <div id="bbs"> <div id="bbs_title"> 회원가입 </div> <form action="" method="post" name="myForm"> <div id="bbsCreated"> <div class="bbsCreated_bottomLine"> <dl> <dt>아 이 디</dt> <dd><input type="text" name="userId" size="35" maxlength="20" class="boxTF"/></dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>패스워드</dt> <dd><input type="password" name="userPwd" size="35" maxlength="20" class="boxTF"/></dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>이 름</dt> <dd><input type="text" name="userName" size="35" maxlength="50" class="boxTF"/></dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>생 일</dt> <dd><input type="text" name="userBirth" size="35" maxlength="50" class="boxTF"/></dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>전 화</dt> <dd><input type="text" name="userTel" size="35" maxlength="50" class="boxTF"/></dd> </dl> </div>
</div>
<div id="bbsCreated_footer"> <input type="button" value="가입하기" class="btn2" onclick="sendIt();"/> <input type="reset" value="다시입력" class="btn2" onclick="document.myForm.userId.focus();"/> <input type="button" value="작성취소" class="btn2" onclick="javascript:location.href='<%=cp %>';"/> </div> </form> </div> </body> </html> |
로그인 페이지(login.jsp)
로그인 오류가 발생할때 메세지
로그인 버튼을 누를 경우 login_ok.do 페이지로 이동하도록 action 설정 login.jsp <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>로그인</title> <link rel="stylesheet" href="<%=cp %>/member/data/style.css" type="text/css"/> <script type="text/javascript"> function login(){
var f = document.myForm; if(!f.userId.value){ alert("아이디를 입력하세요!"); f.userId.focus(); return; } if(!f.userPwd.value){ alert("패스워드를 입력하세요!"); f.userPwd.focus(); return; } f.action = "<%=cp %>/join/login_ok.do"; f.submit(); } </script> </head> <body> <br/><br/> <form action="" method="post" name="myForm"> <table align="center" cellpadding="0" cellspacing="0"> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="30"> <td colspan="2" align="center"><b>로그인</b></td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="25"> <td width="80" bgcolor="#e6e4e6" align="center">아이디</td> <td width="120" style="padding-left: 5px;"> <input type="text" name="userId" maxlength="10" size="15" style="width: 150px; height: 22px;"/> </td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="25"> <td width="80" bgcolor="#e6e4e6" align="center">패스워드</td> <td width="120" style="padding-left: 5px;"> <input type="text" name="userPwd" maxlength="10" size="15" style="width: 150px; height: 22px;"/> </td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="30"> <td colspan="2" align="center"> <input type="button" value="로그인" class="btn2" onclick="login();"> <input type="button" value="취소" class="btn2" onclick="javascript:location.href='<%=cp %>';"> <input type="button" value="회원가입" class="btn2" onclick="javascript:location.href='<%=cp %>/join/created.do';"> </td> </tr> <tr height="30"> <td colspan="2" align="center"> <font color="red"><b>${message }</b></font> 로그인 오류가 발생할 때 메세지 출력 </td> </tr> </table> </form> </body> </html> |
세션에 올릴 정보를 담을 클래스 생성(CustomInfo class)
로그인 성공시 Session 에 id, name 정보를 올려두고, index.jsp를 redirect 진행. 세션에 올릴 정보인 id와 name를 담는 클래스(CustomInfo) 생성 package com.join; public class CustomInfo { private String userId; private String userName;
public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } } |
서블릿 클래스(login.jsp)
MemberServlet.java else if(uri.indexOf("login.do")!=-1){
//로그인시 포워드 페이지 url = "/member/login.jsp"; forward(req, resp, url);
}else if(uri.indexOf("login_ok.do")!=-1){
String userId = req.getParameter("userId"); String userPwd = req.getParameter("userPwd");
MemberDTO dto = dao.getReadData(userId);
//dto==null일 경우 아이디가 없음 //세션에 있는 pwd가 DB의 pwd와 일치하지 않는 경우 if(dto==null||!dto.getUserPwd().equals(userPwd)){ req.setAttribute("message", "아이디 또는 패스워드를 정확히 입력하세요!"); url = "/member/login.jsp"; forward(req, resp, url); return;//로그인 실패시 더이상의 소스코드가 실행되지 않도록 return작성 }
CustomInfo info = new CustomInfo(); info.setUserId(dto.getUserId()); // 저장해놓은 파라미터값(String userId)을 사용해도 오류는 없음 info.setUserName(dto.getUserName());
//자바 클래스에서는 html과는 달리 세션이 없으므로 객체를 달라고 요청을 해야함 HttpSession session = req.getSession(); session.setAttribute("customInfo", info);
url =cp; // http:localhost:8080/study 입력시 index.jsp 실행됨 resp.sendRedirect(url); } |
로그인에 따른 인덱스 페이지(index.jsp)
로그인 전>
로그인 후>
세션 영역의 데이터를 호출하는 방법(customInfo의 userId를 호출하고자 함)
1. <% CustomInfo info = (CustomInfo)session.getAttribute("customInfo"); %>
객체 생성 후 ${info.userId }로 호출
2. ${sessionScope.customInfo.userId }
JSTL 을 사용하여 세션의 값을 바로 가져오도록 작성
index.jsp <%@page import="com.join.CustomInfo"%> <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); //CustomInfo info = (CustomInfo)session.getAttribute("customInfo"); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>인덱스</title> </head> <body> <c:choose> <c:when test="${empty sessionScope.customInfo.userId }"> <b>로그인하면 새로운 세상이 보입니다...</b><br/><br/> </c:when> <c:otherwise> <b>${sessionScope.customInfo.userName }님</b> 반가워요!<br/><br/> </c:otherwise> </c:choose> <c:choose> <c:when test="${empty sessionScope.customInfo.userId }"> 1. 성적처리(JSP)<br/> 2. 게시판(JSP)<br/> 3. 방명록(JSP)<br/> 4. 게시판(Servlet)<br/> </c:when> <c:otherwise> <!--jsp파일의 위치가 서로다를 때 contextpath를 이용하면 됨 --> 1.<a href="<%=cp %>/score/list.jsp">성적처리(JSP)</a><br/> 2.<a href="<%=cp %>/board/list.jsp">게시판(JSP)</a><br/> 3.<a href="<%=cp %>/guest/guest.jsp">방명록(JSP)</a><br/> 4.<a href="<%=cp %>/bbs/list.do">게시판(Servlet)</a><br/> </c:otherwise> </c:choose> 5.<a href="<%=cp %>/sung/list.do">성적처리(Servlet)</a><br/> 항상출력 <br/><br/> <c:choose> <c:when test="${empty sessionScope.customInfo.userId }"> <a href="<%=cp%>/join/created.do">회원가입</a><br/> <a href="<%=cp%>/join/login.do">로그인</a><br/> </c:when> <c:otherwise> <a href="<%=cp %>/join/updated.do">정보수정</a><br/> <a href="<%=cp %>/join/logout.do">로그아웃</a><br/> </c:otherwise> </c:choose> </body> </html> |
서블릿 클래스(logout시 리다이렉트 진행)
로그아웃은 세션에 있는 데이터를 지워야하므로 session 객체 생성필요 MemberServlet.java }else if(uri.indexOf("logout.do")!=-1){
HttpSession session = req.getSession(); session.removeAttribute("customInfo"); session.invalidate(); url= cp;//인덱스페이지 resp.sendRedirect(url);//로그아웃시 인덱스페이지로 리다이렉트 진행 } |
세션 활용해보기 (로그인 성공 시에만 글쓰기가 가능하도록 기능 추가)
게시판(board)에서 로그인이 되었을 경우에만 게시글이 작성되도록 서블릿 클래스에 if문 추가작성 BoardServlet.java if(uri.indexOf("created.do")!=-1){
HttpSession session = req.getSession(); CustomInfo info = (CustomInfo)session.getAttribute("customInfo"); if(info==null){ url = "/member/login.jsp"; forward(req, resp, url); return; }
url= "/sboard/created.jsp"; forward(req, resp, url); } |
세션에 데이터를 올리게 되면 동일 프로젝트내에 있는 모든 페이지에서 데이터에 접근하여 사용이 가능하다.
member 디렉토리에서 로그인 기능을 생성하고 sboard에서 세션에 있는 customInfo 정보를 사용할 수 있다. (study 프로젝트안에 있기 때문)
게시판 작성 페이지(created.jsp)에서 세션에 올라가있는 사용자 이름이 자동으로 출력되도록 value값 설정 ssboard.created.jsp <div class="bbsCreated_bottomLine"> <dl> <dt>작성자</dt> <dd> <input type="text" name="name" size="35" maxlength="20" class="boxTF" value="${sessionScope.customInfo.userName }"/> </dd> </dl> </div> |
회원정보 검색 페이지(searchpw.jsp)
비밀번호 검색을 통해 비밀번호 안내
BoardServlet.java else if(uri.indexOf("searchpw.do")!=-1){
//비밀번호찾기 포워드 페이지 url = "/member/searchpw.jsp"; forward(req, resp, url);
}else if(uri.indexOf("searchpw_ok.do")!=-1){
String userId = req.getParameter("userId"); String userTel = req.getParameter("userTel");
MemberDTO dto = dao.getReadData(userId);
//dto==null일 경우 아이디가 없음 //세션에 있는 pwd가 DB의 pwd와 일치하지 않는 경우 if(dto==null||!dto.getUserTel().equals(userTel)){ req.setAttribute("message", "일치하는 회원정보가 존재하지 않습니다!"); url = "/member/searchpw.jsp"; forward(req, resp, url); return; //로그인 실패시 더이상의 소스코드가 실행되지 않도록 return작성 }else{ String str = "비밀번호는 ["+dto.getUserPwd()+"]입니다."; req.setAttribute("message", str); url = "/member/searchpw.jsp"; forward(req, resp, url); } } |
searchpw.jsp <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>비밀번호찾기</title> <link rel="stylesheet" href="<%=cp %>/member/data/style.css" type="text/css"/> <script type="text/javascript"> function sendIt(){
var f = document.myForm; if(!f.userId.value){ alert("아이디를 입력하세요!"); f.userId.focus(); return; } if(!f.userTel.value){ alert("패스워드를 입력하세요!"); f.userTel.focus(); return; } f.action = "<%=cp %>/join/searchpw_ok.do"; f.submit(); } </script> </head> <body> <br/><br/> <form action="" method="post" name="myForm"> <table align="center" cellpadding="0" cellspacing="0"> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="30"> <td colspan="2" align="center"><b>비밀번호 검색</b></td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="25"> <td width="80" bgcolor="#e6e4e6" align="center">아이디</td> <td width="120" style="padding-left: 5px;"> <input type="text" name="userId" maxlength="10" size="15" style="width: 150px; height: 22px;"/> </td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="25"> <td width="80" bgcolor="#e6e4e6" align="center">전화번호</td> <td width="120" style="padding-left: 5px;"> <input type="text" name="userTel" maxlength="13" size="25" style="width: 150px; height: 22px;"/> </td> </tr> <tr height="2"><td colspan="2" bgcolor="#cccccc"></tr> <tr height="30"> <td colspan="2" align="center"> <input type="button" value="확인" class="btn2" onclick="sendIt();"> <input type="button" value="취소" class="btn2" onclick="javascript:location.href='<%=cp %>/join/login.do';"> <input type="button" value="회원가입" class="btn2" onclick="javascript:location.href='<%=cp %>/join/created.do';"> </td> </tr> <tr height="30"> <td colspan="2" align="center"> <font color="red"><b>${message }</b></font> </td> </tr> <c:choose> <c:when test="${!empty message}"> <tr height="1"><td colspan="2" bgcolor="#cccccc"></tr> <tr><td align="center" colspan="2"> <a href="<%=cp %>/join/searchpw.do;">비밀번호 찾기</a> </td></tr> <tr height="1"><td colspan="2" bgcolor="#cccccc"></tr> </c:when> </c:choose> </table> </form> </body> </html> |
회원정보 수정 페이지(updated.jsp)
로그인 후 회원정보 수정 가능
BoardServlet.java else if(uri.indexOf("updated.do")!=-1){
HttpSession session = req.getSession(); CustomInfo info = (CustomInfo)session.getAttribute("customInfo"); MemberDTO dto = dao.getReadData(info.getUserId()); req.setAttribute("dto", dto);
//회원정보수정 포워드 페이지 url = "/member/updated.jsp"; forward(req, resp, url);
}else if(uri.indexOf("updated_ok.do")!=-1){
HttpSession session = req.getSession(); CustomInfo info = (CustomInfo)session.getAttribute("customInfo");
MemberDTO dto = new MemberDTO();
dto.setUserId(info.getUserId()); dto.setUserPwd(req.getParameter("userPwd")); dto.setUserBirth(req.getParameter("userBirth")); dto.setUserTel(req.getParameter("userTel")); dao.updateData(dto); //회원정보수정 완료후 인덱스페이지로 리다이렉트 url = cp ; resp.sendRedirect(url); } |
updated.jsp <%@ page contentType="text/html; charset=UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <% request.setCharacterEncoding("UTF-8"); String cp = request.getContextPath(); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>정보수정</title> <link rel="stylesheet" href="<%=cp %>/member/data/style.css" type="text/css"/> <link rel="stylesheet" href="<%=cp %>/member/data/created.css" type="text/css"/> <script type="text/javascript" src="<%=cp %>/member/data/util.js"></script> <script type="text/javascript"> function sendIt(){
var f = document.myForm;
str = f.userPwd.value; if(!str){ alert("패스워드를 입력하세요"); f.userPwd.focus(); return; } f.userPwd.value = str;
str = f.userBirth.value; if(!str){ alert("생년월일을 입력하세요"); f.userBirth.focus(); return; } f.userBirth.value = str;
str = f.userTel.value; if(!str){ alert("연락처를 입력하세요"); f.userTel.focus(); return; } f.userTel.value = str;
f.action = "<%=cp %>/join/updated_ok.do"; f.submit(); } </script> </head> <body> <div id="bbs"> <div id="bbs_title"> 회원 정보 수정 </div> <form action="" method="post" name="myForm"> <div id="bbsCreated"> <div class="bbsCreated_bottomLine"> <dl> <dt>아 이 디</dt> <dd>${dto.userId }</dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>이 름</dt> <dd>${dto.userName }</dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>패스워드</dt> <dd><input type="text" name="userPwd" size="35" maxlength="20" value="${dto.userPwd }" class="boxTF"/></dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>생 일</dt> <dd><input type="text" name="userBirth" size="35" maxlength="50" value="${dto.userBirth }" class="boxTF"/>[YYYY-MM-DD]</dd> </dl> </div>
<div class="bbsCreated_bottomLine"> <dl> <dt>전 화</dt> <dd><input type="text" name="userTel" size="35" maxlength="50" value="${dto.userTel }" class="boxTF"/></dd> </dl> </div>
</div>
<div id="bbsCreated_footer"> <input type="button" value="수정하기" class="btn2" onclick="sendIt()"/> <input type="button" value="수정취소" class="btn2" onclick="javascript:location.href='<%=cp %>';"/> </div> </form>
</div> </body> </html> |
'Dev > JSP & Servlet' 카테고리의 다른 글
cos.jar를 이용한 파일 업로드(1)-cos.lib설치, 파일등록, 파일정보 조회 (0) | 2019.02.28 |
---|---|
쿠키의 개요, 생성, 전달, 삭제 (0) | 2019.02.28 |
Servlet - 성적입력 페이지 만들기 (0) | 2019.02.26 |
Servlet - 게시판 만들기 (0) | 2019.02.26 |
Servlet - 서블릿 구조, EL, JSTL, DBCP (0) | 2019.02.25 |