SpringMVC로 CRUD구현(1)
지금가지 MVC패턴으로 연습해오던 코드들을
이번엔 Spring을 활용하여 만들어보자
https://develop-hana.tistory.com/141
MVC 패턴으로 CRUD 구현 (1)
하드코딩이었던 저번 코드에 MVC 패턴으로 DB를 추가하였다. https://develop-hana.tistory.com/140 하나의 Servlet에서 여러 작업을 수행하기 - CRUD DB와 연결하지 않은 하드코딩 버전 메인페이지는 list.jsp이다
develop-hana.tistory.com
Controller, Model
web.xml
web-app 태그 안에 다음과 같이 추가.
정의되어있는 DispatherServlet이 클라이언트의 요청을 받아 알맞은 controller를 찾고 그 응답 결과를 반환한다.
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet-context.xml
모든 view 파일들은 WEB-INF의 view 폴더 밑에 추가하였다.
아래와 같이 설정해주면 저 경로대로 알아서 jsp파일을 찾아줄거다.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="bitedu.lesson.spring" />
</beans:beans>
ModelAndView에 대한 자세한 설명
ModelAndView (Spring Framework 6.0.4 API)
Holder for both Model and View in the web MVC framework. Note that these are entirely distinct. This class merely holds both to make it possible for a controller to return both model and view in a single return value. Represents a model and view returned b
docs.spring.io
MemberController.java
@Controller("memberController")
public class MemberController {
@Autowired
private MemberService service;
private static final Logger logger = LoggerFactory.getLogger(MemberController.class);
/* 메인 페이지 */
@RequestMapping(value = "/home", method = RequestMethod.GET)
public ModelAndView basic() {
logger.info("basic Controller");
ModelAndView mav = new ModelAndView();
String url = "./login/home";
mav.setViewName(url);
return mav;
}
/* 로그인 페이지 */
@RequestMapping(value = "/viewLoginForm", method = RequestMethod.GET)
public ModelAndView viewLoginForm() {
logger.info("viewLoginForm Controller");
ModelAndView mav = new ModelAndView();
String url = "./login/login";
mav.setViewName(url);
return mav;
}
/* 로그인 */
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView login(HttpServletRequest req) {
logger.info("login Controller");
ModelAndView mav = new ModelAndView();
String url = "./login/login";
String id = req.getParameter("id");
String pwd = req.getParameter("pwd");
MemberVO vo = service.isMember(id, pwd);
if(vo != null) {
HttpSession session = req.getSession();
session.setAttribute("vo", vo);
url = "./login/home";
mav.setViewName(url);
}
mav.setViewName(url);
return mav;
}
/* 로그아웃 */
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(HttpServletRequest req) {
logger.info("logout controller");
ModelAndView mav = new ModelAndView();
HttpSession session = req.getSession();
session.invalidate();
String url = "./login/home";
mav.setViewName(url);
return mav;
}
/* 회원리스트 전체조회 */
@RequestMapping(value = "/readAll", method = RequestMethod.GET)
public ModelAndView readAll(HttpServletRequest req) {
logger.info("readAll controller");
ModelAndView mav = new ModelAndView();
ArrayList<MemberVO> voList = service.findAll();
mav.addObject("voList", voList);
String url = "./member/list";
mav.setViewName(url);
return mav;
}
/* 회원 상세조회 */
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ModelAndView search(HttpServletRequest req, @RequestParam("id") String id) {
logger.info("search controller");
ModelAndView mav = new ModelAndView();
MemberVO vo = service.find(id);
mav.addObject("vo", vo);
String url = "./member/detail";
mav.setViewName(url);
return mav;
}
/* 회원 가입 페이지 */
@RequestMapping(value = "/viewRegistForm", method = RequestMethod.GET)
public ModelAndView viewRegistForm() {
logger.info("회원 가입 페이지 controller");
ModelAndView mav = new ModelAndView();
String url = "./member/regist";
mav.setViewName(url);
return mav;
}
/* 회원 가입 */
@RequestMapping(value = "/regist", method = RequestMethod.POST)
public ModelAndView regist(HttpServletRequest req) {
logger.info("regist controller");
try {
req.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ModelAndView mav = new ModelAndView();
String url = "redirect:./readAll";
String id = req.getParameter("id");
String pwd = req.getParameter("pwd");
String name = req.getParameter("name");
String email = req.getParameter("email");
Timestamp registDate = new Timestamp(System.currentTimeMillis());
MemberVO vo = new MemberVO(id, pwd, name, email, registDate);
boolean flag = service.regist(vo);
if(flag == false) {
url = "./member/errorResult";
}
mav.setViewName(url);
return mav;
}
/* 회원정보 수정 페이지 */
@RequestMapping(value = "/viewUpdateForm", method = RequestMethod.GET)
public ModelAndView viewUpdatForm(HttpServletRequest req) {
logger.info("view Update Form controller");
ModelAndView mav = new ModelAndView();
String id = req.getParameter("id");
MemberVO vo = service.find(id);
mav.addObject("vo", vo);
String url = "./member/update";
mav.setViewName(url);
return mav;
}
/* 회원정보 수정 */
@RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(HttpServletRequest req) {
logger.info("update controller");
try {
req.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ModelAndView mav = new ModelAndView();
String url = "redirect:./readAll";
String id = req.getParameter("id");
String pwd = req.getParameter("pwd");
String name = req.getParameter("name");
String email = req.getParameter("email");
MemberVO vo = new MemberVO(id, pwd, name, email, null);
boolean flag = service.modify(vo);
if(flag == false) {
url = "./member/errorResult";
}
mav.setViewName(url);
return mav;
}
/* 회원 삭제 */
@RequestMapping(value = "/delete", method = RequestMethod.GET)
public ModelAndView delete(HttpServletRequest req, @RequestParam("id") String id) {
logger.info("delete controller");
ModelAndView mav = new ModelAndView();
String url = "redirect:./readAll";
boolean flag = service.remove(id);
if(flag == false) {
url = "./member/errorResult";
}
mav.setViewName(url);
return mav;
}
}
MemberService.java와 MemberDAO.java는
각각 @Service, @Repository 어노테이션 달아주고 @AutoWired로 의존성 주입해준 것 외에는 이전과 동일한 코드이다.
ConnectionManager.java와 context.xml의 코드도 이전과 동일하며
나는 MySql을 사용하므로 pom.xml에 mysql-connector 의존성 주입해주어야 한다.
View
home.jsp
<%@page import="bitedu.lesson.spring.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<%
String logInOut = "<a href='./viewLoginForm'>로그인</a>";
String msg = "로그인하세요";
String listLink = "";
String myInfo = "";
// 세션 검사
MemberVO vo = (MemberVO) session.getAttribute("vo");
if(vo != null) {
logInOut = "<a href='./logout'>로그아웃</a>";
msg = vo.getName() + "님 반갑습니다.";
if(vo.getId().equals("taehyun") || vo.getId().equals("beomgyu")) {
listLink = "<a href='./readAll'>회원리스트</a>";
} else {
listLink = "<a href=\"javascript:alert('일반 회원은 접근할 수 없습니다.');\">회원리스트</a>";
}
}
%>
<h1>홈페이지</h1>
<span><%= logInOut %></span>
<span><%= msg %></span>
<span><%= listLink %></span>
</body>
</html>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<form action="./login" method="post">
<table>
<tr>
<td>아이디</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>비밀번호</td>
<td><input type="password" name="pwd"></td>
</tr>
</table>
<input type="submit" value="로그인">
</form>
</body>
</html>
detail.jsp
<%@page import="java.util.Date"%>
<%@page import="bitedu.lesson.spring.utils.DateService"%>
<%@page import="bitedu.lesson.spring.vo.MemberVO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>View Condition</title>
</head>
<body>
<h1>view condition</h1>
<form action="./readAll" method="get">
<table>
<tr>
<td>아이디:</td>
<td><input type="text" name="id" value="${vo.id}" readonly="readonly"></td>
</tr>
<tr>
<td>비밀번호:</td>
<td><input type="password" name="pwd" value="${vo.pwd}" readonly="readonly"></td>
</tr>
<tr>
<td>이름:</td>
<td><input type="text" name="name" value="${vo.name}" readonly="readonly"></td>
</tr>
<tr>
<td>이메일:</td>
<td><input type="text" name="email" value="${vo.email}" readonly="readonly"></td>
</tr>
<tr>
<td>가입일:</td>
<td><fmt:formatDate value="${vo.registDate}" pattern="yyyy-MM-dd"/></td>
</tr>
<tr>
<td><input type="submit" value="확인"></td>
</tr>
</table>
</form>
</body>
</html>
list.jsp
<%@page import="java.util.Date"%>
<%@page import="bitedu.lesson.spring.vo.MemberVO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>List</title>
</head>
<body>
<h1>List</h1>
<a href="./viewRegistForm">가입하기</a> <br>
<table>
<c:if test="${fn:length(voList) == 0}"> <!-- == 대신 eq 가능 -->
회원 정보가 존재하지 않습니다.
</c:if>
<c:if test="${fn:length(voList) > 0}"> <!-- > 대신 gt 가능 -->
<c:forEach var="vo" items="${voList}">
<tr>
<td>${vo.id}</td>
<td>${vo.pwd}</td>
<td>${vo.name}</td>
<td>${vo.email}</td>
<td><fmt:formatDate value="${vo.registDate}" pattern="yyyy-MM-dd"/></td>
<td><a href="./search?id=${vo.id}">상세조회</a></td>
<td><a href="./viewUpdateForm?id=${vo.id}">수정</a></td>
<td><a href="./delete?id=${vo.id}">삭제</a></td>
</tr>
</c:forEach>
</c:if>
</table>
<br>
<a href="./home">홈으로 돌아가기</a>
</body>
</html>
regist.jsp
<%@page import="java.util.Date"%>
<%@page import="bitedu.lesson.spring.utils.DateService"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Regist Form</title>
</head>
<body>
<form action="./regist" method="post">
<table>
<tr>
<td>아이디:</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>비밀번호:</td>
<td><input type="password" name="pwd"></td>
</tr>
<tr>
<td>이름:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>이메일:</td>
<td><input type="text" name="email"></td>
</tr>
<tr>
<td>가입일: </td>
<td><input type="text" value='<fmt:formatDate value="<%= new Date() %>" pattern="yyyy-MM-dd"/>' readonly="readonly"></td>
</tr>
<tr>
<td><input type="submit" value="가입"></td>
</tr>
</table>
</form>
</body>
</html>
update.jsp
<%@page import="bitedu.lesson.spring.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Update Form</title>
</head>
<body>
<%
MemberVO vo = (MemberVO) request.getAttribute("vo");
%>
<h1>회원정보 수정</h1>
<form action="./update" method="post">
<table>
<tr>
<td>아이디:</td>
<td><input type="text" name="id" value="${vo.id}" readonly="readonly"></td>
</tr>
<tr>
<td>비밀번호:</td>
<td><input type="password" name="pwd" value="${vo.pwd}"></td>
</tr>
<tr>
<td>이름:</td>
<td><input type="text" name="name" value="${vo.name}"></td>
</tr>
<tr>
<td>이메일:</td>
<td><input type="text" name="email" value="${vo.email}"></td>
</tr>
<tr>
<td>가입일:</td>
<td><fmt:formatDate value="${vo.registDate}" pattern="yyyy-MM-dd"/></td>
</tr>
<tr>
<td><input type="submit" value="수정완료"></td>
</tr>
</table>
</form>
</body>
</html>