본문 바로가기
자바과정/DB(Oracle)

MVC 2패턴 : 로그인&회원가입, 게시판 (외래키 추가)

by Parkej 2021. 3. 25.

Mvc203.war
6.65MB

 구성요소 

- 코드가 많아서 파일로 WAR파일로 첨부하고 시연 캡쳐와 디렉토리 구성만 보여드리겠습니다.
- 맨 아래에 실행화면이 있습니다.

 

 기본환경 구성 

- MVC 2 패턴에 대한 이해
- API 구성(jar) : jdbc, cos, servlet-api 
- 개발환경 : 이클립스 
- DBMS : 오라클(11g)
- context의 커넥션풀, web.xml에 매핑과 DB 리소스 등록 
- M(Model) : Bean클래스, DAO 
- C(Controller) : 게시판, 회원 컨트롤러/Board, Member 
- V(View) : 로그인, 회원가입, 게시판/jsp 
 + Action Class, Action(인터페이스), ActionForward(sendRedirect OR forward) 

 

추가해보고 싶은거 
* 외래키(ForignKey)를 이용하여 회원 삭제시 해당 회원이 쓴 글이나 답변이 지워지도록 할 예정. (완료)
 - ON DELETE CASCADE 사용하여 회원이 삭제될 시 게시글도 함께 DB에서 삭제가 됨.

* 글을 정리하다보니까 작성자는 수정과 삭제 버튼이 생기고 글 작성자가 아닐시 수정 삭제버튼이 나타나지 않도록 해보는것도 좋을거 같다.

 


 디렉토리 구성 

- Model & Controller

M & C

1. net.board.action & net.board.db

 

  • BoardFrontController(*.bo) : 매핑된 url(요청:request)을 Model과 연결시켜주기 위한 Servlet 즉, Controller 이것은 응답(response)해줄때 forward 방식인지 sendRedirect 방식인지도 결정해준다.
  • BoardDeleteAction : 게시글 삭제를 위한 액션 클래스
  • BoardDetailAction : 게시글 상세내용표시 액션 클래스
  • BoardAddAction : 새 게시글 작성을 위한 액션 클래스
  • BoardListAction : 게시글 목록을 표시하기 위한 액션 클래스
  • BoardModifyAction : 수정할 내용 입력후 최종 수정버튼을 눌렀을때 처리되는 액션 클래스
  • BoardModifyView : 게시글 상세내용에서 수정을 눌렀을때 이전의 값들이 불러와지는지 판단하는 액션 클래스
  • BoardReplyAction : 게시글의 답변 내용 입력후 최종 답변완료 버튼을 눌렀을 때 처리되는 액션 클래스
  • BoardReplyView : 게시글의 상세내용에서 답변을 눌렀을때 이전의 값들이 불러와지는지 판단하는 액션 클래스
  • BoardBean : 게시판 데이터 클래스 
  • BoardDAO : 비즈니스 로직과 DB에 쿼리문을 날리기 위한 클래스

 

2. net.member.action & net.member.db

 

  • MemberFrontController(*.me) : 매핑된 url(요청:request)을 Model과 연결시켜주기 위한 Servlet 즉, Controller 이것은 응답(response)해줄때 forward 방식인지 sendRedirect 방식인지도 결정해준다.
  • MemberDeleteAction : 회원 삭제를 위한 액션 클래스
  • MemberInfoAction : 회원 정보를 보기위한 액션 클래스
  • MemberJoinAction : 회원가입 처리를 위한 액션 클래스
  • MemberListAction : 회원 목록을 보기위한 액션 클래스
  • MemberLoginAction : 로그인 판단을 위한 액션 클래스 
  • MemberBean : 회원 데이터 클래스
  • MemberDAO : 비즈니스 로직과 DB에 쿼리문을 날리기 위한 클래스

 

 


- View

 

V

1. board(게시판)

  • qna_board_delete.jsp : 삭제 확인을 위한 페이지(로그인 기능을 추가하면서 제외시킴)
  • qna_board_list.jsp : 게시판 목록이 출력되는 페이지
  • qna_board_modify.jsp : 게시판 글 수정을 위한 페이지
  • qna_board_reply.jsp : 게시판 글에 대한 답변을 작성하는 페이지
  • qna_board_view.jsp : 게시판 상세내용을 표시하기 위한 페이지
  • qna_board_write.jsp : 새 글을 작성하기 위한 페이지

2. member(회원가입, 로그인)

  • main.jsp : 로그인과 회원가입 페이지(메인 페이지)
  • joinForm.jsp : 회원가입을 위한 페이지
  • memberInfo.jsp : 관리자로 로그인시 회원정보를 보기위한 페이지
  • memberList.jsp : 관리자로 로그인시 회원목록을 출력하기 위한 페이지

+ template(이름만 템플릿.... 로그아웃을 include 액션 태그로 사용하기 위해 만들었습니다.)

  • logout.jsp : 로그아웃 버튼 페이지

 기본 설정 디렉터리 구성 

톰캣, DB연동, API 세팅


- Web.xml

  <!-- 매핑할거 작성 -->
	<servlet>
		<servlet-name>MemberFrontController</servlet-name>
		<servlet-class>net.member.action.MemberFrontController</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>MemberFrontController</servlet-name>
		<url-pattern>*.me</url-pattern>
	</servlet-mapping>

	<servlet>
		<servlet-name>BoardFrontController</servlet-name>
		<servlet-class>net.board.action.BoardFrontController</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>BoardFrontController</servlet-name>
		<url-pattern>*.bo</url-pattern>
	</servlet-mapping>
  
  
  <!-- DB 리소스 작성 -->
  <resource-ref>
		<description>Connection</description>
		<res-ref-name>jdbc/OracleDB</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>

 

- context

<Context>
	<!-- 환경파일 넣을거임  커넥션 풀 -->
	<Resource name = "jdbc/OracleDB"
		auth = "Container"
		driverClassName = "oracle.jdbc.driver.OracleDriver"
		type = "javax.sql.DataSource"
		url = "jdbc:oracle:thin:@localhost:1521:XE"
		username = "hr"
		password = "hr"
		maxActive = "20"
		maxIdle = "10"
		maxWait="-1"/>
</Context>

 

- sql(테이블 구성)

-- 회원
CREATE TABLE MEMBER(
	MEMBER_NUM NUMBER PRIMARY KEY,
	ID VARCHAR(20),
	PW VARCHAR(20),
	EMAIL VARCHAR(50),
	NAME VARCHAR(30),
	ADDR VARCHAR(200),
	PIN NUMBER,
	YEAR NUMBER,
	MONTH NUMBER,
	DAY NUMBER,
	HOBBY VARCHAR(100),
	INTRO VARCHAR(1000)
);


-- 게시판
create table BOARD(
	BOARD_NUM INT,
	BOARD_NAME VARCHAR(20),
	BOARD_SUBJECT VARCHAR(50),
	BOARD_CONTENT VARCHAR(2000),
	BOARD_FILE VARCHAR(50),
	BOARD_RE_REF INT,
	BOARD_RE_LEV INT,
	BOARD_RE_SEQ INT,
	BOARD_READCOUNT INT,
	BOARD_DATE DATE,
	PRIMARY KEY(BOARD_NUM)
);

-- 테이블 생성 후 설정 (외래키)
ALTER TABLE BOARD ADD CONSTRAINT FK_BOARD_NAME FOREIGN KEY(BOARD_NAME) REFERENCES MEMBER(ID) ON DELETE CASCADE;

-- 제약조건 삭제
ALTER TABLE BOARD DROP CONSTRAINTS FK_BOARD_NAME;

 컨트롤러 코드 

 - BoardFrontController(게시판)

  package net.board.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class BoardFrontController
 */
@WebServlet("/BoardFrontController")
public class BoardFrontController extends HttpServlet implements Servlet{
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public BoardFrontController() {
        super();
        // TODO Auto-generated constructor stub
    }

    protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    	String RequestURI=request.getRequestURI();// 요청이 들어온 전체 uri를 불러온다 "localhost:8080/Day5/~~~.bo"
    	String contextPath=request.getContextPath(); // 내 프로젝트까지 있는 주소만 불러온다. "localhost:8080/Day5/"~~~.bo
    	String command = RequestURI.substring(contextPath.length()); // 전체 URI에서 문자열을 contextPath에 담긴 "localhost:8080/Day5/" 를 자른 주소만 넣는다.

    	ActionForward forward = null;
    	Action action = null;
    	
		 if(command.equals("/BoardWrite.bo")){
			 forward=new ActionForward();

			 forward.setRedirect(false);
			 forward.setPath("./board/qna_board_write.jsp");

		 }else if(command.equals("/BoardReplyAction.bo")){
			 action = new BoardReplyView();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardDelete.bo")){
			 forward=new ActionForward();
			 forward.setRedirect(false);
			 forward.setPath("./board/qna_board_delete.jsp");
			 
		 }else if(command.equals("/BoardModify.bo")){
			 action = new BoardModifyView();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardAddAction.bo")){
			 action  = new BoardAddAction();
			 try {
				 forward=action.execute(request, response );
			 } catch (Exception e) {
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardReplyView.bo")){
			 action = new BoardReplyAction();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardModifyAction.bo")){
			 action = new BoardModifyAction();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardDeleteAction.bo")){
			 action = new BoardDeleteAction();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardList.bo")){
			 action = new BoardListAction(); // 객체만 생성했음. 
			 try{
				 forward = action.execute(request, response); // redirect, forward인지 값을 반환
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }else if(command.equals("/BoardDetailAction.bo")){
			 action = new BoardDetailAction();
			 try{
				 forward=action.execute(request, response);
			 }catch(Exception e){
				 e.printStackTrace();
			 }
		 }

		 
		 
		 if(forward.isRedirect()){ // 센드리다이렉트 방식
			 response.sendRedirect(forward.getPath());
		 }else{ // 포워드
			 RequestDispatcher dispatcher = request.getRequestDispatcher(forward.getPath());
			 dispatcher.forward(request, response);
		 }

    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

}

 

 - MemberFrontController(회원, 로그인)

package net.member.action;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class MemberFrontController
 */
@WebServlet("/MemberFrontController")
public class MemberFrontController extends HttpServlet implements Servlet {

	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		String RequestURI=request.getRequestURI();
		String contextPath=request.getContextPath();
		String command=RequestURI.substring(contextPath.length());

		ActionForward forward = null;
		Action action = null;

		// 로그인 화면
		if(command.equals("/main.me")) {
			forward = new ActionForward();

			forward.setRedirect(false);
			forward.setPath("./member/main.jsp");
		}
		
		// 회원가입 폼
		else if(command.equals("/joinForm.me")) {
			forward = new ActionForward();

			forward.setRedirect(false);
			forward.setPath("./member/joinForm.jsp");
		}
		
		// 회원가입 버튼
		else if(command.equals("/MemberJoinAction.me")) {
			action = new MemberJoinAction();
			try {
				forward = action.execute(request, response);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		// 로그인 클릭시
		else if(command.equals("/MemberLoginAction.me")) {
			action = new MemberLoginAction();
			try {
				forward = action.execute(request, response);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		// 로그인 성공 후 관리자로 회원목록 출력할 시
		else if(command.equals("/MemberList.me")) {
			action = new MemberListAction();
			try {
				forward = action.execute(request, response);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		// 회원 정보를 보고싶을 때 get 방식
		else if(command.equals("/MemberInfo.me")) {
			action = new MemberInfoAction();
			try {
				forward = action.execute(request, response);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		// 회원 삭제
		else if(command.equals("/MemberDeleteAction.me")) {
			action = new MemberDeleteAction();
			try {
				forward = action.execute(request, response);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	
		
		// Action -> controller -> View
		if(forward.isRedirect()){
			response.sendRedirect(forward.getPath());
		}
		else {
			RequestDispatcher dispatcher = request.getRequestDispatcher(forward.getPath());
			dispatcher.forward(request, response);
		}
	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

}

 


 페이지 전송 방식 클래스 코드 

 - Action (인터페이스)

package net.board.action;

import javax.servlet.http.*;

public interface Action {
	
	// 추상메서드
	public ActionForward execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}

 

- ActionForward

package net.board.action;

// 전송방식을 결정하는 클래스
public class ActionForward {
// 포워드 , 리다이렉트
	private boolean isRedirect = false; // redirect인지 foward인지 
	private String path = null; // 실제 저장할 페이지 주소를 담는 변수 
	
	public boolean isRedirect() {
		return isRedirect;
	}
	public void setRedirect(boolean isRedirect) {
		this.isRedirect = isRedirect;
	}
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	
	
}

 


 MODEL (Bean, DAO) 

- Bean 클래스 (코드가 너무 많아 필드명과 일부 코드만 적었습니다. )

// 게시판 : 생성자(필드초기화)와 게터세터 제외
package net.board.db;

import java.sql.Date;

public class BoardBean {
	private int BOARD_NUM;
	private String BOARD_NAME;
	private String BOARD_PASS;
	private String BOARD_SUBJECT;
	private String BOARD_CONTENT;
	private String BOARD_FILE;
	private int BOARD_RE_REF;
	private int BOARD_RE_LEV;
	private int BOARD_RE_SEQ;
	private int BOARD_READCOUNT;
	private Date BOARD_DATE;
}
//--------------------------------------------------------------------------------------------

// 회원 : 생성자(필드초기화) 제외, 일부 게터세터만 표시
package net.member.db;

// 빈즈 클래스 데이터 값 넘기고 받아오는 역할..?
// 기존 회원폼과 같음.

public class MemberBean {
	private int MEMBER_NUM;
	private String id; // 1 아이디 
	private String pw; // 2 비번
	private String email; // 3 이메일
	private String name; // 4 이름
	private String addr[]; // 5 주소
	private String pin; // 6 주민번호
	private String year; // 7 생일
	private String month; // 8 생일
	private String day; // 9 생일
	private String hobby[]; // 10 관심분야
	private String intro; // 11 자기소개 
	
	private String addarr2; //추가
	private String hobbyarr2; // 추가
	
    
	public String getHobbyarr2() {
		return hobbyarr2;
	}
	
	public String getAddarr2() {
		return addarr2;
	}
	
	public void setHobbyarr2(String hobbyarr) {
		this.hobbyarr2 = hobbyarr;
	}
	
	public void setAddarr2(String addarr) {
		this.addarr2 = addarr;
	}
	
	
	public String getHobbyarr() {
		// 나눠진 관심분야를 합쳐서 출력하기 위한 게터
		String hobbyarr = "";
		for(int i=0;i<hobby.length;i++) {
			hobbyarr += hobby[i];
			if(i<hobby.length -1) {
				hobbyarr += ',';
			}
		}
		return hobbyarr;
	}

	
	public String getAddarr() {
    	// 나눠진 주소를 합쳐서 출력하기 위한 게터
		String addarr = "";
		for(int i=0;i<addr.length;i++) {
			addarr += addr[i];
			if(i<addr.length -1) {
				addarr += "<br>";
			}
		}
		return addarr;
	}

	public String[] getHobby() {
		return hobby;
	}

	public void setHobby(String[] hobby) {
		this.hobby = hobby;
	}
}

 

- DAO 클래스(코드가 너무 많아 필드, 생성자만 표시하고 어떤 메소드를 썼는지만 표기)

// 게시판 DAO
package net.board.db;

import ...

public class BoardDAO {
	Connection con;
	PreparedStatement pstmt;
	ResultSet rs;
	// 생성자에 커넥션 풀
	public BoardDAO() {
		try{
			Context init = new InitialContext();
	  		DataSource ds = 
	  	(DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
	  		con = ds.getConnection();
		}catch(Exception ex){
			System.out.println("DB 연결 실패 : " + ex);
			return;
		}
	}
    
    //글의 개수 구하기.
    public int getListCount() {}
    
    //글 목록 보기.	
	public List getBoardList(int page,int limit){}
    
    //글 내용 보기.
	public BoardBean getDetail(int num) throws Exception{}
    
    //글 등록.
	public boolean boardInsert(BoardBean board){}
    
    //글 답변.
	public int boardReply(BoardBean board){}
    
    //글 수정.
	public boolean boardModify(BoardBean modifyboard) throws Exception{}
    
    //글 삭제.
	public boolean boardDelete(int num){}
    
    //조회수 업데이트.
	public void setReadCountUpdate(int num) throws Exception{}
    
    //글쓴이인지 확인.
	public boolean isBoardWriter(String id,int num){}
    
}

//-------------------------------------------------------------------------------------------
// 회원 DAO
package net.member.db;

import ...

public class MemberDAO {
	Connection conn;
	PreparedStatement pstmt;
	ResultSet rs;
	
	public MemberDAO() {
		// 커넥션 풀을 DAO 생성자에 삽입
		try{
			Context init = new InitialContext();
	  		DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
	  		conn = ds.getConnection();
		}catch(Exception ex){
			System.out.println("DB 연결 실패 : " + ex);
			return;
		}
	}
    
    // 회원가입 회원 등록
	public boolean memberInsert(MemberBean member) {}
    
    // 로그인
	public boolean memberLogin(MemberBean member) {}
    
    // 회원목록
	public ArrayList<Object> memberList() {}
    
    // 회원 개인정보 관리자용
	public MemberBean memberInfo(MemberBean m) {}
    
    // 회원 삭제.
	public boolean memberDelete(String id) {}

}

 자바스크립트 코드(회원가입 유효성 검사) 

script.js

var re = /^[a-zA-Z0-9]{4,12}$/; // 아이디와 패스워드가 적합한지 검사할 정규식
var re2 = /^[0-9a-zA-Z]{1,}@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i; // 이메일 조건 정규 표현식
function allCheck(){
  return (idCheck()&&pwCheck()&&checkMail()&&nameCheck()&&checkAddr()&&ymdCheck()&&checkInterest()&&introCheck());
}

// 아이디
function idCheck(){
  var id = document.getElementById("_id");
  // ^ 이 규칙으로 문장을 시작한다. 
  // [문자 규칙을 입력]
  // {} = [] 안에 포함되는 문자가 최소 4개부터 12개까지
  
  if(id.value == ""){
    window.alert("ID를 입력하세요");
    id.focus();
    id.value = "";
    return false;
  }
  else if(!re.test(id.value)){
    window.alert("아이디는 4~12자와 영어 숫자로만 입력");
    id.focus();
    id.value = "";
    return false;
  }
  else return true;
}

// 주소 유효성 판별 체크 (상세주소)
function checkAddr(){
  var sangaddr = document.getElementById("tbox3").value;
  var numaddr = document.getElementById("tbox1").value;
  if(numaddr == ""){
    alert("주소를 입력해 주세요.");
    document.getElementById("tbox1").focus;
    return false;
  }
  if(sangaddr == ""){ //상세주소 없으면 안받아줌
    alert("상세주소를 입력해 주세요.");
    document.getElementById("tbox3").focus();
    return false;
  }
  else return true;
}

// 비밀번호체크
function pwCheck(){
      var pw1 = document.getElementById("_pw");
      var pw2 = document.getElementById("_pw2");

      // 아이디랑 비번이랑 같을 경우
      if (pw1.value == document.getElementById("_id").value)
      {
        alert("아이디랑 비밀번호가 같으면 안됩니다.")
        pw1.focus;
        pw1.value = "";
        pw2.value = "";
        return false;
      }
      // 비번 길이와 영어소대문자 입력값이 올바른지
      // 정규표현식을 true false로 반환할거면 test
      else if (!re.test(pw1.value))
      {
        alert("비밀번호는 4~12자 또는 영문 대소문자만 입력하세요.");
        pw1.focus;
        pw1.value = "";
        pw2.value = "";
        return false;
      }
      // 비번 확인이 잘 안된 경우
      else if (pw1.value != pw2.value)
      {
        alert("비밀번호를 확인해주세요")
        pw1.focus;
        pw1.value = "";
        pw2.value = "";
        return false;
      }
      else return true;
}

// 메일주소
function checkMail(){
  var mail = document.getElementById("_mail");
  if(mail.value == ""){
    alert("이메일 내용을 입력해주세요.");
    mail.focus;
    mail.value = "";
    return false;
  }
  else if(!re2.test(mail.value)){
    alert("이메일 형식을 확인바랍니다.");
    mail.focus;
    mail.value = "";
    return false;
  }
  else return true;  
}

//이름
function nameCheck(){
  var name = document.getElementById("_name");
  var reKor = /^[가-힣]{1,}$/;
  if (name.value == null){
    alert("이름을 입력해주세요");
    name.focus;
    name.value = "";
    return false;
  }
  else if(!reKor.test(name.value)){
    alert("한글을 입력해 주세요.")
    name.focus;
    name.value = "";
    return false;
  }
  else return true;
}


// 주소팝업
function addrFind() {
  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 + ')';
    }
    // 조합된 참고항목을 해당 필드에 넣는다.
    document.getElementById("tbox4").value = extraAddr;
    } else {
      document.getElementById("tbox4").value = '';
    }
    // 우편번호와 주소 정보를 해당 필드에 넣는다.
    document.getElementById('tbox1').value = data.zonecode;
    document.getElementById("tbox2").value = addr;
    // 커서를 상세주소 필드로 이동한다.
    document.getElementById("tbox3").focus();
    }
  }).open();

}

// 주민번호 , 생일
function ymdCheck(){
  var today = new Date();
  var yearcheck = today.getFullYear()
  var ssn = document.getElementById("_ju").value;
  var birth = ssn.substr(0,6);
  var reymd = /^[0-9]{1,}$/; // 숫자만 판별하고 1개이상들어가야함.
  
  // 몇년생인지 구분
  if(!reymd.test(ssn)){
    alert("숫자만 입력하세요.");
    document.getElementById("_ju").focus;
    document.getElementById("_ju").value = "";
    return false;
  }else{
    if(parseInt("20"+birth.substr(0,2)) > yearcheck){
      document.getElementById("birth").value = "19"+ birth.substr(0,2);
    }
    else {
      document.getElementById("birth").value = "20"+ birth.substr(0,2);
    }
    // 월 체크
    month[parseInt(birth.substr(2,2))-1].selected = true;
    day[parseInt(birth.substr(4,2))-1].selected = true;
    
    if(parseInt(ssn[6]) > 4)
    {
      alert("너는 성별이 어떻게 되냐?");
    }
    else if(
      ssn[12] != (11-((2*parseInt(ssn[0])+ 3*parseInt(ssn[1])+ 4*parseInt(ssn[2])+
      5*parseInt(ssn[3])+ 6*parseInt(ssn[4])+ 7*parseInt(ssn[5])+
      8*parseInt(ssn[6])+ 9*parseInt(ssn[7])+ 2*parseInt(ssn[8])+
      3*parseInt(ssn[9])+ 4*parseInt(ssn[10])+5*parseInt(ssn[11]))%11))) 
      {
        alert("주민번호가 매우 수상해~");
    }
    return true;
  }
}

//관심분야
function checkInterest(){
    var interest = document.getElementsByName("hobby")
    var cnt = 0;
    for(var i =0; i<interest.length; i ++){
      if(interest[i].checked){cnt++};
    }
    if (cnt == 0)
    {
      alert("관심분야를 체크해 주세요.")
    return false;
    }
    else return true;
}

// 자기소개
function introCheck(){
  var intro = document.getElementById("my_intro");

  if(intro.value == ""){
    alert("자기소개란에 내용을 입력해주세요.");
    intro.focus;
    return false;
  }
  else return true;
}

 

 


 실행화면 

 

main.me

 

 

 

 


joinFrom.me (회원가입 : 유효성 검사 정상작동/javascript)

 

 

 


joinForm.me (회원가입)

 - 우편번호 찾기는 다음 API 사용

 - 주민번호 입력후 회원가입 버튼을 누를 시 자동으로 생년원일이 DB에 입력됨. (생년월일은 공백으로 놔둠)


테이블의 각 컬럼 타입에 맞게 삽입된 데이터

 

 

 


main.me (로그인)
- 회원가입한 a1234를 이용 비밀번호는 테스트를 위해 text필드로 지정 암호형식으로 할 시 텍스트 타입을 password로 변경

 

 

 


BoardList.bo (게시판 글 목록)
- 로그인 성공 시 보여지는 게시판
- 게시글은 테스트를 위해 사전입력한 데이터


현재 url

 

 

 


BoardWitre.bo (글쓰기)
- 게시판 글 출력에서 오른쪽 하단의 글쓰기 버튼을 누르면 나타나는 view
- 글쓴이는 로그인된 사용자의 아이디가 표시
- 내용 입력 후 등록 버튼 누르면 이동..

 

 

 


BoardList.bo
- 글쓰기 성공시

 

 

 


BoardDetailAction.bo (게시글 상세내용)
- BoardDetailAction.bo?num=2&id=a1234
- get방식으로 num과 id의 값을 넘겨줌
- id는 세션처리하면 되는 부분이라 필요없다고 판단되지만 값이 제대로 넘어가는지 확인하기 위해 테스트 한것.
- 중간중간 id를 get방식으로 넘겨줘할 필요성이 있다고 생각됨 이 부분은 다시 공부할때 보완할 계획.
- 수정 테스트를 위해 수정 버튼을 클릭..

 

 

 


BoardModify.bo (게시글 수정)
- BoardModify.bo?num=2&id=a1234
- 게시글 번호와 로그인 id를 판단하기위해 get방식 사용.
- id는 세션처리하면 된다고 판단해 필요성을 못느꼈지만 값이 잘 전달되는지 확인하기 위해 사용. (곳곳에 필요성을 느낄때도 있음. 이 부분은 다시 공부할때 보완할 예정)
- 수정 버튼을 클릭해 완료하기..

 

수정 내용 입력후 수정버튼 클릭


수정 완료된 뷰

 

 

 


BoardList.bo
- admin 게시글을 삭제해볼까 ?
- admin 게시글 클릭클릭

 

 

 


BoardDetailAction.bo (게시글 상세내용)
- 작성자 admin의 게시글을 들어와봤다.
- url : BoardDetailAction.bo?num=1&id=a1234
- id값은 로그인된 사용자의 id의 값이 출력됨(세션기능이 제대로 동작함.)
- 삭제를 눌러보자.

 

 

 


BoardDeleteAction.bo (게시글 삭제)
- Delete 액션 클래스로 넘어가 게시글을 작성자가 맞는지 판단 
- 게시글 작성자가 아니면 alert창으로 삭제불가 표시
- 확인을 누르면 다시 게시판 글 출력(BoardList.bo) 창으로 이동

 

 

 


BoardList.bo
- 삭제가 되지 않는걸 확인
- 이번엔 자기 글을 삭제해 보자. (id : a1234)

 

 

 


BoardDetailAction.bo

 

 

 


BoardList.bo
- 삭제 기능 정상작동 확인

 

 

 


작성자가 쓰지 않은 게시글을 수정할 시
- 정상작동

 

 

 


BoardReplyAction.bo (게시글 답변)
- BoardReplyAction.bo?num=1&id=a1234
- 로그인한 사용자의 id가 잘 넘어가는것을 확인
- 답변 클릭 


 


게시글 답변 등록 완료

 

 

 


BoardList.bo
- 게시글 기능도 정상


답변 상세내용

 

 

 


관리자(admin)로 로그인해보기
- 로그아웃 후 admin 계정 접속


DB에 등록된 admin 정보


 

 

 


BoardList.bo
- 괸리자 모드 링크가 표시됨
- 눌러보자

 

 

 


MemberList.me
- admin을 제외한 회원의 목록이 출력(DB와 연동해서 member테이블의 회원정보가 출력됨
- 저 회원을 눌러보자. (a1234)

 

 

 


MemberInfo.me
- MemberInfo.me?id=a1234
- 해당 회원의 정보가 잘 뜬다.

 

 

 


MemberDeleteAction.me
- 뒤로가기를 해서 삭제 버튼을 눌러보자


깔끔

 

 

 


로그아웃도 정상
- 로그아웃 클릭해보기 


모든 세션을 종료


 

반응형

댓글