CRUD 메소드를 사용하여 도서 정보 수정하기
마찬가지로 JdbcTemplate 클래스의 update() 메소드를 사용해서 도서 쇼핑몰에서 등록된 도서 정보를
수정해서 뷰 페이지에 출력되는 것을 구현해 보겠습니다.
BookRepository.java
도서 정보를 수정하는 setUpdateBook() 메소드를 추가합니다.
package com.springmvc.repository;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.springmvc.domain.Book;
public interface BookRepository {
List<Book> getAllBookList();
List<Book> getBookListByCategory(String category);
Set<Book> getBookListByFilter(Map<String, List<String>> filter);
Book getBookById(String bookId);
void setNewBook(Book book);
void setUpdateBook(Book book);
}
BookRepositoryImpl.java
앞서 정의한 setUpdateBook() 메소드를 구현합니다.
package com.springmvc.repository;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import com.springmvc.domain.Book;
import com.springmvc.exception.BookIdException;
import java.util.ArrayList;
import java.util.HashSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class BookRepositoryImpl implements BookRepository {
private List<Book> listOfBooks = new ArrayList<Book>();
private JdbcTemplate template;
@Autowired
public void setJdbctemplate(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
public BookRepositoryImpl() {
Book book1 = new Book("ISBN1234","C#교과서",30000);
book1.setAuthor("박용준");
book1.setDescription(
"C#교과서는 생에 첫 프로그래밍 언어로 C#을 시작하는 독자를 대상으로 한다. 특히 응용프로그래머를 위한 C# 입문서로, C#을 사용하여 게임(유니티), 웹, 모바일, IoT 등을 개발할 때 필요한 C# 기초 문법을 익히고 기본기를 탄탄하게 다지는 것이 목적이다."
);
book1.setPublisher("길벗");
book1.setCategory("IT전문서");
book1.setUnitsInStock(1000);
book1.setReleaseDate("2020/01/01");
Book book2 = new Book("ISBN1235", "Node.js교과서",36000);
book2.setAuthor("조현영");
book2.setDescription(
"이 책은 프런트부터 서버, 데이터베이스, 배포까지 아우르는 광범위한 내용을 다룬다. 군더더기 없는 직관적인 설명으로 기본 개념을 확실히 이해하고, 노드와 기능과 생태계를 사용해 보면서 실제로 동작하는 서버를 만들어보자."
);
book2.setPublisher("길벗");
book2.setCategory("IT전문서");
book2.setUnitsInStock(1000);
book2.setReleaseDate("2020/02/02");
Book book3 = new Book("ISBN1236", "어도비 XD CC 2020",25000);
book3.setAuthor("김두한");
book3.setDescription(
"어도비 XD 프로그램을 통해 UI/UX 디자인을 배우고자 하는 예비 디자이너의 눈높이에 맞게 기본적인 도구를 활용한 아이콘 디자인과 웹&앱 페이지 디자인, UI 디자인, 앱 디자인에 애니메이션과 인터랙션을 적용한 프로토타입을 학습합니다."
);
book3.setPublisher("길벗");
book3.setCategory("IT활용서");
book3.setUnitsInStock(1000);
book3.setReleaseDate("2020/03/03");
listOfBooks.add(book1);
listOfBooks.add(book2);
listOfBooks.add(book3);
}
@Override
public List<Book> getAllBookList() {
String SQL = "SELECT * FROM book";
List<Book> listOfBooks = template.query(SQL, new BookRowMapper());
return listOfBooks;
}
public List<Book> getBookListByCategory(String category) {
List<Book> booksByCategory = new ArrayList<Book>();
String SQL = "SELECT * FROM book where b_category LIKE '%"+category+"%'";
booksByCategory = template.query(SQL, new BookRowMapper());
return booksByCategory;
}
public Set<Book> getBookListByFilter(Map<String, List<String>> filter) {
Set<Book> booksByPublisher = new HashSet<Book>();
Set<Book> booksByCategory = new HashSet<Book>();
Set<String> criterias = filter.keySet();
if(criterias.contains("publisher")) {
for(int j=0;j<filter.get("publisher").size();j++) {
String publisherName = filter.get("publisher").get(j);
String SQL = "SELECT * FROM book where b_publisher LIKE '%"+publisherName+"%'";
booksByPublisher.addAll(template.query(SQL, new BookRowMapper()));
}
}
if(criterias.contains("category") ) {
for(int i=0;i<filter.get("category").size();i++) {
String category = filter.get("category").get(i);
String SQL = "SELECT * FROM book where b_category LIKE '%"+category+"%'";
booksByCategory.addAll(template.query(SQL, new BookRowMapper()));
}
}
booksByCategory.retainAll(booksByPublisher);
return booksByCategory;
}
public Book getBookById(String bookId) {
Book bookInfo = null;
String SQL = "SELECT count(*) FROM book where b_bookId=?";
int rowCount = template.queryForObject(SQL, Integer.class, bookId);
if(rowCount != 0) {
SQL = "SELECT * FROM book where b_bookId=?";
bookInfo = template.queryForObject(SQL, new Object[] {bookId}, new BookRowMapper());
}
if(bookInfo==null)
throw new BookIdException(bookId);
return bookInfo;
}
public void setNewBook(Book book) {
String SQL = "INSERT INTO book (b_bookId, b_name, b_unitPrice, b_author, b_description, b_publisher, b_category, b_unitsInStock, b_releaseDate, b_condition, b_fileName)"
+"Values(?,?,?,?,?,?,?,?,?,?,?)";
template.update(SQL, book.getBookId(), book.getName(), book.getUnitPrice(), book.getAuthor(), book.getDescription(), book.getPublisher(), book.getCategory(), book.getUnitsInStock(), book.getReleaseDate(), book.getCondition(), book.getFileName());
}
public void setUpdateBook(Book book) {
if(book.getFileName() != null) {
String SQL = "UPDATE book SET b_name=?, b_unitPrice=?, b_author=?, b_description=?, b_publisher=?, b_category=?, b_unitsInStock=?, b_releaseDate=?, b_condition=?, b_fileName=? where b_bookId=?";
template.update(SQL, book.getName(), book.getUnitPrice(), book.getAuthor(), book.getDescription(), book.getPublisher(), book.getCategory(), book.getUnitsInStock(), book.getReleaseDate(), book.getCondition(), book.getFileName(), book.getBookId());
} else if(book.getFileName() == null) {
String SQL = "UPDATE book SET b_name=?, b_unitPrice=?, b_author=?, b_description=?, b_publisher=?, b_category=?, b_unitsInStock=?, b_releaseDate=?, b_condition=? where b_bookId=?";
template.update(SQL, book.getName(), book.getUnitPrice(), book.getAuthor(), book.getDescription(), book.getPublisher(), book.getCategory(), book.getUnitsInStock(), book.getReleaseDate(), book.getCondition(), book.getBookId());
}
}
}
setUpdateBook() 메소드는 요청한 도서의 정보를 수정합니다.
도서 이미지가 없을 경우에는 b_fileName 필드를 제외하고 도서 내용을 갱신합니다.
BookService.java
setUpdateBook() 메소드를 추가합니다.
package com.springmvc.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.springmvc.domain.Book;
public interface BookService {
List<Book> getAllBookList();
List<Book> getBookListByCategory(String category);
Set<Book> getBookListByFilter(Map<String, List<String>> filter);
Book getBookById(String bookId);
void setNewBook(Book book);
void setUpdateBook(Book book);
}
BookServiceImpl.java
setUpdateBook() 메소드를 구현합니다.
package com.springmvc.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.springmvc.domain.Book;
import com.springmvc.repository.BookRepository;
@Service
public class BookServiceImple implements BookService {
@Autowired
private BookRepository bookRepository;
@Override
public List<Book> getAllBookList() {
// TODO Auto-generated method stub
return bookRepository.getAllBookList();
}
public List<Book> getBookListByCategory(String category) {
List<Book> booksByCategory = bookRepository.getBookListByCategory(category);
return booksByCategory;
}
public Set<Book> getBookListByFilter(Map<String, List<String>> filter) {
Set<Book> booksByFilter = bookRepository.getBookListByFilter(filter);
return booksByFilter;
}
public Book getBookById(String bookId) {
Book bookById = bookRepository.getBookById(bookId);
return bookById;
}
public void setNewBook(Book book) {
bookRepository.setNewBook(book);
}
public void setUpdateBook(Book book) {
bookRepository.setUpdateBook(book);
}
}
setUpdateBook() 메소드는 요청한 도서의 정보를 수정해서 갱신합니다.
BookController.java
GET 방식의 getUpdateForm() 메소드와 POST 방식의 submitUpdateBookForm() 메소드를 추가합니다.
package com.springmvc.controller;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.MatrixVariable;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.springmvc.domain.Book;
import com.springmvc.exception.BookIdException;
import com.springmvc.exception.CategoryException;
import com.springmvc.service.BookService;
import com.springmvc.validator.BookValidator;
import com.springmvc.validator.UnitsInStockValidator;
@Controller
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@Autowired
private UnitsInStockValidator unitsInStockValidator;
@Autowired
private BookValidator bookValidator;
@RequestMapping
public String requestBookList(Model model) {
List<Book> list = bookService.getAllBookList();
model.addAttribute("bookList", list);
return "books";
}
@RequestMapping("/all")
public ModelAndView requestAllBooks() {
ModelAndView modelAndView = new ModelAndView();
List<Book> list = bookService.getAllBookList();
modelAndView.addObject("bookList", list);
modelAndView.setViewName("books");
return modelAndView;
}
@RequestMapping("/{category}")
public String requestBooksByCategory(@PathVariable("category") String bookCategory, Model model) {
List<Book> booksByCategory = bookService.getBookListByCategory(bookCategory);
if(booksByCategory==null || booksByCategory.isEmpty()) {
throw new CategoryException();
}
model.addAttribute("bookList", booksByCategory);
return "books";
}
@RequestMapping("/filter/{bookFilter}")
public String requestBooksByFilter(
@MatrixVariable(pathVar="bookFilter") Map<String, List<String>> bookFilter, Model model) {
Set<Book> booksByFilter = bookService.getBookListByFilter(bookFilter);
model.addAttribute("bookList", booksByFilter);
return "books";
}
@RequestMapping("/book")
public String requestBookById (
@RequestParam("id") String bookId, Model model) {
Book bookById = bookService.getBookById(bookId);
model.addAttribute("book", bookById);
return "book";
}
@RequestMapping("/add")
public String requestAddBookForm(@ModelAttribute("NewBook") Book book) {
return "addBook";
}
@PostMapping("/add")
public String submitAddNewBook(@Valid @ModelAttribute("NewBook") Book book, BindingResult result) {
if(result.hasErrors())
return "addBook";
MultipartFile bookImage = book.getBookImage();
String saveName = bookImage.getOriginalFilename();
File saveFile = new File("C:\\upload",saveName);
if(bookImage!=null && !bookImage.isEmpty()) {
try {
bookImage.transferTo(saveFile);
book.setFileName(saveName);
} catch(Exception e) {
throw new RuntimeException("도서 이미지 업로드가 실패하였습니다",e);
}
}
bookService.setNewBook(book);
return "redirect:/books";
}
@ModelAttribute
public void addAttribute(Model model) {
model.addAttribute("addTitle", "신규 도서 등록");
}
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(bookValidator);
binder.setAllowedFields("bookId","name","unitPrice","author","description","publisher","category","unitsInStock","totalPages","releaseDate","condition","bookImage");
}
@ExceptionHandler(value= {BookIdException.class})
public ModelAndView handleError(HttpServletRequest req, BookIdException exception) {
ModelAndView mav = new ModelAndView();
mav.addObject("invalidBookId",exception.getBookId());
mav.addObject("exception",exception);
mav.addObject("url",req.getRequestURL()+"?"+req.getQueryString());
mav.setViewName("errorBook");
return mav;
}
@GetMapping("/update")
public String getUpdateBookForm(@ModelAttribute("updateBook") Book book, @RequestParam("id") String bookId, Model model) {
Book bookById = bookService.getBookById(bookId);
model.addAttribute("book", bookById);
return "updateForm";
}
@PostMapping("/update")
public String submitUpdateBookForm(@ModelAttribute("updateBook") Book book) {
MultipartFile bookImage = book.getBookImage();
String rootDirectory = "c:/upload/";
if(bookImage != null && !bookImage.isEmpty()) {
try {
String fname = bookImage.getOriginalFilename();
bookImage.transferTo(new File("c:/upload/"+fname));
book.setFileName(fname);
} catch(Exception e) {
throw new RuntimeException("Book Image saving failed", e);
}
}
bookService.setUpdateBook(book);
return "redirect:/books";
}
}
getUpdateBookForm() 메소드는 URL 요청이 /books/update이고 HTTP 메소드가 GET 방식일 때 매핑되는 메소드입니다.
수정하려는 도서를 updateBook 커맨드 객체로 뷰 페이지에 전달하고
updateForm 뷰 페이지를 반환합니다.
submitUpdateBookForm() 메소드는 URL 요청이 /books/update이고 HTTP 메소드가 POST 방식일 때 매핑되는 메소드입니다.
updateForm.jsp 페이지에서 <form:input> 태그에 입력된 수정 데이터 값을
updateBook 커맨드 객체로 전달되며 수정된 값으로 도서 정보가 저장됩니다.
수정 요청을 처리하고 URL이 /books로 이동합니다.
book.jsp
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<html>
<head>
<link href="<c:url value="/resources/css/bootstrap.min.css"/>" rel="stylesheet">
<script src="${pageContext.request.contextPath }/resources/js/controllers.js"></script>
<title>도서 상세 정보</title>
</head>
<body>
<div class="container">
<div class="row">
<c:choose>
<c:when test="${book.getBookImage()==null }">
<img src="<c:url value="C:\\upload\\${book.fileName }"/>" style="width:100%"/>
</c:when>
<c:otherwise>
<img src="<c:url value="C:\\upload\\${book.fileName }"/>" style="width:100%"/>
</c:otherwise>
</c:choose>
<div class="col-md-8">
<h3>${book.name }</h3>
<p>${book.description }</p>
<br/>
<p><b>도서코드 : </b><span class="badge badge-info">${book.bookId }</span>
<p><b>저자</b> : ${book.author }
<p><b>출판사</b> : ${book.publisher }
<p><b>출판일</b> : ${book.releaseDate }
<p><b>분류</b> : ${book.category }
<p><b>재고수</b> : ${book.unitsInStock }
<h4>${book.unitPrice }원</h4>
<br>
<form:form name="addForm" method="put">
<p><a href="javascript:addToCart('../cart/add/${book.bookId }')" class="btn btn-primary">도서주문 »</a>
<a href="<c:url value="/cart"/>" class="btn btn-warning">장바구니 »</a>
<a href="<c:url value="/books"/>" class="btn btn-secondary">도서 목록 »</a>
<sec:authorize access="isAuthenticated()">
<a href="<c:url value="/books/update?id=${book.bookId }"/>" class="btn btn-success">수정 »</a>
</sec:authorize>
</form:form>
</div>
</div>
</div>
</body>
</html>
시큐리티 태그를 사용하기 위해 태그 라이브러리를 선언합니다.
<sec:authorize>태그를 사용해서 관리자 인증 시 [수정] 버튼이 표시되도록 합니다.
updateForm.jsp
WEB-INF/views 폴더에 다음과 같이 뷰 페이지를 작성합니다.
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<link href="<c:url value="/resources/css/bootstrap.min.css"/>" rel="stylesheet">
<title>도서 상세 정보</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4">
<img src="<c:url value="c:/upload/${book.fileName }"></c:url>" alt="image" style="width:100%"/>
</div>
<div class="col-md-7">
<form:form modelAttribute="updateBook" action="./update?${_csrf.parameterName }=${_csrf.token }" class="form-horizontal" enctype="multipart/form-data">
<fieldset>
<div class="form-group row">
<label class="col-sm-2 control-label">도서 ID</label>
<div class="col-sm-6" style="padding-top:10px">
<form:input id="bookId" path="bookId" type="hidden" class="form-control" value="${book.bookId }"/>
<span class="badge badge-info">${book.bookId }</span>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">도서명</label>
<div class="col-sm-6">
<form:input path="name" class="form-control" value="${book.name }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">가격</label>
<div class="col-sm-6">
<form:input path="unitPrice" class="form-control" value="${book.unitPrice }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">저자</label>
<div class="col-sm-6">
<form:input path="author" class="form-control" value="${book.author }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">상세정보</label>
<div class="col-sm-6">
<form:textarea path="description" cols="50" rows="2" class="form-control" value="${book.description }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">출판사</label>
<div class="col-sm-6">
<form:input path="publisher" class="form-control" value="${book.publisher }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">분류</label>
<div class="col-sm-6">
<form:input path="category" class="form-control" value="${book.category }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">재고수</label>
<div class="col-sm-6">
<form:input path="unitsInStock" class="form-control" value="${book.unitsInStock }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">출판일</label>
<div class="col-sm-6">
<form:input path="releaseDate" class="form-control" value="${book.releaseDate }"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">상태</label>
<div class="col-sm-6">
<form:radiobutton path="condition" value="New"/>New
<form:radiobutton path="condition" value="Old"/>Old
<form:radiobutton path="condition" value="E-Book"/>E-Book
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 control-label">이미지</label>
<div class="col-sm-10">
<form:input path="bookImage" type="file" class="form-control"/>
</div>
</div>
<div class="form-group row">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-primary" value="수정"/>
<a href="<c:url value="/books/"/>" class="btn btn-primary">취소</a>
</div>
</div>
</fieldset>
</form:form>
</div>
</div>
</div>
</body>
</html>
<form:form> 태그의 modelAttribute 속성 값은 URL에 매핑되는 컨트롤러에 메소드의 매개변수로
선언한 커맨드 객체 이름 updateBook과 일치해야 합니다.
<form:input> 태그의 path 속성에 설정된 커맨드 객체의 필드 이름에 다라 필드 값이 출력됩니다.
[수정] 버튼을 누르면 커맨드 객체 이름 updateBook으로 입력된 모든 데이터가 바인딩됩니다.
이 때의 URL이 /updateForm이고 POST 방식이므로 submitUpdateFromBookForm() 메소드가 요청을 처리합니다.
[취소] 버튼을 누르면 도서 수정을 취소하고 /books 경로로 이동합니다.
tiles.xml
타일즈 설정 파일에 다음과 같이 내용을 추가합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="base-Template" template="/WEB-INF/tiles/layout/baseLayout.jsp">
<put-attribute name="title" value="Sample Title"/>
<put-attribute name="heading" value=""/>
<put-attribute name="subheading" value=""/>
<put-attribute name="menu" value="/WEB-INF/tiles/template/menu.jsp"/>
<put-attribute name="content" value=""/>
<put-attribute name="footer" value="/WEB-INF/tiles/template/footer.jsp"/>
</definition>
<definition name="welcome" extends="base-Template">
<put-attribute name="title" value="Welcome"/>
<put-attribute name="heading" value="도서 웹 쇼핑몰"/>
<put-attribute name="subheading" value="Welcome to BookMarket"/>
<put-attribute name="content" value="/WEB-INF/views/welcome.jsp"/>
</definition>
<definition name="books" extends="base-Template">
<put-attribute name="title" value="Books"/>
<put-attribute name="heading" value="도서 목록"/>
<put-attribute name="subheading" value="Books List"/>
<put-attribute name="content" value="/WEB-INF/views/books.jsp"/>
</definition>
<definition name="book" extends="base-Template">
<put-attribute name="title" value="Book"/>
<put-attribute name="heading" value="도서 정보"/>
<put-attribute name="subheading" value="Book Details"/>
<put-attribute name="content" value="/WEB-INF/views/book.jsp"/>
</definition>
<definition name="addBook" extends="base-Template">
<put-attribute name="title" value="Books"/>
<put-attribute name="heading" value="도서 등록"/>
<put-attribute name="subheading" value="Book Addition"/>
<put-attribute name="content" value="/WEB-INF/views/addBook.jsp"/>
</definition>
<definition name="login" extends="base-Template">
<put-attribute name="title" value="Login"/>
<put-attribute name="heading" value="로그인"/>
<put-attribute name="subheading" value="Login"/>
<put-attribute name="content" value="/WEB-INF/views/login.jsp"/>
</definition>
<definition name="cart" extends="base-Template">
<put-attribute name="title" value="Shopping Cart"/>
<put-attribute name="heading" value="장바구니"/>
<put-attribute name="subheading" value="Shopping Cart"/>
<put-attribute name="content" value="/WEB-INF/views/cart.jsp"/>
</definition>
<definition name="orderCustomerInfo" extends="base-Template">
<put-attribute name="title" value="Order"/>
<put-attribute name="heading" value="고객정보"/>
<put-attribute name="subheading" value="Customer Details"/>
<put-attribute name="content" value="/WEB-INF/flows/order/orderCustomerInfo.jsp"/>
</definition>
<definition name="orderShippingInfo" extends="base-Template">
<put-attribute name="title" value="Order"/>
<put-attribute name="heading" value="배송정보"/>
<put-attribute name="subheading" value="Shipping Details"/>
<put-attribute name="content" value="/WEB-INF/flows/order/orderShippingInfo.jsp"/>
</definition>
<definition name="orderConfirmation" extends="base-Template">
<put-attribute name="title" value="Order"/>
<put-attribute name="heading" value="주문정보"/>
<put-attribute name="subheading" value="Order Confirmation"/>
<put-attribute name="content" value="/WEB-INF/flows/order/orderConfirmation.jsp"/>
</definition>
<definition name="orderFinished" extends="base-Template">
<put-attribute name="title" value="Order"/>
<put-attribute name="heading" value="주문완료"/>
<put-attribute name="subheading" value="Thanks you"/>
<put-attribute name="content" value="/WEB-INF/flows/order/orderFinished.jsp"/>
</definition>
<definition name="orderCartWarning" extends="base-Template">
<put-attribute name="title" value="Order"/>
<put-attribute name="heading" value="주문취소"/>
<put-attribute name="subheading" value="Invalid Cart"/>
<put-attribute name="content" value="/WEB-INF/flows/order/orderCartWarning.jsp"/>
</definition>
<definition name="updateForm" extends="base-Template">
<put-attribute name="title" value="Book"/>
<put-attribute name="heading" value="도서수정"/>
<put-attribute name="subheading" value="Book Editing"/>
<put-attribute name="content" value="/WEB-INF/views/updateForm.jsp"/>
</definition>
</tiles-definitions>
실행 결과
/books를 입력하고 [상세정보] 버튼을 눌러서 도서의 가격을 변경해서 확인해 보겠습니다.
다음과 같이 수정이 완료되었습니다.
'SPRING' 카테고리의 다른 글
[Q] 의존성 주입은 무엇이고 스프링에서는 어떻게 관리할까? (0) | 2025.02.26 |
---|---|
[SPRING]#85 도서 쇼핑몰 구현 (DB 연동10) (0) | 2024.03.04 |
[SPRING]#83 도서 쇼핑몰 구현 (DB 연동8) (0) | 2024.03.04 |
[SPRING]#82 도서 쇼핑몰 구현 (DB 연동7) (0) | 2024.03.03 |
[SPRING]#81 도서 쇼핑몰 구현 (DB 연동6) (0) | 2024.03.03 |