구성요소
- 코드가 많아서 파일로 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
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
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 : 로그아웃 버튼 페이지
기본 설정 디렉터리 구성
- 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) {}
}
자바스크립트 코드(회원가입 유효성 검사)
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 (게시판 글 목록)
- 로그인 성공 시 보여지는 게시판
- 게시글은 테스트를 위해 사전입력한 데이터
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 계정 접속
BoardList.bo
- 괸리자 모드 링크가 표시됨
- 눌러보자
MemberList.me
- admin을 제외한 회원의 목록이 출력(DB와 연동해서 member테이블의 회원정보가 출력됨
- 저 회원을 눌러보자. (a1234)
MemberInfo.me
- MemberInfo.me?id=a1234
- 해당 회원의 정보가 잘 뜬다.
MemberDeleteAction.me
- 뒤로가기를 해서 삭제 버튼을 눌러보자
로그아웃도 정상
- 로그아웃 클릭해보기
반응형
'자바과정 > DB(Oracle)' 카테고리의 다른 글
MVC 2패턴 흐름과 게시판 흐름도 (0) | 2021.03.18 |
---|---|
DB를 활용한 회원가입/로그인 (JDBC, 오라클, MVC 1패턴) (0) | 2021.03.16 |
JDBC 연결 테스트 (0) | 2021.03.15 |
데이터베이스란? 2부(DB와 테이블) (0) | 2021.03.14 |
데이터베이스란? 1부 (0) | 2021.03.14 |
댓글