학원/servlet jsp

11.23일 (mvc / ajax / jackson object class)

쿠룽지 2023. 11. 24. 00:35
728x90
반응형

 

 

<회원제 게시판 생성>

-회원 등록, 로그인, 게시판을 시작해 확장하는 방식으로 학습

-프로젝트 시 참고할 파일

 

 

 

ch08-mvcPage.war 파일 안에 선생님이 기본적인 servlet과 .jar파일 등은 다 넣어주셨음

수정하면서 배워나가기

 

 


 

 

 

테이블 생성

기본테이블1, 개인정보테이블1, 시퀀스1 생성

탈퇴 시 개인정보테이블 데이터를 삭제하고, 기존 id로는 재가입하지 못하게 기본테이블의 id는 남겨둠

글은 모두 삭제해도 되고, 안해도 됨

 

webapp

sql (folder)

table.sql

--부모테이블 (아이디 남기기)
create table zmember(
 mem_num number not null,
 id varchar2(12) unique not null, --재가입 못하게 방지
 auth number(1) default 2 not null, --회원등급 : 0탈퇴회원,1정지회원,2일반회원,9관리자
 constraint zmember_pk primary key (mem_num)
);

--자식테이블 (개인정보 다 지우기)
create table zmember_detail(
 mem_num number not null,
 name varchar2(30) not null,
 passwd varchar2(35) not null,
 phone varchar2(15) not null,
 email varchar2(50) not null,
 zipcode varchar2(5) not null,
 address1 varchar2(90) not null,
 address2 varchar2(90) not null,
 photo varchar2(150),
 reg_date date default sysdate not null,
 modify_date date, --수정된날짜(첫 등록 시 null 인정/ 변경 시 update)
 constraint zmember_detail_pk primary key (mem_num),
 constraint zmember_detail_fk foreign key (mem_num) references zmember (mem_num)
);
create sequence zmember_seq;

zmember의 mem_num을 zmember_detail의 pk로 지정

 

 


 

 

메인 페이지 만들기

ch08-mvcPage

src/main/java

kr.main.action

MainAction

package kr.main.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;

public class MainAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//JSP 경로 반환
		return "/WEB-INF/views/main/main.jsp";
	}
	
}

 

 

 

 

 

WEB-INF

views (folder)

main (folder) // 쉽게 구분하기 위해 하위폴더 생성

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>메인</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<div class="content-main">
		<h4>회원제 게시판</h4>
	</div>
</div>
</body>
</html>
  • <jsp:include/> 를 이용하여 이미 있는 JPS페이지를 현재 JSP페이지에 포함시킴

 

 

 

 

properties를 하나가 아닌 여러 개를 만들어서 사용할 수 있음 (팀 프로젝트에도 적합)

 

회원 > member.properties

게시판 > board.properties 로 사용할 예정

 

webapp

WEB-INF

member.properties

#대문페이지
/main/main.do=kr.main.action.MainAction

 

 

 

 

 

webapp

index.jsp (초기 화면)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<% 
	response.sendRedirect(request.getContextPath()+"/main/main.do");
%>

 

 


 

<jsp:include> 기법 사용,

별도의 메뉴를 만들어서 내부 메뉴를 include

(header를 만들고 header.jsp에 include)

 

 

 

WEB-INF

views

common (folder)

header.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- header 시작 -->
<div id="main_logo">
	<h1 class="align-center"><a href="${pageContext.request.contextPath}/main/main.do">
    회원제 게시판</a></h1> <%-- uri 방식으로 주소 기재 --%>
</div>
<div id="main_nav">
	<ul>
		<li>
			<a href="${pageContext.request.contextPath}/board/list.do">게시판</a>
		</li>
		<c:if test="${!empty user_num}"> <%-- 데이터가 비어있지 않을 경우 (로그인된 상태) --%>
		<li class="menu-logout">
			[<span>${user_id}</span>]
			<a href="${pageContext.request.contextPath}/member/logout.do">로그아웃</a>
		</li>
		</c:if>
		<c:if test="${empty user_num}"><%-- null이거나 비어있는 경우 --%>
		<li><a href="${pageContext.request.contextPath}/member/registerUserForm.do">회원가입</a></li>
		<li><a href="${pageContext.request.contextPath}/member/loginForm.do">로그인</a></li>
		</c:if>
	</ul>
</div>
<!-- header 끝 -->

 

  • main_logo = 회원제 게시판
    main_nav ul li a = 게시판 

    ${!empty user_num} == user_num이 비어있지 않은 경우 (로그인된 상태)
                                main_nav ul li a = 로그아웃
    ${empty user_num} == user_num이 비어있는 경우 
                                main_nav ul li a = 회원가입 / 로그인

 

  • css로 스타일 적용하고, main.,jsp에 include 

 

 

VO/ DAO 두 테이블을 합쳐서 생성

src/main/java

kr.member.vo

MemberVO

package kr.member.vo;

import java.sql.Date;

public class MemberVO {
	private int mem_num;	//회원번호
	private String id;	//아이디
	private int auth;	//회원 등급
	private String name;	//이름
	private String passwd;	//비밀번호
	private String phone;	//전화번호
	private String email;	//이메일
	private String zipcode;	//우편번호
	private String address1;//주소
	private String address2;//상세주소
	private String photo;	//프로필사진
	private Date reg_date;	//가입일
	private Date modify_date;//수정일
	
	
	public int getMem_num() {
		return mem_num;
	}
	public void setMem_num(int mem_num) {
		this.mem_num = mem_num;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public int getAuth() {
		return auth;
	}
	public void setAuth(int auth) {
		this.auth = auth;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPasswd() {
		return passwd;
	}
	public void setPasswd(String passwd) {
		this.passwd = passwd;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getZipcode() {
		return zipcode;
	}
	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}
	public String getAddress1() {
		return address1;
	}
	public void setAddress1(String address1) {
		this.address1 = address1;
	}
	public String getAddress2() {
		return address2;
	}
	public void setAddress2(String address2) {
		this.address2 = address2;
	}
	public String getPhoto() {
		return photo;
	}
	public void setPhoto(String photo) {
		this.photo = photo;
	}
	public Date getReg_date() {
		return reg_date;
	}
	public void setReg_date(Date reg_date) {
		this.reg_date = reg_date;
	}
	public Date getModify_date() {
		return modify_date;
	}
	public void setModify_date(Date modify_date) {
		this.modify_date = modify_date;
	}
}

 

 

 

 

 

kr.member.dao

MemberDAO (기본 틀 생성)

package kr.member.dao;

public class MemberDAO {
	//싱글턴 패턴
	private static MemberDAO instance = new MemberDAO();
	public static MemberDAO getInstance() {
		return instance;
	}
	private MemberDAO() {}
	
	
	//회원가입
	//ID 중복체크 및 로그인 처리
	//회원 상세 정보
	//회원 정보 수정
	//비밀번호 수정
	//프로필 사진 수정
	//회원 탈퇴 (회원 정보 삭제)
	
	//관리자
	//전체 내용 개수, 검색 내용 개수
	//목록, 검색 목록
	//회원 등급 수정 (회원 정보 중 등급만 변경 가능)
	
	
}

 

 


 

 

회원가입

kr.member.action

RegisterUserFormAction.java

package kr.member.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;

public class RegisterUserFormAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		//JSP 경로 반환
		return "/WEB-INF/views/member/registerUserForm.jsp";
	}
}

 

 

 

 

 

views (folder)

member (folder)

registerUserForm.jsp (회원가입 폼)

 

회원가입 시 daum 주소 찾기를 통해 우편번호와 주소를 자동 기입하고 나머지 주소를 입력하는 식으로 생성

우편번호 검색 코드가 있어서 조금 길다..!

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/>
	<div class="content-main">
		<h2>회원가입</h2>
		<form id="register_form" action="registerUser.do" method="post">
			<ul>
				<li>
					<label for="id">id</label>
					<input type="text" name="id" id="id" maxlength="12" autocomplete="off" class="input-check">
					<input type="button" value="ID중복체크" id="id_check">
					<span id="message_id"></span>
					<div class="form-notice">*영문 또는 숫자(4자~12자)</div>
				</li>
				<li>
					<label for="name">이름</label>
					<input type="text" name="name" id="name" maxlength="10" class="input-check">
				</li>
				<li>
					<label for="passwd">비밀번호</label>
					<input type="password" name="passwd" id="passwd" maxlength="12" class="input-check">
				</li>
				<li>
					<label for="phone">전화번호</label>
					<input type="text" name="phone" id="phone" maxlength="15" class="input-check">
				</li>
				<li>
					<label for="email">이메일</label>
					<input type="email" name="email" id="email" maxlength="50" class="input-check">
				</li>
				<li>
					<label for="zipcode">우편번호</label>
					<input type="text" name="zipcode" id="zipcode" maxlength="5" autocomplete="off" class="input-check">
					<%-- 우편번호 코드 사용 --%>
					<input type="button" onclick="execDaumPostcode()" value="우편번호 찾기">
				</li>
				<li>
					<label for="address1">주소</label>
					<input type="text" name="address1" id="address1" maxlength="30" class="input-check">
				</li>
				<li>
					<label for="address2">나머지 주소</label>
					<input type="text" name="address2" id="address2" maxlength="30" class="input-check">
				</li>
			</ul>
			<div class="align-center">
				<input type="submit" value="등록">
				<input type="button" value="홈으로" onclick="${pageContext.request.contextPath}/main/main.do">
			</div>
		</form>	
	</div>
</div>
<!-- 우편번호 검색 시작 -->
	<!-- iOS에서는 position:fixed 버그가 있음, 적용하는 사이트에 맞게 position:absolute 등을 이용하여 top,left값 조정 필요 -->
<div id="layer" style="display:none;position:fixed;overflow:hidden;z-index:1;-webkit-overflow-scrolling:touch;">
<img src="//t1.daumcdn.net/postcode/resource/images/close.png" id="btnCloseLayer" style="cursor:pointer;position:absolute;right:-3px;top:-3px;z-index:1" onclick="closeDaumPostcode()" alt="닫기 버튼">
</div>

<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
    // 우편번호 찾기 화면을 넣을 element
    var element_layer = document.getElementById('layer');

    function closeDaumPostcode() {
        // iframe을 넣은 element를 안보이게 한다.
        element_layer.style.display = 'none';
    }

    function execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    //(주의)address1에 참고항목이 보여지도록 수정
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    //(수정) document.getElementById("address2").value = extraAddr;
                
                } 
                //(수정) else {
                //(수정)    document.getElementById("address2").value = '';
                //(수정) }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('zipcode').value = data.zonecode;
                //(수정) + extraAddr를 추가해서 address1에 참고항목이 보여지도록 수정
                document.getElementById("address1").value = addr + extraAddr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("address2").focus();

                // iframe을 넣은 element를 안보이게 한다.
                // (autoClose:false 기능을 이용한다면, 아래 코드를 제거해야 화면에서 사라지지 않는다.)
                element_layer.style.display = 'none';
            },
            width : '100%',
            height : '100%',
            maxSuggestItems : 5
        }).embed(element_layer);

        // iframe을 넣은 element를 보이게 한다.
        element_layer.style.display = 'block';

        // iframe을 넣은 element의 위치를 화면의 가운데로 이동시킨다.
        initLayerPosition();
    }

    // 브라우저의 크기 변경에 따라 레이어를 가운데로 이동시키고자 하실때에는
    // resize이벤트나, orientationchange이벤트를 이용하여 값이 변경될때마다 아래 함수를 실행 시켜 주시거나,
    // 직접 element_layer의 top,left값을 수정해 주시면 됩니다.
    function initLayerPosition(){
        var width = 300; //우편번호서비스가 들어갈 element의 width
        var height = 400; //우편번호서비스가 들어갈 element의 height
        var borderWidth = 5; //샘플에서 사용하는 border의 두께

        // 위에서 선언한 값들을 실제 element에 넣는다.
        element_layer.style.width = width + 'px';
        element_layer.style.height = height + 'px';
        element_layer.style.border = borderWidth + 'px solid';
        // 실행되는 순간의 화면 너비와 높이 값을 가져와서 중앙에 뜰 수 있도록 위치를 계산한다.
        element_layer.style.left = (((window.innerWidth || document.documentElement.clientWidth) - width)/2 - borderWidth) + 'px';
        element_layer.style.top = (((window.innerHeight || document.documentElement.clientHeight) - height)/2 - borderWidth) + 'px';
    }
</script>
<!-- 우편번호 검색 끝 -->
</body>
</html>
  • id에 중복체크 button을 눌러서 span태그에 중복인지 아닌지 표시

  • 우편번호 코드 사용 시 text 타입의 input 외에 button input 추가 생성
    onclick="execDaumPostcode()" 실행> 아래 코드 구문으로 이동 ->
    우편번호 코드와 이름을 맞춰서 자동으로 값이 보여지게함 (address1, address2)
    ++ 우편번호 코드는 </body> 전에만 붙여넣으면 됨

 

 

 

 

member.properties

#대문페이지
/main/main.do=kr.main.action.MainAction
#회원관리 사용자
/member/registerUserForm.do=kr.member.action.RegisterUserFormAction

 

 

 

 

 

kr.member.dao

MemberDAO.java (회원가입)

	//회원가입
	public void insertMember(MemberVO member)throws Exception{
		//pk를 만들어서 다른 테이블과 공유해야함 -> 3번 트랜잭션 처리
		Connection conn = null;
		PreparedStatement pstmt = null;
		PreparedStatement pstmt2 = null;
		PreparedStatement pstmt3 = null;
		ResultSet rs = null;
		String sql = null;
		int num = 0; // 시퀀스 번호 저장
		
		try {
			//커넥션풀로부터 커넥션 할당
			conn = DBUtil.getConnection();
			//오토 커밋 해제
			conn.setAutoCommit(false);
			
			//1) 회원 번호(mem_num) 생성
			sql = "SELECT zmember_seq.nextval FROM dual"; // 가상테이블(dual)에서 zmember_seq.nextval 실행
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			if(rs.next()) { //하나의 행이라서 if
				num = rs.getInt(1); // 1=>컬럼 인덱스
			}
			
			//2) zmember 테이블에 데이터 저장
			sql = "INSERT INTO zmember (mem_num,id) VALUES (?,?)";
			pstmt2 = conn.prepareStatement(sql);
			pstmt2.setInt(1, num); //위 회원번호 num값(시퀀스)을 받아서 넣음
			pstmt2.setString(2, member.getId()); //아이디
			pstmt2.executeUpdate();
			
			//3) zmember_detail 테이블에 데이터를 저장
			sql = "INSERT INTO zmember_detail (mem_num,name,passwd,phone,email,zipcode,
            address1,address2) VALUES (?,?,?,?,?,?,?,?)"; //시퀀스는 위에서 생성해서 ?처리
			pstmt3 = conn.prepareStatement(sql);
			
			pstmt3.setInt(1, num); // 회원번호(시퀀스)
			pstmt3.setString(2, member.getName());
			pstmt3.setString(3, member.getPasswd());
			pstmt3.setString(4, member.getPhone());
			pstmt3.setString(5, member.getEmail());
			pstmt3.setString(6, member.getZipcode());
			pstmt3.setString(7, member.getAddress1());
			pstmt3.setString(8, member.getAddress2());
			pstmt3.executeUpdate();
			
			//SQL문 실행 시 모두 성공하면 실행
			conn.commit();
			
		}catch(Exception e) {
			//SQL문이 하나라도 실패하면 rollback
			conn.rollback();
			throw new Exception(e);
		}finally {
			DBUtil.executeClose(null, pstmt3, null);
			DBUtil.executeClose(null, pstmt2, null);
			DBUtil.executeClose(rs, pstmt, conn);
		}
	}

  • 테이블이 2개고 pk를 만들어서 다른 테이블과 공유해야하기 때문에 트랜잭션을 각각 처리해줘야함
    회원번호(시퀀스) 생성을 포함 3개의 pstmt 객체 필요+오토커밋 해제

    1) 회원번호 생성 (zmember_seq)
         num = rs.getInt(1); // 1=>컬럼 인덱스 // 컬럼 인덱스 값을 num으로 줌
    2) zmember 테이블에 데이터 저장 
        1에서 생성한 num을 mem_num에 넣음
    3) zmember_detail 테이블에 데이터 저장
        그외 컬럼

 

 

 

 

kr.member.action

RegisterUserAction.java

package kr.member.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class RegisterUserAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//전송된 데이터 인코딩 처리
		request.setCharacterEncoding("utf-8");
		//자바빈(VO) 생성
		MemberVO vo = new MemberVO();
		vo.setId(request.getParameter("id"));
		vo.setName(request.getParameter("name"));
		vo.setPasswd(request.getParameter("passwd"));
		vo.setPhone(request.getParameter("phone"));
		vo.setEmail(request.getParameter("email"));
		vo.setZipcode(request.getParameter("zipcode"));
		vo.setAddress1(request.getParameter("address1"));
		vo.setAddress2(request.getParameter("address2"));
		
		MemberDAO dao = MemberDAO.getInstance();
		dao.insertMember(vo);
		
		//JSP 경로 반환
		return "/WEB-INF/views/member/registerUser.jsp";
	}

}

 

 

 

 

 

views

member

registerUser.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 완료</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
</head>
<body>
<div class="page-main">
	<jsp:include page="/WEB-INF/views/common/header.jsp"/> <%-- 메뉴 공통적으로 보이기 --%>
	<div class="content-main">
		<h2>회원가입 완료</h2>
		<div class="result-display">
			<div class="align-center">
				회원가입이 완료되었습니다.
				<p> <%-- p태그를 하나만 쓰면 brbr 쓴거랑 똑같음 --%>
				<input type="button" value="홈으로" 
                onclick="location.href='${pageContext.request.contextPath}/main/main.do'">
			</div>
		</div>
	</div>
</div>
</body>
</html>

 

 

 

vo -> 전달 -> dao  == 회원가입(insertmember) 실행

 


 

 

MemberDAO

아이디 중복체크 및 로그인 처리

 

중복 체크 sql문 => DAO

체크 후 ajax처리 => CheckDuplicatedIdAction

	//ID 중복체크 및 로그인 처리
	public MemberVO checkMember(String id)throws Exception{
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		MemberVO member = null;
		String sql = null;
		
		try {
			//커넥션풀로부터 커넥션 할당
			conn = DBUtil.getConnection();
			//SQL문 작성 (조인)
			//zmember와 zmember_detail 조인시 zmember의 누락된 데이터가 보여야 id 중복 체크 가능
			sql = "SELECT * FROM zmember LEFT OUTER JOIN zmember_detail USING(mem_num) WHERE id=?"; 
			//PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			//?에 데이터 바인딩
			pstmt.setString(1, id);
			//SQL문 실행
			rs = pstmt.executeQuery();
			if(rs.next()) {
				member = new MemberVO();
				member.setMem_num(rs.getInt("mem_num"));
				member.setId(rs.getString("id"));
				member.setAuth(rs.getInt("auth"));
				member.setPasswd(rs.getString("passwd"));
				member.setPhoto(rs.getString("photo"));
			}
		}catch(Exception e) {
			throw new Exception(e);
		}finally {
			DBUtil.executeClose(rs, pstmt, conn);
		}
		return member;
	}
  • A LEFT OUTER JOIN B 
    ==> A 기준으로 JOIN하기 때문에 A,B가 모두 값을 가지고 있는 컬럼 + A만 가지고 있는 컬럼이 나옴
    B는 값이 없지만 A에는 값이 있는 컬럼이 나오기 때문에 (ex- A:3 B:null 처리) 중복체크에 유용함

 

 

 

 

kr.member.action

CheckDuplicatedIdAction.java

(

package kr.member.action;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;

import kr.controller.Action;
import kr.member.dao.MemberDAO;
import kr.member.vo.MemberVO;

public class CheckDuplicatedIdAction implements Action{

	@Override
	public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
		//전송된 데이터 인코딩 처리
		request.setCharacterEncoding("utf-8");
		
		String id = request.getParameter("id");
		
		MemberDAO dao = MemberDAO.getInstance();
		MemberVO member = dao.checkMember(id);
		
		Map<String,String> mapAjax = new HashMap<String,String>();
		if(member == null) { //아이디 미중복
			mapAjax.put("result", "idNotFound");
		}else {//아이디 중복
			mapAjax.put("result", "idDuplicated");
		}
		
		//objectmapper만들고 writevalue에 mapajax를 넣으면 문자열을 반환
		//json문자열을 ajax_view에 넘기려고 함
		ObjectMapper mapper = new ObjectMapper(); 
		String ajaxData = mapper.writeValueAsString(mapAjax);
		
		request.setAttribute("ajaxData", ajaxData);
		
		//JSP 경로 반환
		return "/WEB-INF/views/common/ajax_view.jsp";
	}
	
}
  • 1) request로부터 id 데이터 읽어온 후 MemberVO member = dao.checkMember(id)
    아이디 중복 체크 후 결과값 member에 저장

    2) hashmap을 이용 (key, value 쌍으로 데이터 저장 및 출력) 
    member==null일 경우 (아이디 미중복) mapAjax.put("result","idNotFound");
    else (중복) mapAjax.put("result","idDuplicated");

    3) jackson ObjectMapper 클래스 이용, java객체 -> JSON 직렬화 (+역직렬화도 가능)
    String ajaxData = mapper.writeValueAsString(mapAjax);

    4) ajaxData라는 이름으로 ajaxData를 request에 저장
    request.setAttribute("ajaxData", ajaxData);

    5) ajax_view.jsp에 return



    선생님이 lib에 jackson.jar를 추가해줘서 사용 가능..!

 

 

 

 

views

common (folder) // 두 테이블의 공통적인 내용을 넣는 폴더

ajax_view.jsp

<%@ page language="java" contentType="text/plain; charset=UTF-8"
    pageEncoding="UTF-8" trimDirectiveWhitespaces="true"%>
${ajaxData}
  • JSON만을 다루는 파일이라 contentType, trimDirective를 넣어줌

 

 

 

member.properties

#대문페이지
/main/main.do=kr.main.action.MainAction
#회원관리 사용자
/member/registerUserForm.do=kr.member.action.RegisterUserFormAction
/member/registerUser.do=kr.member.action.RegisterUserAction
/member/checkDuplicatedId.do=kr.member.action.CheckDuplicatedIdAction

 

 

 

아직 다 완성하지 않았지만 get방식으로 test 가능!

index.jsp로 메인 페이지 띄우고 주소창에 member/checkDuplicatedId.do?id= ....

... 부분에는 오라클에 회원가입 시 생성한 or 생성하지 않은 아이디 넣기

 

 

[정상 구동 시 화면 출력]

 

{"result":"idDuplicated"} 

or

{"result":"idNotFound"} 

 

 


 


<jsp:include/> 참고 블로그
https://pingfanzhilu.tistory.com/entry/JSP-%EA%B8%B0%EC%B4%88-22-%EC%95%A1%EC%85%98%ED%83%9C%EA%B7%B8-jspinclude

 

[JSP] - 22. <jsp:include> 액션태그 사용법

# 액션태그 사용법 #액션태그 -이미 있는 JSP 페이지를 현재 JSP 페이지에 포함하는 태그이다. -화면의 유지보수 및 재사용성을 높일 수 있다. -다른 JSP의 실행 결과나 코드를 포함할 때 사용한다. -

pingfanzhilu.tistory.com

 

 

 

left outer join 참고 블로그
https://helloworld92.tistory.com/34

 

INNER JOIN / OUTER JOIN / LEFT OUTER JOIN 차이 및 예제

INNER JOIN Inner join은 쉽게말해서교집합 이라고 표현된다. 또한 쿼리는 다음과 같은 방법들로 작성된다. select * from A inner join B on A.번호= B.번호 select * from A,B A.번호=B.번호 INNER JOIN된 결과를 보면 A

helloworld92.tistory.com

 

 

 

Jackson 참고 블로그
https://recordsoflife.tistory.com/599

 

Jackson ObjectMapper 소개

1. 개요 이 사용방법(예제)는 Jackson ObjectMapper 클래스 를 이해하고 Java 개체를 JSON으로 직렬화하고 JSON 문자열을 Java 개체로 역직렬화하는 방법 에 중점을 둡니다 . 일반적으로 Jackson 라이브러리에

recordsoflife.tistory.com

 

728x90
반응형