#1 JSP Project 04(Blog) - 회원가입
210627~28 유투버 '데어프로그래밍'님 강의 참조
기본적인 웹서버 프로세스
- 사용자 -> 컨트롤러 -> 서비스 -> 레파지토리 -> 서비스 -> 컨트롤러 -> 사용자 순
- 레파지토리에서는 1) DAO 2)네트워크로 나뉘며 DAO관련은 DB와 네트워크 관련은 통신과 관련이 있음
- 서비스/레파지토리를 웹에 붙이면 웹프로젝트 앱에 붙이면 앱 프로젝트가 된다. 웹은 HTML, 앱은 JSON으로 구성되기때문에 일반적인 HTML기반인 JSP 로직이 적용 되지 않는다. (리턴값이 서로 달라야한다)
- 현재 블로그 프로젝트의 레파지토리는 도메인으로 구분하고 이 도메인은 모델/DAO로 구성된다. 즉 웹->컨트롤러->서비스->도메인 순으로 데이터가 움직인다
1. 블로그 메인 화면 만들기
- 메인화면이 있어야 작업하기가 쉽다. 내가 어떻게 구성을하고 어떻게 서버를 연결할지가 크게 보인다
- webapp/board/list.jsp가 메인화면이 된다. w3school로 디자인은 들고오자(BS4->Navbar->Collapsing)
- 여기서 중요한것은 layout폴더를 따로 만들어 header.jsp를 만들고 'include'라는 태그립을 통해 모든 화면에 넣는것!
- 또한 첫 페이지였던 index.jsp 또한 list.jsp로 바뀌도록 코딩
*header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<a class="navbar-brand" href="#">Blog</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="<%=request.getContextPath()%>/user?cmd=joinForm">Join</a>
</li>
<li class="nav-item">
<a class="nav-link" href="<%=request.getContextPath()%>/user?cmd=loginForm">Login</a>
</li>
</ul>
</div>
</nav>
<br>
</body>
</html>
2. 회원가입 화면 구성(joinForm.jsp)
- 똑같이 디자인은 w3school에서 들고오자 (BS4->Form->Stacked)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="../layout/header.jsp"%>
<div class="container">
<form action="/blog/user?cmd=join" method="post">
<div class="form-group">
<input type="text" name="username" class="form-control" placeholder="Enter Username" required/>
</div>
<div class="form-group">
<input type="password" name ="password" class="form-control" placeholder="Enter Password" required/>
</div>
<div class="form-group">
<input type="email" name ="email" class="form-control" placeholder="Enter Email" required/>
</div>
<div class="form-group">
<input type="text" name ="address" class="form-control" placeholder="Enter Address" required/>
</div>
<button type="submit" class="btn btn-primary">Sign-up</button>
</form>
</div>
</body>
</html>
3. 값을 넣어서 회원가입 완료
- 컨트롤러에서 세팅해놓은 값을 받아야한다
- 값을 들고 잘 넘어가는지 테스트도 필수
- 테스트 완료 후 DB에 넣기 (UserDao)
public class UserDao {
public int save(JoinReqDto dto) { //회원가입
//Admin은 DB에서 따로 변경하면 쉽다.
//1) 쿼리문 준비
String sql = "INSERT INTO USER (USERNAME, PASSWORD, EMAIL, ADDRESS, USERROLE, CREATEDATE) VALUES(?,?,?,?,'USER',now())";
PreparedStatement pstmt = null;
//2) DB커넥션 연결
Connection conn = DBConn.getConnection(); //
try {
//3)
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,dto.getUsername());
pstmt.setString(2,dto.getPassword());
pstmt.setString(3,dto.getEmail());
pstmt.setString(4,dto.getAddress());
int result = pstmt.executeUpdate();
return result;
} catch (Exception e) {
e.printStackTrace();
} finally { //try-catch 상관없이 무조건 실행
//코드가 길어지니 DBconn에서 함수로 따로 관리
DBConn.close(conn, pstmt);
}
return -1;
}
*중요포인트
- PreparedStatement 는 일반 Statement보다 향상된 보안 장점이 있다.
- PreparedStatement 는 DB에 쿼리문을 던질 수 있다.
- Statement보다 향상된 메소드와 "?" 로 인해 가독성 + 효율성 이 높다
- PreparedStatement execute를 따로 해야한다 (수정시 executeUpdate, 호출시 executeQuery)
- UserDao를 불러서 쓸 UserService 수정
public class UserService {
private UserDao userDao;
public UserService() {
userDao = new UserDao();
}
public int 회원가입(JoinReqDto dto) {
int result = userDao.save(dto);
return result;
}
***동작 정리!
- 클라이언트가 'join'을 요청
- UserController가 'join'에 할당된 함수를 실행(데이터 가공 및 최종 단계의 userService.회원가입(); 함수에 던짐)
- UserService는 그것을 가지고 단순히 UserDao.save()함수를 호출
- UserDao는 가공된 데이터를 가지고 DB에 쿼리문 + 데이터를 뿌림 (이때 정상작동이면 return 1, 비작동이면 return -1)
- 마찬가지로 UserService도 정상/비정상에따라 return값이 int result로 남음
- 다시 UserController로 돌아가 작동 결과에따라 회원가입 완료 후 페이지 이동 (return ==1 vs return == -1)
*UserController
.....
} else if (cmd.equals("join")) {
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
String address = request.getParameter("address");
JoinReqDto dto = new JoinReqDto();
dto.setUsername(username);
dto.setPassword(password);
dto.setEmail(email);
dto.setAddress(address);
System.out.println(dto);
int result = userSerivce.회원가입(dto);
if (result == 1) {
response.sendRedirect("index.jsp");
} else {
script.back();
}
4. 로그인 실패시 경고 주기(util->Script)
public class Script {
public static void back(HttpServletResponse response, String msg) {
PrintWriter out;
try {
out = response.getWriter();
out.println("<script>");
out.println("alert('"+msg+"');");
out.println("history.back();");
out.println("</script>");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. 주소 API 해보기
API 개념 잡기
- API(Application Programming interface, 응용 프로그램 인터페이스) 응용 프로그램에서 사용 할 수 있으며 운영체제나 프로그래밍 언어가 제공하는 기능을 제어하도록 만든 인터페이스. 주로 파일 제어, 창 제어, 문자 제어 등이 있다.
- 주소API는 시스템에 실시간으로 주소 정보를 연동할 수 있으며, 최종 고객들은 연동된 시스템을 통하여 주소 검색 서비스를 편리하게 이용할 수 있다.
기본 설정
-joinForm에 버튼 추가/ 주소 칸 쓰기 막기/id추가하여 연동
-juso.go.kr -> API신청
-사이트에 올라와있는 JSP 기반으로 화면 구현
-테스트를 꼭 거치자!
-joinForm.jsp 에 스크립트 추가
-JS 의 코드 또한 중요!
<script>
// opener관련 오류가 발생하는 경우 아래 주석을 해지하고, 사용자의 도메인정보를 입력합니다. ("팝업API 호출 소스"도 동일하게 적용시켜야 합니다.)
//document.domain = "abc.go.kr";
function goPopup(){
// 주소검색을 수행할 팝업 페이지를 호출합니다.
// 호출된 페이지(jusopopup.jsp)에서 실제 주소검색URL(https://www.juso.go.kr/addrlink/addrLinkUrl.do)를 호출하게 됩니다.
var pop = window.open("/blog/user/jusoPopup.jsp","pop","width=570,height=420, scrollbars=yes, resizable=yes");
// 모바일 웹인 경우, 호출된 페이지(jusopopup.jsp)에서 실제 주소검색URL(https://www.juso.go.kr/addrlink/addrMobileLinkUrl.do)를 호출하게 됩니다.
//var pop = window.open("/popup/jusoPopup.jsp","pop","scrollbars=yes, resizable=yes");
}
function jusoCallBack(roadFullAddr){
var addressEl = document.querySelector("#address")
addressEl.value = roadFullAddr;
}
</script>