danbibibi
article thumbnail
Published 2023. 4. 24. 00:40
Spring MVC 실습 WEB/back-end

내용 정리 겸 지금까지 학습한 Spring, JSP, MVC 패턴 등을 적용한 간단한 실습을 해보자!!

 

1. DB 만들기

아주 간단한 table 2가지를 만들어서 진행!

<sql />
drop database if exists animal; create database if not exists animal DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_as_cs ; use animal; drop table if exists user; create table if not exists user( id varchar(10) primary key, pw varchar(10) not null, name varchar(20) not null ); insert into user values ('danbi', '1234', '홍길동'), ('admin', '1234', '관리자'); select * from user; drop table if exists cat; create table if not exists cat( code varchar(10) primary key, nickname varchar(20) not null, price int not null, id varchar(10), foreign key (id) references user(id) ); insert into cat values ('101', '야옹이', 1000, 'danbi'), ('102', '꽁냥이', 2000, 'danbi'), ('103', '꼬물이', 3000, 'admin'); select * from cat;

 

 

2. DTO 만들기

앞서 만들어둔 스키마를 보고 DTO를 만들어 준다!!

<java />
import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString public class User { private String id; private String pw; private String name; }

 

<java />
import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @ToString public class Cat { private String code; private String nickname; private int price; private String id; private User user; }

 

 

3. DAO 만들기 (@Repository)

먼저 다음과 같이 Interface를 만들어 준다!

<java />
import java.sql.SQLException; import com.danbi.cat.dto.User; public interface UserRepo { User select(User user) throws SQLException; }

 

<java />
import java.sql.SQLException; import java.util.List; import com.danbi.cat.dto.Cat; public interface CatRepo { int insert(Cat cat) throws SQLException; int delete(String code) throws SQLException; int update(Cat cat) throws SQLException; Cat select(String code) throws SQLException; List<Cat> selectAll() throws SQLException; }

 

그리고, 위에서 만들어 둔 Interface를 구현해준다!

후에 servlet-context.xml과 root-context.xml에서 component-scan을 통해 의존성 주입을 할 것이므로!

객체를 별도로 생성하지 않고, annotation을 이용하여 의존성 주입을 하고 있는 것을 확인할 수 있다.

 

User 객체를 받아서, 아이디와 비밀번호가 DB에 저장된 경우 해당 객체를, 저장되지 않은 경우에는 null을 반환해준다!

<java />
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import org.springframework.stereotype.Repository; import com.danbi.cat.dto.User; @Repository public class UserRepoImpl implements UserRepo { @Autowired private DataSource dataSource; @Override public User select(User user) throws SQLException { User selected = null; String sql = "select * from user where id = ?"; try(Connection conn = dataSource.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)){ ps.setString(1, user.getId()); try(ResultSet rs = ps.executeQuery()){ if(rs.next() && user.getPw().equals(rs.getString("pw"))) { selected = new User(rs.getString("id"), rs.getString("pw"), rs.getString("name")); } } } return selected; } // test public static void main(String[] args) throws SQLException { ApplicationContext ctx = new GenericXmlApplicationContext("file:src/main/webapp/WEB-INF/spring/root-context.xml"); UserRepo repo = ctx.getBean(UserRepoImpl.class); System.out.println(repo.select(new User("danbi", "1234", ""))); } }

 

 

4. Service 만들기 (@Service)

service도 DAO처럼 먼저 interface를 만들어 준다!!

<java />
import java.sql.SQLException; import com.danbi.cat.dto.User; public interface UserService { User select(User user) throws SQLException; }

 

<java />
import java.sql.SQLException; import java.util.List; import com.danbi.cat.dto.Cat; public interface CatService { int insert(Cat cat) throws SQLException; int delete(String code) throws SQLException; int update(Cat cat) throws SQLException; Cat select(String code) throws SQLException; List<Cat> selectAll() throws SQLException; }

 

그리고 만든 interface를 구현해 주는데, 이때 앞서 만들어 둔 DAO를 이용해서 데이터 로직을 처리해준다!

<java />
import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import org.springframework.stereotype.Service; import com.danbi.cat.dto.User; import com.danbi.cat.model.repo.UserRepo; @Service public class UserServiceImpl implements UserService { @Autowired UserRepo userRepo; @Override public User select(User user) throws SQLException { return userRepo.select(user); } // test public static void main(String[] args) throws SQLException { ApplicationContext ctx = new GenericXmlApplicationContext("file:src/main/webapp/WEB-INF/spring/root-context.xml"); UserService svc = ctx.getBean(UserService.class); System.out.println(svc.select(new User("danbi", "1234", ""))); } }

 

select 시 user 정보를 얻기 위해 join을 했다!

<java />
import java.sql.SQLException; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.danbi.cat.dto.Cat; import com.danbi.cat.model.repo.CatRepo; @Service public class CatServiceImpl implements CatService { @Autowired CatRepo catRepo; @Override @Transactional public int insert(Cat cat) throws SQLException { return catRepo.insert(cat); } @Override @Transactional public int delete(String code) throws SQLException { return catRepo.delete(code); } @Override @Transactional public int update(Cat cat) throws SQLException { return catRepo.update(cat); } @Override public Cat select(String code) throws SQLException { return catRepo.select(code); } @Override public List<Cat> selectAll() throws SQLException { return catRepo.selectAll(); } // test public static void main(String[] args) throws Exception{ ApplicationContext ctx = new GenericXmlApplicationContext("file:src/main/webapp/WEB-INF/spring/root-context.xml"); CatService svc = ctx.getBean(CatService.class); svc.insert(new Cat("104", "길냥이", 4000, "admin", null)); svc.update(new Cat("104", "업데이트 완료", 5000, "admin", null)); System.out.println(svc.select("104")); svc.delete("104"); for(Cat c : svc.selectAll()) System.out.println(c); } }

 

 

5. JSP 페이지 만들기

다음과 같이 간단한 페이지를 몇개 만들어 주었다!

 

헤더이다!

<html />
<!-- include/header.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <c:set var="root" value="${pageContext.request.contextPath}"></c:set> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="Cache-Control" content="no-cache"> <title>Spring MVC 실습</title> </head> <body> <h1>Spring MVC 실습</h1> <div> <c:if test="${empty loginUser}"> <a href="${root}/login">로그인</a> </c:if> <c:if test="${not empty loginUser}"> [${loginUser.name}] 님 반갑습니다. <a href="${root}/logout">로그아웃</a> </c:if> </div> <hr> <script> let msg="${msg}"; if(msg) alert(msg); </script>

 

메인 페이지이다!

<html />
<!-- index.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2> CAT HOUSE </h2> <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

푸터이다!

<html />
<!-- include/footer.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <p> <hr> <a href="${root}/">홈으로</a> <a href="${root}/regist">등록</a> <a href="${root}/list">목록</a> </body> </html>

 

에러가 발생하면 보여질 페이지이다!

<html />
<!-- error/error.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2>오류 </h2> 잠시 후 다시 시도해 주세요. ${errmsg} <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

로그인 페이지이다!

<java />
<!-- user/login.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2> 로그인 </h2> <form action="${root}/login" method="post"> 아이디 : <input type="text" name="id" value="danbi"> <br> 패스워드 : <input type="password" name="pw" value="1234"> <br> <input type="submit" value="로그인"> </form> <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

cat들의 리스트를 보여주는 페이지이다!

<html />
<!-- cat/list.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2> 목록 </h2> <c:if test="${not empty cats}"> <form action="${root}/delm" method="post"> <table border="1" style="border-collapse: collapse;"> <tr> <th>코드</th> <th>애칭</th> <th>가격</th> <th>삭제</th> </tr> <c:forEach var="cat" items="${cats}"> <tr> <td><a href="${root}/detail?code=${cat.code}">${cat.code}</a></td> <td>${cat.nickname}</td> <td>${cat.price}</td> <th><input type="checkbox" name="codes" value="${cat.code}"></th> </tr> </c:forEach> </table> <input type="submit" value="삭제"> </form> </c:if> <c:if test="${empty cats}"> <p> 등록된 정보가 없습니다.</p> </c:if> <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

새로운 cat을 등록하는 페이지이다!

<html />
<!-- cat/regist.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2> 등록 </h2> <form action="${root}/regist" method="post"> 코드: <input type="text" name="code" value="104" > <br> 애칭: <input type="text" name="nickname" value="길냥이" > <br> 가격: <input type="text" name="price" value="4000" > <br> 아디: <input type="text" name="id" value="${loginUser.id}" <c:if test="${not empty loginUser}">readonly </c:if>> <br> <input type="submit" value="등록"> </form> <c:if test="${not empty err}"> <fieldset> <legend>등록오류</legend> ${err} </fieldset> </c:if> <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

cat 정보를 상세하게 볼 수 있는 페이지이다!

<html />
<!-- cat/detail.jsp --> <%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/WEB-INF/views/include/header.jsp" %> <h2> 상세 </h2> <table> <tr> <th>아디</th> <td>${cat.id}</td></tr> <tr> <th>이름</th> <td>${cat.user.name}</td></tr> <tr> <th>코드</th> <td>${cat.code}</td></tr> <tr> <th>애칭</th> <td>${cat.nickname}</td></tr> <tr> <th>가격</th> <td>${cat.price}</td></tr> </table> <a href="${root}/dele?code=${cat.code}"> 삭제</a> <%@include file="/WEB-INF/views/include/footer.jsp" %>

 

 

6. servlet-context.xml, root-xml 수정

annotation을 사용하기 위해 다음과 같이 component-scan을 해준다!

또 Database를 사용하기 위해 bean으로 등록해준다!! (여기서는 mysql을 사용했다.)

<bash />
# servlet-context.xml <context:component-scan base-package="com.danbi.cat.controller" /> # root-context.xml <context:component-scan base-package="com.danbi.cat.model"/> <bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource"> <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/animal?serverTimezone=UTC"/> <property name="username" value="아이디"/> <property name="password" value="비밀번호"/> </bean>

 

 

7. Controller 만들기 (@Controller)

<java />
import java.net.BindException; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import com.danbi.cat.dto.Cat; import com.danbi.cat.dto.User; import com.danbi.cat.model.service.CatService; import com.danbi.cat.model.service.UserService; import lombok.extern.slf4j.Slf4j; @Slf4j @Controller public class CatController { @Autowired private UserService us; @Autowired private CatService cs; @ExceptionHandler(Exception.class) public String handler(Model m, Exception e) { e.printStackTrace(); m.addAttribute("errmsg", e.getMessage()); if(e instanceof BindException) { m.addAttribute("errmsg", "중복 등록 오류"); } return "error/error"; } @GetMapping({"/", "/index"}) public String index() { return "index"; } @GetMapping("/login") public String login() { return "user/login"; } @PostMapping("/login") public String login(User user, Model model, HttpSession session) throws SQLException { User loginUser = us.select(user); if(loginUser!=null) { session.setAttribute("loginUser", loginUser); return "redirect:/"; } else { model.addAttribute("msg", "아이디와 패스워드를 확인해주세요!"); return "user/login"; } } @GetMapping("/logout") public String logout(HttpSession session) { session.invalidate(); return "redirect:/"; } @GetMapping("/regist") public String regist() { return "cat/regist"; } @PostMapping("/regist") public String regist(Cat cat, Model model) throws SQLException { try { cs.insert(cat); model.addAttribute("msg", "등록되었습니다."); } catch (SQLIntegrityConstraintViolationException e) { model.addAttribute("msg", "등록 중 오류가 발생했습니다."); e.printStackTrace(); } return "cat/list"; } @GetMapping("/list") public String list(Model model) throws SQLException { model.addAttribute("cats", cs.selectAll()); return "cat/list"; } @GetMapping("/detail") public String detail(String code, Model model) throws SQLException { model.addAttribute("cat", cs.select(code)); return "cat/detail"; } @GetMapping("/dele") public String dele(String code) throws SQLException { cs.delete(code); return "redirect:/list"; } @PostMapping("/delm") public String delm(String[] codes) throws SQLException { for(String code : codes) cs.delete(code); return "redirect:/list"; } }

 

 

최종 프로젝트 구조는 다음과 같다!

'WEB > back-end' 카테고리의 다른 글

MyBatis, MyBatis-Spring 설정  (0) 2023.04.24
Spring File Upload (Apache Commons FileUpload)  (1) 2023.04.24
Interceptor  (0) 2023.04.22
AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)  (0) 2023.04.22
Spring  (0) 2023.04.21
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로