반응형

# MVC07_12 업로드 한 파일 삭제하기

상세 보기 시 업로드 된 파일 삭제하기 작업

## memberList.jsp

<script type="text/javascript">
	function delFile(num, filename) {
		location.href="<c:url value='/fileDel.do'/>?num=" + num + "&filename=" + filename;
	}
</script>

<a href="javascript:delFile('${vo.num}', '${vo.filename}')"><span class="glyphicon glyphicon-remove"></span></a>

## HandlerMapping

package kr.bit.frontcontroller;

import java.util.HashMap;

import kr.bit.controller.Controller;
import kr.bit.controller.*;

public class HandlerMapping {
  private HashMap<String, Controller> mappings;
  public HandlerMapping() {
	  mappings=new HashMap<String, Controller>();
	  mappings.put("/memberList.do", new MemberListController());
	  mappings.put("/memberInsert.do", new MemberInsertController());
	  mappings.put("/memberRegister.do", new MemberRegisterController());
	  mappings.put("/memberContent.do", new MemberContentController());
	  mappings.put("/memberUpdate.do", new MemberUpdateController());
	  mappings.put("/memberDelete.do", new MemberDeleteController());
	  mappings.put("/memberLogin.do", new MemberLoginController());
	  mappings.put("/memberLogout.do", new MemberLogoutController());
	  mappings.put("/memberDbcheck.do", new MemberDbcheckController());
	  mappings.put("/memberAjaxList.do", new MemberAjaxListController());
	  mappings.put("/memberAjaxDelete.do", new MemberAjaxDeleteController());
	  mappings.put("/fileAdd.do", new FileAddController());
	  mappings.put("/fileGet.do", new FileGetController());
	  mappings.put("/fileDel.do", new FileDelController());
  }
  public Controller getController(String key) { // key=>/memberList.do
	  return mappings.get(key);
  }
}

## FileDelController 생성

  • 프로젝트 > src > kr.bit.controller 우 클릭 > class > FileDelController 이름으로 생성
package kr.bit.controller;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;

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

import kr.bit.model.MemberDAO;

public class FileDelController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String ctx = request.getContextPath();
		
		String filename = request.getParameter("filename");
		int num = Integer.parseInt(request.getParameter("num"));
		filename = URLEncoder.encode(filename, "UTF-8");
		filename = filename.replace("+", " ");
		
		String UPLOAD_DIR = "file_repo";
		String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
		File file = new File(uploadPath + "\\" + filename);
		
		// 디렉터리에서 파일 삭제.
		if (file.exists()) {
			file.delete();
			System.err.println("디렉터리에서 파일 삭제.");
		}
		
		// 테이블에서 파일 삭제(null 처리_update)
		MemberDAO dao = new MemberDAO();
		int cnt = dao.memberDeleteFile(num);
				
		return "redirect:" + ctx + "/memberContent.do?num=" + num;
	}

}

## MemmberDAO

// 테이블에서 파일 삭제(null 처리_update)
public int memberDeleteFile(int num) {
  SqlSession session = sqlSessionFactory.openSession();
  int cnt = session.update("memberDeleteFile", num);
  session.commit();	// DB 내용이 수정되므로 commit을 해줘야 한다.
  session.close();	// 연결 종료(반납)
  return cnt;
}

## MemberMapper

<!-- 테이블에서 파일 삭제(null 처리_update) -->
<update id="memberDeleteFile" parameterType="Integer">
  UPDATE member1 
  SET filename = ''
  WHERE num = #{num}
</update>  

 

# MVC07_13 업로드 한 파일 수정하기

첨부파일이 존재하는 경우, 첨부파일이 없는 경우 2가지 경우 존재.

## memberList.jsp 수정

## memberUpdateController 수정

package kr.bit.controller;

import java.io.IOException;

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

import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

public class MemberUpdateController implements Controller{

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String ctx=request.getContextPath();
		
		int num=Integer.parseInt(request.getParameter("num"));
		int age=Integer.parseInt(request.getParameter("age"));
		String email=request.getParameter("email");
		String phone=request.getParameter("phone");
		
		MemberVO vo=new MemberVO();
		if(request.getParameter("mode").equals("fupdate")) {
			String filename = request.getParameter("filename");
			vo.setFilename(filename);
		}
		vo.setNum(num);
		vo.setAge(age);
		vo.setEmail(email);
		vo.setPhone(phone);
		
		MemberDAO dao=new MemberDAO();
		int cnt = -1;
		
		if(request.getParameter("mode").equals("fupdate")) {
			cnt = dao.memberUpdateFile(vo);
		} else {
			cnt = dao.memberUpdate(vo);
		}
				
		String nextPage=null;
		if(cnt>0) {
		    	// 수정성공		        
			nextPage="redirect:"+ctx+"/memberList.do";
		 }else {
		    	// 가입실패-> 예외객체를 만들어서  WAS에게 던지자.
		    	throw new ServletException("not update");	    	
		 }		
		return nextPage;
	}
}

## MemberDAO

// 회원 수정하기(파일정보 포함)
public int memberUpdateFile(MemberVO vo) {
  SqlSession session = sqlSessionFactory.openSession();
  int cnt = session.update("memberUpdateFile", vo);
  session.commit();	// DB 내용이 수정되므로 commit을 해줘야 한다.
  session.close();	// 연결 종료(반납)
  return cnt;
}

## MembmerMapper

<!-- 회원 정보 수정(파일정보 포함) -->
<update id="memberUpdateFile" parameterType="memberVO">
  UPDATE member1 
  SET age = #{age}, email = #{email}, phone = #{phone}, filename = #{filename} where num = #{num}
</update>

 

# MVC07_14 정리

1. 회원 리스트_초기 진입 화면 : http://localhost:8081/MVC07/memberList.do 

  • 해당화면에서 회원 리스트 확인 가능.
  • 로그인 시 본인 정보 삭제 가능.
  • 회원가입 시 or 회원 정보 수정 시 첨부한 이미지 파일 존재할 경우 이미지 표시 가능.
  • 하단 회원 리스트 클릭 시 ajax로 리스트 출력.

2. 회원가입

  • 아이디 입력 후 중복체크 클릭 시 아이디 중복여부 확인 가능.
  • 파일 선택 클릭하여 첨부파일 등록 가능.

3. 회원 상세보기

  • 본인 회원정보 상세보기 시 상단에 이미지 표시
  • 본인 정보는 본인만 수정가능
  • 첨부파일 첨부 or 수정 or 다운로드 가능

4. 작업한 파일

MVC07.war
3.14MB

반응형
반응형

# MVC07_11 파일 다운로드(한글깨짐 방지)

## 상세보기 시 이미지 표시

  • 로그인 한 경우 본인 정보 상세보기 클릭 시 사진 노출되도록 작업
  • memberContent.jsp에 아래와 같이 작업. ${sessionScope.userName}님이 로그인 하셨습니다. 앞에 이미지 가져오는 코드 추가.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>    
<%
  // MemberVO vo=(MemberVO)request.getAttribute("vo");
%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<script type="text/javascript">
	function update() {
		document.form1.action="<c:url value='/memberUpdate.do'/>";
		document.form1.submit();
	}
	
	function frmreset() {
		document.form1.reset();
	}
</script>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
</head>
<body>

<div class="container">
	<h2>상세 화면</h2>
	<div class="panel panel-default">
		<div class="panel-heading">
			<c:if test="${sessionScope.userId != null && sessionScope != '' && sessionScope.userId == vo.id}">
				<label>
					<img src="<c:out value='file_repo/${vo.filename}'/>" width="60px" height="60px" />
					${sessionScope.userName}님이 로그인 하셨습니다.
				</label>
			</c:if>
			<c:if test="${sessionScope.userId == null || sessionScope == '' }">
				<label>안녕하세요.</label>
			</c:if>	
		</div>
		<div class="panel-body">
		<form id="form1" name="form1" class="form-horizontal" method="post">
		<input type="hidden" name="num" value="${vo.num}"/>
			<div class="form-group">
				<label class="control-Label col-sm-2">번호 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.num}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">아이디 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.id}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">비밀번호 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.pass}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">이름 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.name}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">나이 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="age" name="age" value="${vo.age}" style="width:10%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">이메일 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="email" name="email" value="${vo.email}" style="width:30%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">전화번호 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="phone" name="phone" value="${vo.phone}" style="width:30%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">첨부파일 :</label>
				<div class="col-sm-10">
					<input type="file" id="file" name="file" />
					<c:if test="${vo.filename != null && vo.filename != ''}">
						<c:out value='${vo.filename}'/>	
					</c:if>	
					<c:if test="${sessionScope.userId != null && sessionScope.userId == vo.id && vo.filename != null && vo.filename != ''}">
						<span class="glyphicon glyphicon-remove"></span>
					</c:if>				
				</div>
			</div>			
		</form>
		</div>
		<div class="panel-footer" style="text-align: center;">
			<c:if test="${!empty sessionScope.userId}">
				<c:if test="${sessionScope.userId == vo.id}">
					<input type="button" value="수정하기" class='btn btn-primary' onclick="update()"/>
				</c:if>
				<c:if test="${sessionScope.userId != vo.id}">
					<input type="button" value="수정하기" class='btn btn-primary' onclick="update()" disabled="disabled"/>
				</c:if>
			</c:if>
			<input type="button" value="취소" class='btn btn-warning' onclick="frmreset()"/>
			<input type="button" value="리스트" onclick="location.href='${ctx}/memberList.do'" class='btn'/>
		</div>
	</div>
</div>
</body>
</html>

## 상세보기 첨부파일 이미지 다운로드

  • 상세보기 첨부파일 이름 클릭 시 이미지 다운받을 수 있도록 작업

1. memberContent.jsp 에 아래와 같이 작업

<script type="text/javascript">
	function getFile(filename) {
		location.href="<c:url value='/fileGet.do'/>?filename=" + filename;
	}
</script>

<div class="form-group">
  <label class="control-Label col-sm-2">첨부파일 :</label>
  <div class="col-sm-10">
  	<input type="file" id="file" name="file" />
    <c:if test="${vo.filename != null && vo.filename != ''}">
    	<a href="javascript:getFile('${vo.filename}')"><c:out value='${vo.filename}'/></a>	
    </c:if>	
    <c:if test="${sessionScope.userId != null && sessionScope.userId == vo.id && vo.filename != null && vo.filename != ''}">
    	<span class="glyphicon glyphicon-remove"></span>
    </c:if>				
  </div>
</div>

2. HandlerMapping

package kr.bit.frontcontroller;

import java.util.HashMap;

import kr.bit.controller.Controller;
import kr.bit.controller.*;

public class HandlerMapping {
  private HashMap<String, Controller> mappings;
  public HandlerMapping() {
	  mappings=new HashMap<String, Controller>();
	  mappings.put("/memberList.do", new MemberListController());
	  mappings.put("/memberInsert.do", new MemberInsertController());
	  mappings.put("/memberRegister.do", new MemberRegisterController());
	  mappings.put("/memberContent.do", new MemberContentController());
	  mappings.put("/memberUpdate.do", new MemberUpdateController());
	  mappings.put("/memberDelete.do", new MemberDeleteController());
	  mappings.put("/memberLogin.do", new MemberLoginController());
	  mappings.put("/memberLogout.do", new MemberLogoutController());
	  mappings.put("/memberDbcheck.do", new MemberDbcheckController());
	  mappings.put("/memberAjaxList.do", new MemberAjaxListController());
	  mappings.put("/memberAjaxDelete.do", new MemberAjaxDeleteController());
	  mappings.put("/fileAdd.do", new FileAddController());
	  mappings.put("/fileGet.do", new FileGetController());
  }
  public Controller getController(String key) { // key=>/memberList.do
	  return mappings.get(key);
  }
}

3. FileGetController 생성

  • 프로젝트 > src > kr.bit.controller 우 클릭 > class > FileGetController 이름으로 생성
  • 다운로드 준비 시 아래 코드 추가
response.setContentLength((int)file.length());
response.setContentType("application/x-msdownload;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + filename + ";");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
  • 다운로드를 위한 코드는 아래와 같다.
package kr.bit.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

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

public class FileGetController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		String filename = request.getParameter("filename");
		
		String UPLOAD_DIR = "file_repo";
		String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
		
		File file = new File(uploadPath + "\\" + filename);
		
		// 클라이언트로부터 넘어오는 파일 이름에 한글 있는 경우 깨짐 방지.
		filename = URLEncoder.encode(filename, "UTF-8");
		filename = filename.replace("+", " ");
		// 다운로드 준비 (서버에서 클라이언트에게 다운로드 준비 시키는 부분_다운로드 창 띄움)
		response.setContentLength((int)file.length());
		response.setContentType("application/x-msdownload;charset=utf-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + filename + ";");
		response.setHeader("Content-Transfer-Encoding", "binary");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Expires", "0");
		
		// 	실제 다운로드를 하는 부분
		FileInputStream in = new FileInputStream(file);	// 파일 읽기 준비
		OutputStream out = response.getOutputStream();
		byte[] buffer = new byte[104];
		
		while ( true ) {
			int count = in.read(buffer);
			
			if ( count == -1 ) {
				break;
			}
			out.write(buffer, 0, count); // 다운로드 (0% ..... 100%)
		}
		
		in.close();
		out.close();
		
		return null;
	}

}

## 다운로드 테스트

  • 영문, 한글, 공백 이름의 파일 업로드, 다운로드 가능
  • 아래와 같이 다운로드 가능!!

반응형
반응형

# MVC07_07 Ajax를 이용한 파일 업로드 화면 구현 

  • 회원가입 시 사진 업로드 가능하도록 진행 예정.

## memberRegister.jsp

  • 기존 회원가입 폼 내에 첨부파일 input 추가.
<div class="form-group">
  <label class="control-label col-sm-2" for="">첨부파일:</label>
  <div class="col-sm-10">
  	<input type="file" class="control-label" id="file" name="file" >
  </div>
</div>
  • 첨부 파일이 있는 경우 없는 경우 존재, 그에 따른 처리 로직 구현
  • $.ajax 로 파일 업로드 시 processData 와 contentType의 값을 false로 줘야 한다.
function add2() {
if ( $("#file").val() != '' ) {	// 파일 첨부된 경우
  var formData = new FormData();
  formData.append("file", $("input[name=file]")[0].files[0]);
  $.ajax({
    url : "<c:url value='/fileAdd.do'/>",	// 파일 업로드 컨트롤러
    type : "post",
    data : formData,
    processData : false, 
    contentType : false,
    success : function (data) {		// 업로드 된 실제파일 이름을 전달 받기
      $('#filename').val(data);
      document.form1.action="<c:url value='/memberInsert.do'/>";	// text 데이터 저장하는 부분
      document.form1.submit();
    },
    error : function () {alert("error");}
    });			
  } else {	// 파일 첨부 되지 않은 경우.

  }
}
  • 파일 insert 하기위한 신규 테이블 생성
create table member1(
 num int primary key auto_increment,
 id varchar(20) not null,
 pass varchar(20) not null,
 name varchar(30) not null,
 age int not null,
 email varchar(30) not null,
 phone varchar(30) not null,
 filename varchar(100),
 unique key(id)
);

 

# MVC07_08 Ajax를 이용한 파일 업로드

## HandlerMapping

fileAdd.do 관련 추가.

package kr.bit.frontcontroller;

import java.util.HashMap;

import kr.bit.controller.Controller;
import kr.bit.controller.*;

public class HandlerMapping {
  private HashMap<String, Controller> mappings;
  public HandlerMapping() {
	  mappings=new HashMap<String, Controller>();
	  mappings.put("/memberList.do", new MemberListController());
	  mappings.put("/memberInsert.do", new MemberInsertController());
	  mappings.put("/memberRegister.do", new MemberRegisterController());
	  mappings.put("/memberContent.do", new MemberContentController());
	  mappings.put("/memberUpdate.do", new MemberUpdateController());
	  mappings.put("/memberDelete.do", new MemberDeleteController());
	  mappings.put("/memberLogin.do", new MemberLoginController());
	  mappings.put("/memberLogout.do", new MemberLogoutController());
	  mappings.put("/memberDbcheck.do", new MemberDbcheckController());
	  mappings.put("/memberAjaxList.do", new MemberAjaxListController());
	  mappings.put("/memberAjaxDelete.do", new MemberAjaxDeleteController());
	  mappings.put("/fileAdd.do", new FileAddController());
  }
  public Controller getController(String key) { // key=>/memberList.do
	  return mappings.get(key);
  }
}

## 파일 업로드 시 필요한 API

  • API jar 파일 다운로드 후 프로젝트 > lib에 넣기.

1. commons-fileupload

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.3.3

2. commons-io

https://mvnrepository.com/artifact/commons-io/commons-io/2.6

 

## FileAddController 생성

  • 프로젝트 > src > kr.bit.controller 우 클릭 > New > class > FileAddController 이름으로 생성
  • File.separator : 운영체제에 맞게 구분자 ( // , \\ , / ) 를 설정하기 위함.
  • request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR; : 실제 경로를 갖고오기 위함.
  • File currentDirPath = new File(uploadPath); : 업로드 할 경로를 파일 객체로 만들기.
package kr.bit.controller;

import java.io.File;
import java.io.IOException;
import java.util.List;

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

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class FileAddController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
			
		String UPLOAD_DIR = "file_repo";	
		
		// UPLOAD_DIR의 실제 경로 가져오는 것.
		String uploadPath = request.getServletContext().getRealPath("") + File.separator + UPLOAD_DIR;
		File currentDirPath = new File(uploadPath);	// 업로드할 경로를 File 객체로 만들기
		
		if ( !currentDirPath.exists() ) {	// 해당 경로에 파일 없을 경우.
			currentDirPath.mkdir();
		}
		
		// 파일을 업로드 할 때 먼저 저장될 임시 저장경로 설정
		// 파일 업로드 시 필요한 API - commons-fileupload, commons-io
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setRepository(currentDirPath);
		factory.setSizeThreshold(1024*1024); // 파일 용량 지정
		
		String fileName = null;
		
		ServletFileUpload upload = new ServletFileUpload(factory);
		try { // items에 parseRequest로 얻어온 파일 존재. --> FileItem[], FileItem[], FileItem[], ..
			List<FileItem> items = upload.parseRequest(request);	// request 안에 여러개의 파일이 업로드 된 경우. 
			
			for ( int i = 0; i < items.size(); i ++ ) {
				FileItem fileItem = (FileItem)items.get(i);
				
				if ( fileItem.isFormField() ) { // 폼 필드이면 이름, 값만 출력
					System.out.println(fileItem.getFieldName() + " = " + fileItem.getString("utf-8"));
				} else {	// 파일인 경우 업로드.
					if ( fileItem.getSize() > 0 ) {	// 정상 파일 인 경우.
						int idx = fileItem.getName().lastIndexOf("\\");	// \\(Windows일때). /(Linux)
						
						if ( idx == -1 ) {
							idx = fileItem.getName().lastIndexOf("/");
						}
						
						fileName = fileItem.getName().substring(idx + 1);	// 파일 이름.
						
						File uploadFile = new File(currentDirPath + "\\" + fileName);
						
						// 파일 중복체크
						if ( uploadFile.exists() ) {	// 파일 이름 중복인 경우
							fileName = System.currentTimeMillis() + "_" + fileName;
							uploadFile = new File(currentDirPath + "\\" + fileName);
						}
						
						// 임시 경로에서 -> 새로운 경로에 파일 쓰기
						fileItem.write(uploadFile);
					}
				}
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// $.ajax() 쪽으로 업로드 된 최종 파일 이름을 전송.
		response.setContentType("text/html; charset=euc-kr");
		response.getWriter().print(fileName);
		
		return null;
	}

}

 

# MVC07_09  파일 업로드 DataBase에 저장

## 파일 업로드 테스트

  • 이클립스가 실제로 관리 하는 디렉터리 경로는 아래와 같다.
C:\eGovFrame-3.9.0\workspace.edu\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

## 파일 업로드 DataBase에 저장

### memberList.do

  • 파일 있는 경우, 없는 경우 구분 위해 ?mode 추가.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>      
<c:set var="ctx" value="${pageContext.request.contextPath}"/>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
	<script type="text/javascript">
		function add() {
			// form의 데이터 유효성 체크
			document.form1.action="<c:url value='/memberInsert.do'/>";
			document.form1.submit();
		}
		
		function add2() {
			if ( $("#file").val() != '' ) {	// 파일 첨부된 경우
				var formData = new FormData();
				formData.append("file", $("input[name=file]")[0].files[0]);
				$.ajax({
					url : "<c:url value='/fileAdd.do'/>",	// 파일 업로드 컨트롤러
					type : "post",
					data : formData,
					processData : false, 
					contentType : false,
					success : function (data) {		// 업로드 된 실제파일 이름을 전달 받기
						$('#filename').val(data);
						document.form1.action="<c:url value='/memberInsert.do'/>?mode=fadd";	// text 데이터 저장하는 부분
						document.form1.submit();
					},
					error : function () {alert("error");}
				});			
			} else {	// 파일 첨부 되지 않은 경우.
				document.form1.action="<c:url value='/memberInsert.do'/>?mode=add";	// text 데이터 저장하는 부분
				document.form1.submit();
			}
		}
		
		function frmreset() {
			document.form1.reset();
		}
		
		// 아이디 중복체크 버튼 클릭 시 실행
		function doubleCheck() {
			if ( $("#id").val()=='' ) {
				alert("아이디를 입력하세요.");
				$("#id").focus();
				return;
			}
			
			var id = $("#id").val();
			
			$.ajax({
				url : "<c:url value='/memberDbcheck.do'/>", 	// 서버 경로(요청 url)
				type : "POST", 			// GET, POST
				data : {"id" : id}, 	// 서버 요청 시 넘기는 값
				success : dbCheck,		// callback 함수
				error : function() {	// 실패 시.
					alert("error");
				}
			});
		}
		
		// 아이디 중복체크 ajax 성공 시 실행.
		function dbCheck(data) {
			if ( data != "NO" ) {
				alert("중복된 아이디 입니다.");
				$("#id").focus();
			} else {
				alert("사용 가능한 아이디 입니다.");
				$("#id").focus();
			}
		}
	</script>
</head>
<body>
<div class="container">
	<h2>회원가입 화면</h2>
	<div class="panel panel-default">
	<div class="panel-heading">
		<c:if test="${sessionScope.userId != null && sessionScope != '' }">
			<label>${sessionScope.userName}님이 로그인 하셨습니다.</label>
		</c:if>
		<c:if test="${sessionScope.userId == null || sessionScope == '' }">
			<label>안녕하세요.</label>
		</c:if>	
	</div>
	<div class="panel-body">
	<form id="form1" name="form1" class="form-horizontal" method="post">
		<div class="form-group">
			<label class="control-label col-sm-2" for="id">아이디:</label>
			<div class="col-sm-10">
				<table>
					<tr>
						<td>
							<input type="text" class="form-control" id="id" name="id" placeholder="아이디를 입력하세요." >
						</td>
						<td>
							<input type="button" class="btn btn-warning" value="중복체크" onclick="doubleCheck()"/>
						</td>
					</tr>
				</table>					
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="pass">패스워드:</label>
			<div class="col-sm-10">
				<input type="password" class="form-control" id="pass" name="pass" placeholder="비밀번호를 입력하세요." style="width:30%;">
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="name">이름:</label>
			<div class="col-sm-10">
				<input type="text" class="form-control" id="name" name="name" placeholder="이름을 입력하세요." style="width:30%;">
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="age">나이:</label>
			<div class="col-sm-10">
				<input type="text" class="form-control" id="age" name="age" placeholder="나이입력" style="width:12%;">
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="email">이메일:</label>
			<div class="col-sm-10">
				<input type="email" class="form-control" id="email" name="email" placeholder="이메일을 입력하세요." style="width:30%;">
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="phone">전화번호:</label>
			<div class="col-sm-10">
				<input type="text" class="form-control" id="phone" name="phone" placeholder="전화번호를 입력하세요." style="width:30%;">
			</div>
		</div>
		<div class="form-group">
			<label class="control-label col-sm-2" for="">첨부파일:</label>
			<div class="col-sm-10">
				<input type="file" class="control-label" id="file" name="file" >
			</div>
		</div>
		<input type="hidden" id="filename" name="filename" value="" />
	</form>
	</div>
	<div class="panel-footer" style="text-align: center;">
		
		<c:if test="${sessionScope.userId == null || sessionScope.userId == ''}">
			<input type="button" value="등록" class='btn btn-primary' onclick="add2()"/>
		</c:if>
		<c:if test="${sessionScope.userId != null && sessionScope.userId != ''}">
			<input type="button" value="등록" class='btn btn-primary' onclick="add()" disabled="disabled"/>
		</c:if>
		<input type="button" value="취소" class='btn btn-warning' onclick="frmreset()"/>
		<input type="button" value="리스트" onclick="location.href='${ctx}/memberList.do'" class='btn'/>
	</div>
</div>
</div>
</body>
</html>

### MemberVO

  • 파일이름 추가.
package kr.bit.model;
//회원(Object)->MemberVO
public class MemberVO {
	 private int num;
	 private String id;
	 private String pass;
	 private String name;
	 private int age;
	 private String email;
	 private String phone;
	 private String filename;
	 public MemberVO() {   }
	 
	public MemberVO(String id, String pass, String name, int age, String email, String phone) {
		super();
		this.id = id;
		this.pass = pass;
		this.name = name;
		this.age = age;
		this.email = email;
		this.phone = phone;
	}
	public MemberVO(int num, String id, String pass, String name, int age, String email, String phone) {
		super();
		this.num = num;
		this.id = id;
		this.pass = pass;
		this.name = name;
		this.age = age;
		this.email = email;
		this.phone = phone;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPass() {
		return pass;
	}
	public void setPass(String pass) {
		this.pass = pass;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getFilename() {
		return filename;
	}
	public void setFilename(String filename) {
		this.filename = filename;
	}
	@Override
	public String toString() {
		return "MemberVO [num=" + num + ", id=" + id + ", pass=" + pass + ", name=" + name + ", age=" + age + ", email="
				+ email + ", phone=" + phone + ", filename=" + filename + "]";
	} 
}

 ### MemberInsertController

  • ?mode 에 따른 파일이름 받는 로직 추가.
package kr.bit.controller;

import java.io.IOException;

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

import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

public class MemberInsertController implements Controller{
	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
        
		String ctx=request.getContextPath();
		
		String id=request.getParameter("id");
		String pass=request.getParameter("pass");
		String name=request.getParameter("name");
		int age=Integer.parseInt(request.getParameter("age")); // "40"->40
		String email=request.getParameter("email");
		String phone=request.getParameter("phone");
		//파라메터수집(VO)
		//MemberVO vo=new MemberVO(id, pass, name, age, email, phone);
		MemberVO vo=new MemberVO();
		
		// 파일 존재하는 경우만 파일 이름 추가.
		if ( request.getParameter("mode").equals("fadd") ) {
			String filename = request.getParameter("filename");
			vo.setFilename(filename);
		}
		
		vo.setId(id);
		vo.setPass(pass);
		vo.setName(name);
		vo.setAge(age);
		vo.setEmail(email);
		vo.setPhone(phone);			
	    MemberDAO dao=new MemberDAO();
	    int cnt = -1;
	    // 파일 존재하는 경우
	    if ( request.getParameter("mode").equals("fadd") ) {	
	    	cnt = dao.memberInsertFile(vo);	// 파일 이름을 저장해야 하는 경우.
	    } else {
	    	cnt = dao.memberInsert(vo);		// 파일 이름을 저장할 필요 없는 경우
	    }
	    
	    //PrintWriter out=response.getWriter();
	    String nextPage=null;
	    if(cnt>0) {
	    	// 가입성공
	        //out.println("insert success");	// 다시 회원리스트 보기로 가야된다.(/MVC03/memberList.do)
	    	nextPage="redirect:"+ctx+"/memberList.do";
	    }else {
	    	// 가입실패-> 예외객체를 만들어서  WAS에게 던지자.
	    	throw new ServletException("not insert");	    	
	    }	
		return nextPage;
	}

}

### MemberDAO

  • 파일 존재하는 경우 insert 추가
// 회원 가입 기능 (파일 업로드 한 경우)
public int memberInsertFile(MemberVO vo) {
  SqlSession session = sqlSessionFactory.openSession();
  int cnt = session.insert("memberInsertFile", vo);
  session.commit();	// DB 내용이 수정되므로 commit을 해줘야 한다.
  session.close();	// 연결 종료(반납)
  return cnt;
}

### MemberMapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namerspace는 이름. -->
<mapper namespace="kr.bit.mybatis.MemberMapper">
  
    <!-- 회원 리스트(전체) -->
    <select id="memberList" resultType="memberVO">
	    SELECT *
    	FROM member1
    </select>
    
    <!-- 회원 가입 -->
    <insert id="memberInsert" parameterType="memberVO">
        INSERT INTO member1(id, pass, name, age, email, phone) 
        values(#{id}, #{pass}, #{name}, #{age}, #{email}, #{phone})
    </insert>
    
    <!-- 회원 가입 -->
    <insert id="memberInsertFile" parameterType="memberVO">
        INSERT INTO member1(id, pass, name, age, email, phone, filename) 
        values(#{id}, #{pass}, #{name}, #{age}, #{email}, #{phone}, #{filename})
    </insert>
    
    <!-- 회원 삭제 -->
    <delete id="memberDelete" parameterType="Integer">
        DELETE 
        FROM member1
        WHERE num = #{num}
    </delete>
    
    <!-- 회원 상세보기 -->
    <select id="memberContent" parameterType="Integer" resultType="memberVO">
        SELECT *
        FROM member1
        WHERE num = #{num}
    </select>
    
    <!-- 회원 정보 수정 -->
    <update id="memberUpdate" parameterType="memberVO">
        UPDATE member1 
        SET age = #{age}, email = #{email}, phone = #{phone} where num = #{num}
    </update>
    
    <!-- 회원 로그인 -->
    <select id="memberLogin" parameterType="memberVO" resultType="String">
        SELECT name
        FROM member1
        WHERE id = #{id}
        AND  pass = #{pass}
    </select>
    
    <!-- 아이디 중복확인 -->
    <select id="memberDbcheck" parameterType="memberVO" resultType="String">
        SELECT id
        FROM member1
        WHERE id = #{id}
    </select>
    
</mapper>

 

# MVC07_10 회원 리스트에 이미지 보이기

## memberList.jsp

  • 이미지 등록 시 표시되도록 jsp 수정
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>    
<%@ page import="java.util.*" %>
<%
     // ArrayList<MemberVO> list=(ArrayList<MemberVO>)request.getAttribute("list");
%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
<style type="text/css">
	table td {
		vertical-align: middle !important;
	}
</style>
<script type="text/javascript">
	$(document).ready(function(){
		<c:if test="${!empty msg}">
			alert("${msg}");
			<c:remove var="msg" scope="session"/>
		</c:if>
	});

	function deleteFn(num) {
		location.href="${ctx}/memberDelete.do?num="+num; // ?num=12
	}
	
	function check() {
		if ($('#user_id').val() == '') {
			alert("아이디를 입력해주세요.");
			return false;
	 	}
		
		if ($('#password').val() == '') {
			alert("비밀번호를 입력해주세요.");
			return false;
		}
		
		return true;
	}
	
	function logout() {
		location.href="<c:url value='/memberLogout.do'/>";
	}
	
	function memberList() {
		// var html = $("#collapse1 .panel-body").html();
		// alert(html);
		
		$.ajax({
			url : "<c:url value='/memberAjaxList.do'/>",	// 서버 요청
			type : "get",
			dataType : "json",
			success : resultHtml,	// 회원 리스트로 받기([{}, {}, {}])
			error : function() { error("error"); }
		});	
	}	
	
	function resultHtml(data) {
		var html="<table class='table table-hover'>";
		html+="<tr>";
		html+="<th>번호</th>";
		html+="<th>아이디</th>";
		html+="<th>비밀번호</th>";
		html+="<th>이름</th>";
		html+="<th>나이</th>";
		html+="<th>이메일</th>";
		html+="<th>전화번호</th>";
		html+="<th>삭제</th>";
		html+="</tr>";
		
		// 반복문 처리	[{}, {}, {}]
		$.each(data, function(index, obj) {
			html+="<tr>";
			html+="<td>" + obj.num + "</td>";
			html+="<td>" + obj.id + "</td>";
			html+="<td>" + obj.pass + "</td>";
			html+="<td>" + obj.name + "</td>";
			html+="<td>" + obj.age + "</td>";
			html+="<td>" + obj.email + "</td>";
			html+="<td>" + obj.phone + "</td>";
			html+="<td><input type='button' value='삭제' class='btn btn-warning' onclick='delFn(" + obj.num + ")'></td>";
			html+="</tr>";
		});
		html+="</table>";
		
		$("#collapse1 .panel-body").html(html);
	}
	
	function delFn(num) {
		$.ajax({
			url : "<c:url value='/memberAjaxDelete.do'/>",
			type : "get",
			data : {"num" : num},
			success : memberList,
			error : function() { alert("error"); }			
		});
	}
</script>
</head>
<body>

<div class="container">
	<h2>회원관리 시스템</h2>
	<div class="panel panel-default">
		<div class="panel-heading">
		<c:if test="${sessionScope.userId == null || sessionScope.userId == ''}">
			<form class="form-inline" action="${ctx}/memberLogin.do" method="post">
			    <div class="form-group">
					<label for="user_id">ID:</label>
					<input type="text" class="form-control" id="user_id" name="user_id">
			    </div>
			    <div class="form-group">
					<label for="pwd">Password:</label>
					<input type="password" class="form-control" id="password" name="password">
			    </div>
			    <button type="submit" class="btn btn-default" onclick="return check()">로그인</button>
			</form>
		</c:if>
		<c:if test="${sessionScope.userId != null && sessionScope.userId != ''}">
			${sessionScope.userName}님 환영합니다.
			<button type="submit" class="btn btn-warning" onclick="logout()" >로그아웃</button>
		</c:if>	
		</div>
	<div class="panel-body">
		<div class="table-responsive">          
			<table class="table table-hover">
			<thead>
				<tr>
					<th>번호</th>
					<th>아이디</th>
					<th>비밀번호</th>
					<th>이름</th>
					<th>나이</th>
					<th>이메일</th>
					<th>전화번호</th>
					<th>이미지</th>
					<th>삭제</th>
				</tr>
			</thead>
			<tbody>
				<c:forEach var="vo" items="${list}">
				<tr>
		    	    <td>${vo.num}</td>
		    	    <td><a href="${ctx}/memberContent.do?num=${vo.num}">${vo.id}</a></td>
		    	    <td>${vo.pass}</td>
		    	    <td>${vo.name}</td>
		    	    <td>${vo.age}</td>
		    	    <td>${vo.email}</td>
		    	    <td>${vo.phone}</td>
		    	    <td>
		    	    	<c:if test="${vo.filename != null && vo.filename != ''}">
		    	    		<img src="<c:out value='file_repo/${vo.filename}'/>" width="60px" height="60px" />
		    	    	</c:if>
		    	    </td>
		    	    <c:if test="${sessionScope.userId == vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})"></td>
		    	    </c:if>
		    	    <c:if test="${sessionScope.userId != vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})" disabled="disabled"></td>
		    	    </c:if>
				</tr>    	 
				</c:forEach>
				<tr>
					<td colspan="8" align="right"><input type="button" value="회원가입" class="btn btn-primary" onclick="location.href='${ctx}/memberRegister.do'"/></td>			  
				</tr>
			</tbody>
			</table>
		</div>
	</div>
	<div class="panel-footer">
		회원관리 ERP System(admin@naver.com)
	</div>
	</div>
</div>
<div class="panel-group">
	<div class="panel panel-default">
		<div class="panel-heading">
			<h4 class="panel-title">
				<a data-toggle="collapse" href="#collapse1" onclick="memberList()">회원 리스트 보기</a>
			</h4>
		</div>
		<div id="collapse1" class="panel-collapse collapse">
			<div class="panel-body">
	
			</div>
	    	<div class="panel-footer">Panel Footer</div>
		</div>
	</div>
</div>

</body>
</html>

## 이미지 등록 테스트

  • 회원가입 시 이미지 등록 후 리스트에 나오는지 확인.

### 이미지 등록 했는데 안뜬 경우

  • 만약 회원가입 시 이미지 첨부해서 등록했는데 보이지 않는 경우에는 아래와 같이 진행
  • 이클립스 > Window > Preferences > General > Workspace > Refresh using native hooks or polling 체크

## 회원 상세보기_첨부파일 표시, 삭제 버튼만(기능x) 추가

### memberList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>    
<%
  // MemberVO vo=(MemberVO)request.getAttribute("vo");
%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<script type="text/javascript">
	function update() {
		document.form1.action="<c:url value='/memberUpdate.do'/>";
		document.form1.submit();
	}
	
	function frmreset() {
		document.form1.reset();
	}
</script>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
</head>
<body>

<div class="container">
	<h2>상세 화면</h2>
	<div class="panel panel-default">
		<div class="panel-heading">
			<c:if test="${sessionScope.userId != null && sessionScope != '' }">
				<label>${sessionScope.userName}님이 로그인 하셨습니다.</label>
			</c:if>
			<c:if test="${sessionScope.userId == null || sessionScope == '' }">
				<label>안녕하세요.</label>
			</c:if>	
		</div>
		<div class="panel-body">
		<form id="form1" name="form1" class="form-horizontal" method="post">
		<input type="hidden" name="num" value="${vo.num}"/>
			<div class="form-group">
				<label class="control-Label col-sm-2">번호 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.num}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">아이디 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.id}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">비밀번호 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.pass}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">이름 :</label>
				<div class="col-sm-10">
					<c:out value="${vo.name}"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">나이 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="age" name="age" value="${vo.age}" style="width:10%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">이메일 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="email" name="email" value="${vo.email}" style="width:30%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">전화번호 :</label>
				<div class="col-sm-10">
					<input type="text" class="form-control" id="phone" name="phone" value="${vo.phone}" style="width:30%;"/>
				</div>
			</div>
			<div class="form-group">
				<label class="control-Label col-sm-2">첨부파일 :</label>
				<div class="col-sm-10">
					<input type="file" id="file" name="file" />
					<c:if test="${vo.filename != null && vo.filename != ''}">
						<c:out value='${vo.filename}'/>	
					</c:if>	
					<c:if test="${sessionScope.userId != null && sessionScope.userId == vo.id && vo.filename != null && vo.filename != ''}">
						<span class="glyphicon glyphicon-remove"></span>
					</c:if>				
				</div>
			</div>			
		</form>
		</div>
		<div class="panel-footer" style="text-align: center;">
			<c:if test="${!empty sessionScope.userId}">
				<c:if test="${sessionScope.userId == vo.id}">
					<input type="button" value="수정하기" class='btn btn-primary' onclick="update()"/>
				</c:if>
				<c:if test="${sessionScope.userId != vo.id}">
					<input type="button" value="수정하기" class='btn btn-primary' onclick="update()" disabled="disabled"/>
				</c:if>
			</c:if>
			<input type="button" value="취소" class='btn btn-warning' onclick="frmreset()"/>
			<input type="button" value="리스트" onclick="location.href='${ctx}/memberList.do'" class='btn'/>
		</div>
	</div>
</div>
</body>
</html>

 

반응형
반응형

# MVC07_04 Ajax와 JSON 데이터 처리_1

  • 버튼 클릭 시 회원 리스트 보일 수 있도록 작업

## memberList.jsp

<div class="panel-group">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" href="#collapse1">Collapsible panel</a>
      </h4>
    </div>
    <div id="collapse1" class="panel-collapse collapse">
      <div class="panel-body">Panel Body</div>
      <div class="panel-footer">Panel Footer</div>
    </div>
  </div>
</div>
  • memberList.jsp에 부트스트랩 적용 및 스크립트로 버튼 클릭 시 리스트 보여질 수 있도록 초기작업.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>    
<%@ page import="java.util.*" %>
<%
     // ArrayList<MemberVO> list=(ArrayList<MemberVO>)request.getAttribute("list");
%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
<script type="text/javascript">

	$(document).ready(function(){
		<c:if test="${!empty msg}">
			alert("${msg}");
			<c:remove var="msg" scope="session"/>
		</c:if>
	});

	function deleteFn(num) {
		location.href="${ctx}/memberDelete.do?num="+num; // ?num=12
	}
	
	function check() {
		if ($('#user_id').val() == '') {
			alert("아이디를 입력해주세요.");
			return false;
	 	}
		
		if ($('#password').val() == '') {
			alert("비밀번호를 입력해주세요.");
			return false;
		}
		
		return true;
	}
	
	function logout() {
		location.href="<c:url value='/memberLogout.do'/>";
	}
	
	function memberList() {
		// var html = $("#collapse1 .panel-body").html();
		// alert(html);
		
		$.ajax({
			url : "<c:url value='/memberAjaxList.do'/>",	// 서버 요청
			type : "get",
			dataType : "json",
			success : resultHtml,	// 회원 리스트로 받기([{}, {}, {}])
			error : function() {error("error");}
		});
		
		
	}	
	
	function resultHtml(data) {
		var html="<table class='table table-hover'>";
		html+="<tr>";
		html+="<th>번호</th>";
		html+="<th>아이디</th>";
		html+="<th>비밀번호</th>";
		html+="<th>이름</th>";
		html+="<th>나이</th>";
		html+="<th>이메일</th>";
		html+="<th>전화번호</th>";
		html+="<th>삭제</th>";
		html+="</tr>";
		
		// 반복문 처리
		$.each(data, function(index, obj) {
			html+="<tr>";
			html+="<td>" + obj.num + "</td>";
			html+="<td>" + obj.id + "</td>";
			html+="<td>" + obj.pass + "</td>";
			html+="<td>" + obj.name + "</td>";
			html+="<td>" + obj.age + "</td>";
			html+="<td>" + obj.email + "</td>";
			html+="<td>" + obj.phone + "</td>";
			html+="<td>삭제</td>";
			html+="</tr>";
		});
		html+="</table>";
		
		$("#collapse1 .panel-body").html(html);
	}
</script>
</head>
<body>

<div class="container">
	<h2>회원관리 시스템</h2>
	<div class="panel panel-default">
		<div class="panel-heading">
		<c:if test="${sessionScope.userId == null || sessionScope.userId == ''}">
			<form class="form-inline" action="${ctx}/memberLogin.do" method="post">
			    <div class="form-group">
					<label for="user_id">ID:</label>
					<input type="text" class="form-control" id="user_id" name="user_id">
			    </div>
			    <div class="form-group">
					<label for="pwd">Password:</label>
					<input type="password" class="form-control" id="password" name="password">
			    </div>
			    <button type="submit" class="btn btn-default" onclick="return check()">로그인</button>
			</form>
		</c:if>
		<c:if test="${sessionScope.userId != null && sessionScope.userId != ''}">
			${sessionScope.userName}님 환영합니다.
			<button type="submit" class="btn btn-warning" onclick="logout()" >로그아웃</button>
		</c:if>	
		</div>
	<div class="panel-body">
		<div class="table-responsive">          
			<table class="table table-hover">
			<thead>
				<tr>
					<th>번호</th>
					<th>아이디</th>
					<th>비밀번호</th>
					<th>이름</th>
					<th>나이</th>
					<th>이메일</th>
					<th>전화번호</th>
					<th>삭제</th>
				</tr>
			</thead>
			<tbody>
				<c:forEach var="vo" items="${list}">
				<tr>
		    	    <td>${vo.num}</td>
		    	    <td><a href="${ctx}/memberContent.do?num=${vo.num}">${vo.id}</a></td>
		    	    <td>${vo.pass}</td>
		    	    <td>${vo.name}</td>
		    	    <td>${vo.age}</td>
		    	    <td>${vo.email}</td>
		    	    <td>${vo.phone}</td>
		    	    <c:if test="${sessionScope.userId == vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})"></td>
		    	    </c:if>
		    	    <c:if test="${sessionScope.userId != vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})" disabled="disabled"></td>
		    	    </c:if>
				</tr>    	 
				</c:forEach>
				<tr>
					<td colspan="8" align="right"><input type="button" value="회원가입" class="btn btn-primary" onclick="location.href='${ctx}/memberRegister.do'"/></td>			  
				</tr>
			</tbody>
			</table>
		</div>
	</div>
	<div class="panel-footer">
		회원관리 ERP System(admin@naver.com)
	</div>
	</div>
</div>
<div class="panel-group">
	<div class="panel panel-default">
		<div class="panel-heading">
			<h4 class="panel-title">
				<a data-toggle="collapse" href="#collapse1" onclick="memberList()">회원 리스트 보기</a>
			</h4>
		</div>
		<div id="collapse1" class="panel-collapse collapse">
			<div class="panel-body">
	
			</div>
	    	<div class="panel-footer">Panel Footer</div>
		</div>
	</div>
</div>

</body>
</html>

 

# MVC07_05 Ajax와 JSON 데이터 처리_2

## Ajax 이용한 회원 리스트 불러오기 기능

1. HandlerMapping

  • 위에서 작업한 ajax 관련 memberAjaxList.do 요청 처리위한 코드 추가.
package kr.bit.frontcontroller;

import java.util.HashMap;

import kr.bit.controller.Controller;
import kr.bit.controller.*;

public class HandlerMapping {
  private HashMap<String, Controller> mappings;
  public HandlerMapping() {
	  mappings=new HashMap<String, Controller>();
	  mappings.put("/memberList.do", new MemberListController());
	  mappings.put("/memberInsert.do", new MemberInsertController());
	  mappings.put("/memberRegister.do", new MemberRegisterController());
	  mappings.put("/memberContent.do", new MemberContentController());
	  mappings.put("/memberUpdate.do", new MemberUpdateController());
	  mappings.put("/memberDelete.do", new MemberDeleteController());
	  mappings.put("/memberLogin.do", new MemberLoginController());
	  mappings.put("/memberLogout.do", new MemberLogoutController());
	  mappings.put("/memberDbcheck.do", new MemberDbcheckController());
	  mappings.put("/memberAjaxList.do", new MemberAjaxListController());
  }
  public Controller getController(String key) { // key=>/memberList.do
	  return mappings.get(key);
  }
}

2. MemberAjaxListController 생성

  • 프로젝트 > src > kr.bit.controller 우 클릭 > New > class 클릭 후 MemberAjaxListController 이름으로 생성
  • Gson API 이용 하기위해 mvnrepository 방문하여 필요한 라이브러리 다운로드 (https://mvnrepository.com/artifact/com.google.code.gson/gson), jar 파일 다운로드 후 lib 폴더에 추가.
package kr.bit.controller;

import java.io.IOException;
import java.util.List;

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

import com.google.gson.Gson;

import kr.bit.model.MemberDAO;
import kr.bit.model.MemberVO;

public class MemberAjaxListController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		MemberDAO dao = new MemberDAO();
		List<MemberVO> list = dao.memberList();
		
		// Gson API 이용 
		Gson g = new Gson();
		String json = g.toJson(list);	// [{}, {}, {}...]
		
		// $.ajax() 에 따른 json으로 응답
		response.setContentType("text/json;charset=euc-kr");
		response.getWriter().print(json);
		
		return null;
	}

}

## Ajax 이용한 회원 삭제 기능

1. memberList.jsp

  • memberList.jsp에 ajax로 가져온 회원리스트에서 삭제 버튼 클릭 시 삭제 기능 될 수 있도록 구현.
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="kr.bit.model.*" %>    
<%@ page import="java.util.*" %>
<%
     // ArrayList<MemberVO> list=(ArrayList<MemberVO>)request.getAttribute("list");
%>    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
<script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js'></script>
<script type="text/javascript">

	$(document).ready(function(){
		<c:if test="${!empty msg}">
			alert("${msg}");
			<c:remove var="msg" scope="session"/>
		</c:if>
	});

	function deleteFn(num) {
		location.href="${ctx}/memberDelete.do?num="+num; // ?num=12
	}
	
	function check() {
		if ($('#user_id').val() == '') {
			alert("아이디를 입력해주세요.");
			return false;
	 	}
		
		if ($('#password').val() == '') {
			alert("비밀번호를 입력해주세요.");
			return false;
		}
		
		return true;
	}
	
	function logout() {
		location.href="<c:url value='/memberLogout.do'/>";
	}
	
	function memberList() {
		// var html = $("#collapse1 .panel-body").html();
		// alert(html);
		
		$.ajax({
			url : "<c:url value='/memberAjaxList.do'/>",	// 서버 요청
			type : "get",
			dataType : "json",
			success : resultHtml,	// 회원 리스트로 받기([{}, {}, {}])
			error : function() { error("error"); }
		});	
	}	
	
	function resultHtml(data) {
		var html="<table class='table table-hover'>";
		html+="<tr>";
		html+="<th>번호</th>";
		html+="<th>아이디</th>";
		html+="<th>비밀번호</th>";
		html+="<th>이름</th>";
		html+="<th>나이</th>";
		html+="<th>이메일</th>";
		html+="<th>전화번호</th>";
		html+="<th>삭제</th>";
		html+="</tr>";
		
		// 반복문 처리	[{}, {}, {}]
		$.each(data, function(index, obj) {
			html+="<tr>";
			html+="<td>" + obj.num + "</td>";
			html+="<td>" + obj.id + "</td>";
			html+="<td>" + obj.pass + "</td>";
			html+="<td>" + obj.name + "</td>";
			html+="<td>" + obj.age + "</td>";
			html+="<td>" + obj.email + "</td>";
			html+="<td>" + obj.phone + "</td>";
			html+="<td><input type='button' value='삭제' class='btn btn-warning' onclick='delFn(" + obj.num + ")'></td>";
			html+="</tr>";
		});
		html+="</table>";
		
		$("#collapse1 .panel-body").html(html);
	}
	
	function delFn(num) {
		$.ajax({
			url : "<c:url value='/memberAjaxDelete.do'/>",
			type : "get",
			data : {"num" : num},
			success : memberList,
			error : function() { alert("error"); }			
		});
	}
</script>
</head>
<body>

<div class="container">
	<h2>회원관리 시스템</h2>
	<div class="panel panel-default">
		<div class="panel-heading">
		<c:if test="${sessionScope.userId == null || sessionScope.userId == ''}">
			<form class="form-inline" action="${ctx}/memberLogin.do" method="post">
			    <div class="form-group">
					<label for="user_id">ID:</label>
					<input type="text" class="form-control" id="user_id" name="user_id">
			    </div>
			    <div class="form-group">
					<label for="pwd">Password:</label>
					<input type="password" class="form-control" id="password" name="password">
			    </div>
			    <button type="submit" class="btn btn-default" onclick="return check()">로그인</button>
			</form>
		</c:if>
		<c:if test="${sessionScope.userId != null && sessionScope.userId != ''}">
			${sessionScope.userName}님 환영합니다.
			<button type="submit" class="btn btn-warning" onclick="logout()" >로그아웃</button>
		</c:if>	
		</div>
	<div class="panel-body">
		<div class="table-responsive">          
			<table class="table table-hover">
			<thead>
				<tr>
					<th>번호</th>
					<th>아이디</th>
					<th>비밀번호</th>
					<th>이름</th>
					<th>나이</th>
					<th>이메일</th>
					<th>전화번호</th>
					<th>삭제</th>
				</tr>
			</thead>
			<tbody>
				<c:forEach var="vo" items="${list}">
				<tr>
		    	    <td>${vo.num}</td>
		    	    <td><a href="${ctx}/memberContent.do?num=${vo.num}">${vo.id}</a></td>
		    	    <td>${vo.pass}</td>
		    	    <td>${vo.name}</td>
		    	    <td>${vo.age}</td>
		    	    <td>${vo.email}</td>
		    	    <td>${vo.phone}</td>
		    	    <c:if test="${sessionScope.userId == vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})"></td>
		    	    </c:if>
		    	    <c:if test="${sessionScope.userId != vo.id}">
		    	    	<td><input type="button" value="삭제" class="btn btn-warning" onclick="deleteFn(${vo.num})" disabled="disabled"></td>
		    	    </c:if>
				</tr>    	 
				</c:forEach>
				<tr>
					<td colspan="8" align="right"><input type="button" value="회원가입" class="btn btn-primary" onclick="location.href='${ctx}/memberRegister.do'"/></td>			  
				</tr>
			</tbody>
			</table>
		</div>
	</div>
	<div class="panel-footer">
		회원관리 ERP System(admin@naver.com)
	</div>
	</div>
</div>
<div class="panel-group">
	<div class="panel panel-default">
		<div class="panel-heading">
			<h4 class="panel-title">
				<a data-toggle="collapse" href="#collapse1" onclick="memberList()">회원 리스트 보기</a>
			</h4>
		</div>
		<div id="collapse1" class="panel-collapse collapse">
			<div class="panel-body">
	
			</div>
	    	<div class="panel-footer">Panel Footer</div>
		</div>
	</div>
</div>

</body>
</html>

2. HandlerMapping

package kr.bit.frontcontroller;

import java.util.HashMap;

import kr.bit.controller.Controller;
import kr.bit.controller.*;

public class HandlerMapping {
  private HashMap<String, Controller> mappings;
  public HandlerMapping() {
	  mappings=new HashMap<String, Controller>();
	  mappings.put("/memberList.do", new MemberListController());
	  mappings.put("/memberInsert.do", new MemberInsertController());
	  mappings.put("/memberRegister.do", new MemberRegisterController());
	  mappings.put("/memberContent.do", new MemberContentController());
	  mappings.put("/memberUpdate.do", new MemberUpdateController());
	  mappings.put("/memberDelete.do", new MemberDeleteController());
	  mappings.put("/memberLogin.do", new MemberLoginController());
	  mappings.put("/memberLogout.do", new MemberLogoutController());
	  mappings.put("/memberDbcheck.do", new MemberDbcheckController());
	  mappings.put("/memberAjaxList.do", new MemberAjaxListController());
	  mappings.put("/memberAjaxDelete.do", new MemberAjaxDeleteController());
  }
  public Controller getController(String key) { // key=>/memberList.do
	  return mappings.get(key);
  }
}

3. MemberAjaxDeleteController 생성

package kr.bit.controller;

import java.io.IOException;

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

import kr.bit.model.MemberDAO;

public class MemberAjaxDeleteController implements Controller {

	@Override
	public String requestHandler(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		int num=Integer.parseInt(request.getParameter("num"));
		
		MemberDAO dao=new MemberDAO();
		int cnt=dao.memberDelete(num);
		
		response.getWriter().print(cnt);
		
		return null;
	}

}

 

# MVC07_06 Ajax와 JSON

## ajax로 회원 리스트 출력 시

  • MemberAjaxListController에서 list에 담긴 회원리스트를 Gson 라이브러리를 이용해서 arrayList 를 json형태로 변형. 해당 데이터는 아래와 같은 형식으로 되어있다.
[{"num" : 1, "id" : aaa, "pass" : 1234}, {"num" : 2, "id" : bbb, "pass" : 1212}]

위 데이터를 ajax를 이용하여 memberList.jsp 에 가져와서 $.each (key 값 이용해서 데이터 보여줌)를 이용해서 보여준다.

반응형

+ Recent posts