60-1. 사진게시판 상세조회
1. 상세보기 페이지 만들기
thumbnailDetailView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.ArrayList, com.kh.jsp.board.model.vo.*" %>
<%
Board b = (Board)request.getAttribute("b");
ArrayList<Attachment> list = (ArrayList<Attachment>)request.getAttribute("list");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>사진게시판</title>
<style>
#detail-form{
border : 1px solid white;
}
</style>
</head>
<body>
<%@ include file="../common/menubar.jsp" %>
<div class="outer">
<br>
<h2 align="center">상세보기 페이지</h2>
<br>
<table align="center" border="1" id="detail-form">
<tr>
<th width="150">제목</th>
<td colspan="3"><%= b.getBoardTitle() %></td>
</tr>
<tr>
<th>작성자</th>
<td><%= b.getBoardWriter() %></td>
<td>작성일</td>
<td><%= b.getCreateDate() %></td>
</tr>
<tr>
<th>내용</th>
<td colspan="3">
<p style="height:100%;"><%= b.getBoardContent() %></p>
</td>
</tr>
<tr>
<th>대표이미지</th>
<td colspan="3" align="center">
<img src="<%= contextPath %>/<%= list.get(0).getFilePath() %>/<%= list.get(0).getChangeName() %>" alt="대표이미지" id="titleImg" width="250" height="180">
</td>
</tr>
<% for(int i = 1; i < list.size(); i++) { %>
<tr>
<th>상세이미지<%= i %></th>
<td><img src="<%= contextPath %>/<%= list.get(i).getFilePath() %>/<%= list.get(i).getChangeName() %>" alt="상세이미지<%= i %>" id="contentImg<%= i %>" width="150" height="110"></td>
</tr>
<% } %>
</table>
<br>
<br>
<div align="center">
<a href="<%=contextPath %>/list.th" class="btn btn-sm btn-info">목록으로</a>
</div>
<br><br><br>
</div>
</body>
</html>
2. 리스트 목록을 클릭하면 상세보기 페이지로 이동
thumbnailListView.jsp
기존 thumbnail div에 input hidden으로 하나 만들어주고 클릭 시 경로를 보내준다.
<!-- 게시글이 존재할 경우 -->
<% for(Board b : list) { %>
<div class="thumbnail" align="center">
<input type="hidden" value="<%= b.getBoardNo() %>">
<img src="<%= b.getTitleImg() %>">
<p>
No. <%= b.getBoardNo() %> / <%= b.getBoardTitle() %> <br>
조회수 : <%= b.getCount() %>
</p>
</div>
<% } %>
<% } %>
<script>
$(function(){
$('.thumbnail').click(function(){
// 클릭할 때 마다 url요청 => location.href
const bno = $(this).children().eq(0).val();
location.href = '<%= contextPath %>/detail.th?bno=' + bno;
})
})
</script>
3. 게시글 번호를 가지고 조회수 증가요청(이미 해놈)과 상세 정보를 요청할 Controller 만들기
ThumbnailDetailController.java
- 증가요청 UPDATE은 이미 해놓은 것을 사용할 수 있다.
- 상세정보 SELECT는
기존의 메소드를 쓰려고 할 때, 사진게시판은 CATEGORY_NO가 null이라서 조회가 안됨
기존의 selectBoard의 SQL문 INNER JOIN을 OUTER JOIN으로 변경하면
null인 값도 조회되고 기존의 일반게시판 조회에도 문제가 없으니 LEFT (OUTER) JOIN으로 변경한다.
@WebServlet("/detail.th")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 인코딩??
// request.setCharacterEncoding("UTF-8");
// 글번호 뽑아오기
int boardNo = Integer.parseInt(request.getParameter("bno"));
// 가공 ~??
// 서비스요청
// 1. 조회수 증가시키는 요청 (이미 해놓은 것을 써먹음)
int result = new BoardService().increaseCount(boardNo);
// 2. 1번이 성공했을 경우 => Board에서 조회 요청, Attachment에서도 조회 요청
if(result > 0) {
// BOARD테이블 조회 요청
Board b = new BoardService().selectBoard(boardNo);
// 기존에 만들어두었던 selectBoard()를 호출해서 재활용하려 했더니 null값이 나옴
// 일반게시판의 경우 카테고리컬럼에 null인 게시글이 없었지만
// 사진게시판의 경우 카테고리 컬럼의 값이 전부 null이기 때문에 innerJoin으로는 조회가 불가능
// => 카테고리 컬럼을 기준으로 일치하는 컬럼, 그렇지 않은 컬럼도 모두 조회하려고 하면
// 기존의 innerJoin을 outerJoin으로 바꿔주어야 함.
//System.out.println(b); // null이 떴다가 outer로 바꾸니 안뜸
// Attachment에서도 조회를 해야 함.
ArrayList<Attachment> list = new BoardService().selectAttachmentList(boardNo);
// 요청 결과를 Attribute영역에 담기
request.setAttribute("b", b);
request.setAttribute("list", list);
// 응답 View지정
// views/board/thumbnailDetailView.jsp
request.getRequestDispatcher("views/board/thumbnailDetailView.jsp").forward(request, response);
}
}
4. board-mapper SQL문
- 기존의 selectBoard SQL문을 outerJoin으로 바꿔 사용
<entry key="selectBoard">
SELECT
BOARD_NO,
CATEGORY_NAME,
BOARD_TITLE,
BOARD_CONTENT,
USER_ID,
CREATE_DATE
FROM
BOARD
LEFT
JOIN
CATEGORY USING(CATEGORY_NO)
JOIN
MEMBER ON (BOARD_WRITER = USER_NO)
WHERE
BOARD_NO = ?
AND
BOARD.STATUS = 'Y'
</entry>
- 기존의 selectAttachment SQL문을 orderby 정렬해서 사용
<entry key="selectAttachment">
SELECT
FILE_NO,
ORIGIN_NAME,
CHANGE_NAME,
FILE_PATH
FROM
ATTACHMENT
WHERE
REF_BNO = ?
ORDER
BY
FILE_NO ASC
</entry>
5. BoardService.java
// 사진게시판 게시글 상세조회
// 게시글의 첨부사진들 조회
public ArrayList<Attachment> selectAttachmentList(int boardNo){
Connection conn = getConnection();
ArrayList<Attachment> list = new BoardDao().selectAttachmentList(conn, boardNo);
close(conn);
return list;
}
6. BoardDao.java
// 사진게시판 게시글 상세조회
// 게시글의 첨부사진들 조회
public ArrayList<Attachment> selectAttachmentList(Connection conn, int boardNo){
ArrayList<Attachment> list = new ArrayList();
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("selectAttachment");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, boardNo);
rset = pstmt.executeQuery();
while(rset.next()) {
Attachment at = new Attachment();
at.setFileNo(rset.getInt("FILE_NO"));
at.setOriginName(rset.getString("ORIGIN_NAME"));
at.setChangeName(rset.getString("CHANGE_NAME"));
at.setFilePath(rset.getString("FILE_PATH"));
list.add(at);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return list;
}
60-2. AJAX
에이잭스 시작!
Ajax_Project (Dynamic Web Project) 생성
1. WebContent > index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>새로운걸 또 배우는 날(AJAX의 시작)</title>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.min.js"></script>
</head>
<body>
<h1>AJAX개요!</h1>
<p>
Asynchronous JavaScript And XML의 약자로 <br>
서버로부터 데이터를 가져와서 전체 페이지를 다시 만들지 않고
일부만 로드해 내용물만 바꿀 수 있는 기법<br><br>
참고로, 우리가 기존에 a태그를 이용해서 요청 및 form태그를 이용해서 요청한 방식은 동기식 요청! <br>
=> 응답페이지가 돌아와야 그 결과를 볼 수 있었다.(== 페이지가 한 번 깜빡거린다.) <br><br>
비동기식 요청을 보내기 위해서는 AJAX라는 기술이 필요함 <br><br>
* 동기식 / 비동기식 요청 차이 <br>
- 동기식 : 요청 처리 후 해당하는 응답 HTML데이터가 돌아와야만 그 다음 작업이 가능 <br>
만약 서버에서 응답페이지를 돌려주는 시간이 지연되면 무작정 기다려야 함 <br>
전체페이지가 리로드됨(새로고침, 페이지가 기본적으로 한 번 깜빡거리면서 넘어감) <br>
- 비동기식 : 현재 페이지는 그대로 유지하면서 중간중간마다 추가적인 요청을 보내줄 수 있음 <br>
요청을 보낸다고 해서 다른 페이지로 넘어가지 않음(현재 페이지가 그대로 유지) <br>
요청을 보내놓고 그에 해당하는 응답이 돌아올 때까지 현재 페이지에서 다른 작업을 할 수 있음(페이지가 깜빡이지 않음) <br>
예) NAVER 아이디 중복체크 기능, 댓글, 검색어 자동완성 <br><br>
* 비동기식 단점 <br>
- 페이지 내 복잡도가 기하급수적으로 증가 => 에러 발생 시 디버깅이 어려움 <br>
- 요청 후 돌아온 응답데이터를 가지고 현재 페이지에서 새로운 요소를 동적으로 만들어서 뿌려줘야 함<br>
=> DOM요소를 새롭게 만들어내는 구문을 잘 익혀둬야 함 <br><br>
* AJAX구현방식 : JavaScript방식 / jQuery방식 <br>
=> jQuery가 코드가 간결하고 사용하가ㅣ 쉬움 <br><br>
</p>
<pre>
* jQuery에서의 AJAX통신
[ 표현법 ]
$.ajax({
속성명 : 속성값,
속성명 : 속성값,
속성명 : 속성값,
...
});
* 주요속성
- url : 요청할 url(필수로작성) => form태그의 action속성
- type : 요청 전송방식(GET/POST 등등... 생략 시 기본값은 get) => form태그의 method속성
- data : 요청 시 전달할 값({키:밸류, 키:밸류...}) => form태그의 input태그에 입력한 값
- success : AJAX통신 성공 시 실행할 익명함수를 정의
- error : AJAX통신 실패 시 실행할 익명함수를 정의
- complete : AJAX통신을 성공하든 실패하든 무조건 끝나면 실행할 익명함수를 정의
- async : 서버와의 비동기 처리방식 설정 여부(기본값 true)
* 부수적인 속성
</pre>
<hr>
<h1>jQuery방식을 이용한 AJAX테스트</h1>
<h3>1. 버튼 클릭 시 get방식으로 서버에 데이터 전송 및 응답</h3>
입력 : <input type="test" id="input1">
<button id="btn1">요청해줘~~~</button>
<br>
응답 : <label id="output1">현재 응답 없음</label>
<script>
$(function(){
$('#btn1').click(function(){
// 동기식 요청 : location.href = '요청url?쿼리스트링';
// 비동기식 요청
$.ajax({
url : 'jqAjax1.do',
// 동기식이었으면? 404떴지
// 비동기식 => 변화가 없음
data : {input : $('#input1').val()},
type : 'get',
success : function(result){
console.log('AJAX통신성공!');
console.log(result);
$('#output1').text(result);
},
error : function(e){
console.log(e);
alert('AJAX통신 실패!');
},
complete : function(){
console.log("asdfasdf");
}
});
});
})
</script>
<br>
<h3>2. 버튼 클릭 시 POST방식으로 서버에 데이터 전송 및 응답</h3>
이름 : <input type="text" id="input2_1"><br>
나이 : <input type="number" id="input2_2"><br>
<button onclick="ajaxTest2();">요청~</button>
<br>
응답 : <label id="output2">현재 응답 없음</label>
<script>
function ajaxTest2(){
$.ajax({
url : 'jqAjax2.do',
data : {
name : $('#input2_1').val(),
age : $('#input2_2').val()
},
type : 'post',
success : function(result){
console.log(result);
// 배열형태로 넘겼을 때 데이터를 가공해서 눈에 보여지게 하는것은 View의 역할
// $('#output2').text('이름 : ' + result[0] + ', 나이 : ' + result[1]);
// 자바스크립트에서 객체가 가지고 있는 속성값에 접근하는 방법
// 객체명.속성명, 객체명['속성명']
$('#output2').text('이름 : ' + result.name + ', 나이 : ' + result['age']);
},
error : function(){
alert('AJAX통신 실패~');
}
})
}
</script>
<hr>
<h3>3. 서버로 데이터 전송 후, 조회된 객체를 응답데이터로 받기</h3>
회원 번호 입력 : <input type="text" id="input3">
<button onclick="test3();">조회</button>
<div id="output3"></div>
<div>---- ArrayList ----</div>
<table id="output4">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>나이</th>
</tr>
</thead>
<tbody>
<tr>
</tr>
</tbody>
</table>
<script>
function test3(){
$.ajax({
url : 'jqAjax3.do',
data : {num : $('#input3').val()},
success : function(result){
console.log(result);
/*
// VO객체 하나만 넘어온 케이스
const resultStr = '회원번호 : ' + result.memberNo + '<br>'
+ '회원이름 : ' + result.memberName + '<br>'
+ '나이 : ' + result.age + '<br>';
$('#output3').html(resultStr);
*/
},
error : function(){
console.log('AJAX통신실패!');
}
})
}
</script>
br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>
2. AjaxController1.java
mapping값 "/jqAjax1.do"
GET방식
@WebServlet("/jqAjax1.do")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 동기식이었으면?? 빈화면이 나왔겠지
// System.out.println("Hi");
// GET방식 => 인코딩X
// 값 뽑기
// request.getParameter();
String str = request.getParameter("input");
// System.out.println("요청 시 전달값 : " + str);
String responseData = "입력한 값 : " + str + ", 길이 : " + str.length();
// 응답
// 1) 응답데이터에 한글이 있을 경우를 대비해서
// ** 항상 응답데이터에 대해서 인코딩 설정
response.setContentType("text/html; charset=UTF-8");
// 2) 응답 : response.getWriter()
// => 스트림연결(Servlet맛보기할때사용함)
response.getWriter().print(responseData);
}
3. AjaxController2.java
mapping값 "/jqAjax2.do"
POST방식
JSON 라이브러리
https://code.google.com/archive/p/json-simple/downloads
@WebServlet("/jqAjax2.do")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// POST => 인코딩
request.setCharacterEncoding("UTF-8");
// System.out.println("Bye");
// 값 뽑기
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
// VO로 가공 => Service요청
// 결과에 따른 응답
/*
// 한글이 있을 경우를 대비해서 인코딩설정(필수)
response.setContentType("text/html; charset=UTF-8");
// 넘기기
response.getWriter().print(name, age);
print()는 인자값을 하나만 받을 수 있음
*/
// 어쩔 수 없다
// 방법 1) 하나의 데이터로 만들어서 보내기
// 이름 : XXX, 나이 : XX
/*
String responseData = "이름 : " + name + ", 나이 : " + age;
response.setContentType("html/text; charset=UTF-8");
response.getWriter().print(responseData);
*/
// 방법2) AJAX를 이용해서 실제 값을 여러 개 보내고 싶을 때 => 정석
// => JSON(JavaScript Object Notation)
// AJAX통신 시 데이터 전송에 이용되는 포맷형식 중 하나
// 자바스크립트 배열 객체 => [value, value, value...]
// 자바스크립트 일반 객체 => {key:value, key:value, key:value}
/*
* JSON처리 시 사용하는 클래스 종류
* => 자바에서 기본적으로 제공X(라이브러리가 필요 .jar)
*
* https://code.google.com/archive/p/json-simple/downloads
*
* json-simpe01.1.1jar 다운로드 후 dev로 이동 WEB-INF/lib에 붙여넣기
*
* 1. JSONArray => [값1, 값2] 배열형태로 값을 넘길 수 있음
* 2. JSONObject => {키1:밸류1, 키2:밸류2} 객체형태로 값을 넘길 수 있음
*/
/*
JSONArray jArr = new JSONArray(); // [] 자바스크립트 배열형태가 만들어짐
// 요소 추가 => add()
jArr.add(name); // ['홍길동']
jArr.add(age); // ['홍길동', 14]
// 어려운 얘기는 나중에 해줄게요~~~~********************************************************
// 인코딩
// response.setContentType("text/html; charset=UTF-8");
// => text/html로 넘기게되면 문자열로 '["홍길동", 14]'이 전달됨 => list.toString()이랑 같네?
// 응답할 데이터의 컨텐트타입을 json으로 지정
response.setContentType("application/json; charset=UTF-8");
// ▶(2) ['홍길동', 14]로 넘어감
// 보내기
response.getWriter().print(jArr);
*/
// JSONObject를 이용해서 넘기기
JSONObject jObj = new JSONObject(); // {} 자바스크립트 객체 형태가 생성됨
// 객체에 값 담기 => put()
jObj.put("name", name); // {name : "홍길동"}
jObj.put("age", age); // {name : "홍길동", age : 14}
// 값, 저장소, 타입
// 기본자료형, 참조자료형
// 리스트, 셋, 맵
// 변수, 조건문, 반복문
response.setContentType("application/json; charset=UTF-8");
// ▶{name: '홍길동', age: 14}
response.getWriter().print(jObj);
}
4. Member.java VO생성
package com.kh.ajax.model.vo;
public class Member {
private int memberNo;
private String memberName;
private int age;
}
5. AjaxController3.java
@WebServlet("/jqAjax3.do")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// GET방식
// request값 뽑기
int memberNo = Integer.parseInt(request.getParameter("num"));
// DB로부터 데이터를 조회했다는 가정하에 Member객체에 값을 담기
Member m = new Member(memberNo, "홍길동", 50); // <- 얘는 DB조회 결과물 이라고 치자.
// m을 응답
// 형식, 인코딩지정
// response.setContentType("text/html; charset=UTF-8");
// response.getWriter().print(m);
// 내부적으로 toString()호출 문자열 형태로 값이 넘어감
// JSON
// 자바타입객체 => JSON타입 객체로 변환(JSONObject)
/* 하나 넘기는 거
JSONObject jObj = new JSONObject(); // {}
jObj.put("memberNo", m.getMemberNo()); // {memberNo : 123}
jObj.put("memberName", m.getMemberName()); // {memberNo : 123, memberName : "홍길동"}
jObj.put("age", m.getAge()); // {memberNo : 123, memberName : "홍길동", age : 50}
// 응답으로 넘기기
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jObj);
// ▶{memberNo: 1, memberName: '홍길동', age: 50}
*/
// 여러 개의 VO가 들어있는 ArrayList를 넘기기
// ArrayList<Member>
ArrayList<Member> list = new ArrayList();
list.add(new Member(1, "홍길동", 50));
list.add(new Member(2, "고길동", 40));
list.add(new Member(3, "김길동", 30));
// System.out.println(list);
/*
JSONArray jArr = new JSONArray();
for(Member member : list) {
JSONObject jObj = new JSONObject();
jObj.put("memberNo", member.getMemberNo());
jObj.put("memberName", member.getMemberName());
jObj.put("age", member.getAge());
jArr.add(jObj);
}
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jArr);
// ▶(3) [{…}, {…}, {…}]
*/
// GSON을 이용한 다른 방법~
// GSON : Google JSON 라이브러리
// 형식, 인코딩 지정
response.setContentType("application/json; charset=UTF-8");
// Gson 객체 생성
// Gson gson = new Gson();
// Gson gson = new Gson();
// gson.toJson() 호출
// [ 표현법 ] gson.toJson(응답할객체, 응답할스트림);
// gson.toJson(m, response.getWriter());
// => response.getWriter()라는 스트림으로 m이라는 객체를 응답하겠다~
// 자동으로 키값이 전달하는 객체의 필드명이 됨!
// VO 객체 하나만 응답 시 JSONObject{} 형태로 만들어서 응답
// List응답 시 JSONArray{} 형태로 만들어서 응답
// Gson객체 생성 응답 보내기
new Gson().toJson(list, response.getWriter());
// => list라는 객체를 response.getWriter()라는 통로로 응답하겠다.
}
60-3. 회원가입 - ID중복체크
1. memberEnrollFrom.jsp
중복확인 버튼 클릭하면!
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
.outer{
background-color : palegreen;
width : 1000px;
margin : auto;
color : forestgreen;
margin-top : 5px;
}
#enroll-form input{margin : 5px;}
</style>
<title>가입을 해라</title>
</head>
<body>
<%@ include file="../common/menubar.jsp" %>
<!-- ../ : 상위폴더로 이동(view폴더로 이동) -->
<div class="outer">
<br>
<h2 align="center">회원가입</h2>
<!-- localhost:8001 -->
<!-- 아이디, 비밀번호, 이름, 전화번호, 이메일, 주소, 취미 -->
<!-- include는 내 하위 폴더에 있는 모든 jsp나 html에 있는 변수들을 쓸 수 있음. => Path경로/매핑값 -->
<form id="enroll-form" action="<%= contextPath %>/insert.me" method="post">
<table align="center">
<tr>
<td>* 아이디</td>
<td><input type="text" name="userId" maxlength="12" required></td>
<td><button type="button" onclick="idCheck();">중복확인</button></td>
<!-- 중복확인 나중에 AJAX배우고 다음주 수요일..? 금요일쯤..? -->
</tr>
<tr>
<td>* 비밀번호</td>
<td><input type="password" name="userPwd" maxlength="15" required></td>
<td></td>
</tr>
<tr>
<td>* 비밀번호 확인</td>
<td><input type="password" maxlength="15" required></td>
<td></td>
</tr>
<tr>
<td>* 이름</td>
<td><input type="text" name="userName" maxlength="5" required></td>
<td></td>
</tr>
<tr>
<td> 전화번호</td>
<td><input type="text" name="phone" placeholder="-를 포함해서 입력해 주세요."></td>
<td></td>
</tr>
<tr>
<td> 이메일</td>
<td><input type="text" name="email"></td>
<td></td>
</tr>
<tr>
<td> 주소</td>
<td><input type="text" name="address"></td>
<td></td>
</tr>
<tr>
<td> 취미</td>
<td colspan="2">
<input type="checkbox" name="interest" id="sick" value="아프기"><label for="sick">아프기</label>
<input type="checkbox" name="interest" id="recipe" value="레시피"><label for="recipe">레시피</label>
<input type="checkbox" name="interest" id="travel" value="여행"><label for="travel">여행</label>
<br>
<input type="checkbox" name="interest" id="meet" value="소개팅"><label for="meet">소개팅</label>
<input type="checkbox" name="interest" id="tea" value="다도"><label for="tea">다도</label>
<input type="checkbox" name="interest" id="java" value="자바"><label for="java">자바</label>
</td>
</tr>
</table>
<br><br>
<div align="center">
<button type="reset">취소</button>
<button type="submit" disabled>회원가입</button>
</div>
</form>
</div>
<script>
function idCheck(){
// 아이디 인풋태그에 적은 값이 필요함 => 인풋 요소 자체를 먼저 접근!
// console.log($('#enroll-form input[name=userId]'));
const $userId = $('#enroll-form input[name=userId]');
// name이 userId인 요소가 menubar.jsp에도 있기 때문에 조금 더 디테일하게 선택하는 것이 중요함
// AJAX컨트롤러로 요청하기
$.ajax({
url : 'idCheck.me',
data : {checkId : $userId.val()},
// success : result => {
success : function(result){
// console.log(result);
// result 경우의 수 : "NNNNN" / "NNNNY"
if(result == 'NNNNN'){ // 중복된 아이디 == 사용불가
alert('이미 존재하거나 탈퇴한 회원의 아이디입니다.');
$userId.val('').focus();
}
else{ // 중복 X == 사용가능
// 알림창 => confirm();
if(confirm('사용가능한 아이디입니다. 사용하시겠습니까?')){
// 아이디값은 이후에 변경 불가능하도록 ==> readonly
$userId.attr('readonly', true);
// 중복확인 전에 막아두었던 submit버튼을 활성화!
$('#enroll-form button[type=submit]').removeAttr('disabled');
}
}
},
error : function(){
console.log('아이디 중복체크 AJAX통신 실패!');
}
})
}
</script>
</body>
</html>
2. AjaxIdCheckController.java(Servlet)
@WebServlet("/idCheck.me")
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// GET
// 2) request로부터 값 뽑기
String checkId = request.getParameter("checkId");
// 3) VO가공 => 패스~
// 4) Service 요청
int count = new MemberService().idCheck(checkId);
// 5) 결과에 따른 응답~
response.setContentType("text.html; charset-UTF-8");
// AJAX는 데이터만 돌려준다~~ => response.getWriter().print()
// 중복값이 있을 때 count == 1 => 'NNNNN'
// 중복값이 없을 때 count == 0 => 'NNNNY'
if(count > 0) {
response.getWriter().print("NNNNN");
} else {
response.getWriter().print("NNNNY");
}
}
3. MemberService.java
하나의 메소드는 하나의 기능만 수행해야 한다~
나중에 유지보수하기 힘듦.
public int idCheck (String checkId) {
Connection conn = JDBCTemplate.getConnection();
int count = new MemberDao().idCheck(conn, checkId);
JDBCTemplate.close(conn);
return count;
}
4. MemberDao.java
public int idCheck(Connection conn, String checkId) {
int count = 0;
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("idCheck");
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, checkId);
rset = pstmt.executeQuery();
if(rset.next()) {
count = rset.getInt("COUNT(*)");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCTemplate.close(rset);
JDBCTemplate.close(pstmt);
}
return count;
}
5. member-mapping.xml
SQL문
<entry key="idCheck">
SELECT COUNT(*)
FROM MEMBER
WHERE USER_ID = ?
</entry>