스프링 MVC

준비중..

스프링 MVC

스프링을 사용한 웹서비스 만들기

07 데이터 등록하기(create)

# 데이터 등록하기(create) ### 테이블 생성 웹서비스를 통해 만들어진 데이터는 DB를 통해 관리됩니다. 이를 위해서는 먼저 테이블을 생성해 주어야 합니다. ![Imgur](https://i.imgur.com/PeQNOsp.png) DBMS를 실행하여 아래의 테이블을 생성해줍니다. ```sql create table books ( id serial primary key, title varchar(50), author varchar(50), image varchar(255) ); ``` 생성 후 잘 동작하는지 확인해보세요. ![Imgur](https://i.imgur.com/FqX7hzi.png) ### VO 생성 DB에 저장된 데이터를 스프링으로 가져올때, 어딘가 담아둘 곳이 필요하겠죠? 데이터를 담아둘 그릇인 VO(Value Object)클래스를 생성해 봅시다. ![Imgur](https://i.imgur.com/HF4qhT0.png) 먼저 패키지를 생성한 뒤, ![Imgur](https://i.imgur.com/9mggpye.png) Book 클래스를 만들고 필드와 게터세터, 그리고 toString() 메소드를 작성해줍니다. **Book.java** ```java package com.mycompany.vo; public class Book { int id; String title; String author; String image; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } @Override public String toString() { return "Book [id=" + id + ", title=" + title + ", author=" + author + ", image=" + image + "]"; } } ``` ### Mapper 인터페이스 생성 이전 수업에서 MyBatis 라이브러리를 등록하고 설정 했던 내용을 기억하시나요? MyBatis는 디비의 데이터와 VO객체를 맵핑하기 위해 기능를 제공합니다. 이를 **맵퍼(Mapper)**라고 부릅니다. ![Imgur](https://i.imgur.com/nmsk5LQ.png) 해당 위치에 패키지를 생성 후, 클래스를 작성해주세요. ![Imgur](https://i.imgur.com/KGAJzNr.png) **BookMapper.java** ```java package com.mycompany.mapper; public interface BookMapper { } ``` ### Mapper 객체 등록: root-context.xml `bookMapper`를 생성 및 등록합니다. **root-context.xml** ```xml <!-- Maper --> <bean id="bookMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.mycompany.mapper.BookMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> ``` 위 xml을 Java 코드로 변환시 다음과 같습니다. ```java MapperFactoryBean bookMapper = new MapperFactoryBean(mapperInterface, sqlSessionFactory); ``` > xml 파일 수정 후, 서버를 재시작하여 동작여부를 꼭 확인해 주세요. ### 컨트롤러 생성 및 맵퍼 연결 해당 위치에 BooksController를 생성합니다. ![Imgur](https://i.imgur.com/rE14Heo.png) **BooksController.java** ```java package com.mycompany.myapp; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class BooksController { @RequestMapping(value = "/books", method = RequestMethod.GET) public String index() { return "books/index"; } } ``` 맵퍼를 필드로 추가 한 뒤, `@Autowired` 어노테이션을 사용하여 DI해주세요. **BooksController.java** ```java package com.mycompany.myapp; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.mycompany.mapper.BookMapper; @Controller public class BooksController { @Autowired private BookMapper bookMapper; @RequestMapping(value = "/books", method = RequestMethod.GET) public String index() { return "books/index"; } } ``` 뷰 폴더에 `books` 폴더를 생성후 `index.jsp`페이지를 생성합니다. ![Imgur](https://i.imgur.com/IS6YD0V.png) **index.jsp** ```jsp <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page pageEncoding="utf-8" session="false"%> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet"> <title>Books</title> </head> <body> <div class="container"> <div class="jumbotron"> <h1>Books INDEX</h1> <p>views/books/index.jsp</p> </div> </div> </body> </html> ``` 페이지가 잘 나타나는지 확인해볼까요? ![Imgur](https://i.imgur.com/ogjnsyU.png) 현재까지의 흐름을 그림으로 정리하고 넘어갑시다. ![Imgur](https://i.imgur.com/nWveceP.png) ### 책 등록 페이지 만들기 `index.jsp` 페이지에 도서등록 버튼을 만들어 줍니다. **index.jsp** ```jsp ... <body> <div class="container"> <div class="jumbotron"> <h1>Books INDEX</h1> <p>views/books/index.jsp</p> </div> <a href="<c:url value="/books/new" />" class="btn btn-lg btn-primary">도서 등록</a> </div> </body> </html> ``` BooksController에 `newBook()` 메소드를 추가하고 이를 도서등록 버튼의 URL과 연결시켜 줍니다. **BooksController.java** ```java ... @Controller public class BooksController { @Autowired private BookMapper bookMapper; @RequestMapping(value = "/books", method = RequestMethod.GET) public String index() { return "books/index"; } @RequestMapping(value = "/books/new", method = RequestMethod.GET) public String newBook() { return "books/new"; } } ``` 메소드의 리턴값에 해당하는 뷰 페이지를 생성해줍니다. **views/books/new.jsp** ```jsp <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page pageEncoding="utf-8" session="false"%> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="<c:url value="/css/bootstrap.min.css" />" rel="stylesheet"> <title>Books NEW</title> </head> <body> <div class="container"> <div class="jumbotron"> <h1>Books NEW</h1> <p>views/books/new.jsp</p> </div> <form action="<c:url value="/books" />" method="post"> <div class="form-group form-group-lg"> <label class="control-label">도서 제목</label> <input name="title" type="text" class="form-control"> </div> <div class="form-group form-group-lg"> <label class="control-label">저자</label> <input name="author" type="text" class="form-control"> </div> <div class="form-group form-group-lg"> <label class="control-label">이미지</label> <input name="image" type="text" class="form-control"> </div> <button type="submit" class="btn btn-lg btn-primary">전송</button> </form> </div> </body> </html> ``` 컨트롤러에 `create()` 메소드를 만들고, 폼의 액션 값과 메소드에 맞게 라우터를 설정해줍니다. **BooksController.java** ```java @Controller public class BooksController { ... @RequestMapping(value = "/books", method = RequestMethod.POST) public String create(@ModelAttribute Book book) { System.out.println(book.toString()); return ""; } } ``` 이제 폼데이터가 잘 전달되는지 확인해 봅시다. ![Imgur](https://i.imgur.com/ojmg4aS.png) title, autor, image 값이 전달되었음을 확인하였습니다. ![Imgur](https://i.imgur.com/YsfeoF4.png) ### 폼 데이터 한글 깨짐 방지 그런데 한글이 깨져서 전달되는 문제가 보입니다. 이를 해결해봅시다. 먼저는 폼 데이터를 받아오는 컨트롤러에서 아래와 같은 코드를 추가해주면 해결 가능합니다. ``` request.setCharacterEncoding("utf-8"); ``` 하지만 앞으로 만들어질 수 많은 컨트롤러에 이와같은 코드를 적어넣는 것은 비효율적이므로 web.xml파일에 인코딩필터를 추가하여 처리하도록 합니다. ```xml ... <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app> ``` ![Imgur](https://i.imgur.com/u0wiij1.png) > xml 파일을 설정한 뒤, 서버를 재부팅하여 정상 동작 여부를 확인해주세요. ### 맵퍼를 통한 데이터 저장 폼 데이터도 정상 적으로 전달 되었고 하니, 이제 마무리를 해야겠습니다. 맵퍼를 사용하여 폼 데이터를 DB에 저장해봅시다. ![Imgur](https://i.imgur.com/nmsk5LQ.png) 생각보다 컨트롤러의 메소드 내용은 단순합니다. ```java package com.mycompany.myapp; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.mycompany.mapper.BookMapper; import com.mycompany.vo.Book; @Controller public class BooksController { @Autowired private BookMapper bookMapper; @RequestMapping(value = "/books", method = RequestMethod.GET) public String index() { return "books/index"; } @RequestMapping(value = "/books/new", method = RequestMethod.GET) public String newBook() { return "books/new"; } @RequestMapping(value = "/books", method = RequestMethod.POST) public String create(@ModelAttribute Book book) { bookMapper.create(book); return "redirect:/books"; } } ``` 마지막으로 `bookMapper.create(book);`를 구현하며 마무리합니다. ``` package com.mycompany.mapper; import org.apache.ibatis.annotations.Insert; import com.mycompany.vo.Book; public interface BookMapper { @Insert("insert into books (title, author, image) values (#{title}, #{author}, #{image})") public boolean create(Book book); } ``` 축하합니다~~ DB에 저장이 완료 되었습니다. ![Imgur](https://i.imgur.com/ojmg4aS.png) ![Imgur](https://i.imgur.com/iu8P8BW.png)