일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 주니어개발자
- 클라이언트 상태 관리 라이브러리
- prettier-plugin-tailwindcss
- Custom Hook
- 명시적 타입 변환
- 좋은 PR
- Compound Component
- jotai
- CS
- zustand
- Headless 컴포넌트
- 타입 단언
- react
- Recoil
- task queue
- 프로세스
- AJIT
- Microtask Queue
- Sparkplug
- Redux Toolkit
- useCallback
- type assertion
- Render Queue
- TypeScript
- JavaScript
- 암묵적 타입 변환
- useLayoutEffect
- linux 배포판
- helm-chart
- docker
- Today
- Total
구리
TIL_210623_SpringMVC_어노테이션 설정(@RequestMapping, ModelAttribute, RequestParam, SessionAttributes) 본문
TIL_210623_SpringMVC_어노테이션 설정(@RequestMapping, ModelAttribute, RequestParam, SessionAttributes)
guriguriguri 2021. 6. 22. 21:25목차
1. 어노테이션 설정
2. Controller 클래스에 @Controller 어노테이션 설정
3. @RequestMapping 사용
4. 클라이언트 요청 처리 - Command 객체 이용
글 등록 기능 구현
글 목록 검색 구현
글 상세 보기 구현
글 삭제 구현
글 수정 구현
로그인 기능 구현
로그아웃 기능 구현
컨트롤러 통합하여 하나의 클래스로 생성
요청 방식에 따른 처리 - @RequestMapping의 method
JSP에서 Command 객체 사용
@ModelAttribute - Command 객체 이름 변경
Servlet API 사용
일관성 있는 Controller 리턴 타입
기타 어노테이션 사용
- @RequestParam 사용
- @ModelAttribute : View에서 사용할 데이터 설정
- @SessionAttributes
1. 어노테이션 설정
<context:component-scan> 엘리먼트로 스캔 범위를 설정합니다.
(base-package 속성에 Controller 클래스들이 있는 패키지로 등록)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.springbook.view"></context:component-scan>
</beans>
2. Controller 클래스에 @Controller 어노테이션 설정
@Component를 상속한 @Controller는 클래스의 객체를 메모리에 생성하는 기능, DispatcherServlet이 인식하는 Controller 객체로 만드는 기능이 있습니다.
스프링 컨테이너는 @Controller가 선언된 객체를 자동으로 Controller 객체로 인식합니다.
(만약 어노테이션 사용을 원치 않는다면 Controller 인터페이스를 구현한 클래스로 생성한 후 handleRequest() 메소드를 재정의해야 합니다. 그후 스프링 설정파일에서 <bean>으로 생성하면 됩니다.)
3. @RequestMapping 사용
스프링에서는 @RequestMapping 를 이용하여 HandlerMapping 설정을 대체합니다.
예시
@Controller
public class InsertBoardController {
@RequestMapping(value="/insertBoard.do")
public void insertBoard(BoardVO vo){
System.out.println("글 등록 처리");
// 1. 사용자 입력 정보 추출
String title = request.getParameter("title");
String writer = request.getParameter("writer");
String content = request.getParameter("content");
// 2. DB 연동 처리
BoardVO vo = new BoardVO();
vo.setTitle(title);
vo.setWriter(writer);
vo.setContent(content);
BoardDAO boardDAO = new BoardDAO();
boardDAO.insertBoard(vo);
}
}
위의 설정은 아래의 XML 설정 방식과 같은 의미입니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- HanlderMapping 등록 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/insertBoard.do">insertBoard</prop>
</props>
</property>
</bean>
<!-- Controller 등록 -->
<bean id="insertBoard" class="com.springbook.view.board.InsertBoardController"></bean>
</beans>
4. 클라이언트 요청 처리 - Command 객체 이용
Controller는 파라미터로 전달받는 값을 일일이 getParameter() 메소드로 추출하는 것이 아닌 Command 객체를 이용하여 호출할 메소드의 매개변수에 대입하여 값을 전달하는 것이 편리합니다.
(Command 객체 : Controller 메소드 매개변수로 받는 VO(Value Object) 객체를 의미)
예시
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class InsertBoardController {
public InsertBoardController() {
}
@RequestMapping(value="/insertBoard.do")
public void insertBoard(BoardVO vo){
System.out.println("글 등록 처리");
BoardDAO boardDAO=new BoardDAO();
boardDAO.insertBoard(vo);
}
}
insertBoard() 메소드의 매개변수로 사용자가 입력한 값을 매핑할 BoardVO 클래스를 선언하면, 스프링 컨테이너가 Command 객체를 생성하고 입력값을 세팅하여 념겨줍니다.
결과적으로 컨테이너가 자동으로 사용자 입력 정보 추출, VO 객체 생성, 값 설정을 처리하게 됩니다.
즉, 컨트롤러의 메소드의 매개변수에 사용자가 입력한 값을 매핑할 객체 클래스를 선언하여 처리하는 것이 좋습니다.
정리하면 클라이언트가 글 등록 요청시, 스프링 컨테이너는 InsertBoardController 객체의 insertBoard() 메소드 호출
① 매개변수에 해당하는 BoardVO 객체생성
② 입력값 (title,writer..) 추출 후 BoardVO 객체에 저장, 이때 BoardVo 클래의 Setter 메소드 호출
③ insertBoard() 메소드 호출시, 입력값들이 설정된 BoardVO 객체가 인자로 전달
글 등록 기능 구현
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class InsertBoardController {
public InsertBoardController() {
}
@RequestMapping(value="/insertBoard.do")
public String insertBoard(BoardVO vo, BoardDAO boardDAO){
System.out.println("글 등록 처리");
boardDAO.insertBoard(vo);
return "getBoardList.do";
}
}
글 등록 처리 후 글 목록 페이지로 이동하기 위한 GetBoardListController 실행을 위해 String 리턴 타입 변경 및 DB 연동을 위한 BoardDAO 매개변수 추가 선언
Q) redirect: 와 그냥 View 경로 리턴하는 것의 차이는 ?
Controller 메소드 실행 후 View 경로 리턴시 기본 포워딩 방식으로 브라우저의 URL이 변경되지 않습니다.
http://localhost:9000/BoardWeb/inserBoard.do
하지만 리다이렉트를 원할시 "redirect:" 접두사를 붙이고 브라우저의 URL도 변경됩니다.
http://localhost:9000/BoardWeb/getBoardList.do
글 목록 검색 구현
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class GetBoardListController{
@RequestMapping("/getBoardList.do")
public ModelAndView getBoardList(BoardVO vo, BoardDAO boardDAO, ModelAndView mav) {
System.out.println("글목록 처리");
mav.addObject("boardList", boardDAO.getBoardList(vo));
mav.setViewName("getBoardList.jsp");
return mav;
}
}
getBoardList() 메소드 매개변수는 총 3개로, 사용자 입력값을 받기 위한 BoardVO 클래스, DB 연동 처리를 위한 BoardDAO 클래스, 마지막으로 검색 결과 및 화면 정보를 저장하여 리턴하기 위한 ModelAndView를 매개변수로 선언하였습니다.
글 상세 보기 구현
package com.springbook.view.board;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class GetBoardController {
@RequestMapping("/getBoard.do")
public ModelAndView getBoard(BoardVO vo, BoardDAO boardDAO, ModelAndView mav) {
System.out.println("글 상세 조회 처리");
mav.addObject("board", boardDAO.getBoard(vo));
mav.setViewName("getBoard.jsp");
return mav;
}
}
글 삭제 구현
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class DeleteBoardController{
@RequestMapping("/deleteBoard.do")
public String deleteBoard(BoardVO vo, BoardDAO boardDAO) {
System.out.println("글 삭제 처리");
boardDAO.deleteBoard(vo);
return "getBoardList.do";
}
}
글 수정 구현
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class UpdateBoardController{
@RequestMapping("/updateBoard.do")
public String updateBoard(BoardVO vo, BoardDAO boardDAO){
System.out.println("글 수정 처리");
boardDAO.updateBoard(vo);
return "getBoardList.do";
}
}
로그인 기능 구현
package com.springbook.view.user;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.springbook.biz.board.UserVO;
import com.springbook.biz.board.impl.UserDAO;
@Controller
public class LoginController{
@RequestMapping("/login.do")
public String login(UserVO vo,UserDAO userDAO) {
System.out.println("로그인 처리");
if(userDAO.getUser(vo) != null) return "getBoardList.do";
else return "login.jsp";
}
}
로그아웃 기능 구현
package com.springbook.view.user;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LogoutController{
@RequestMapping("/logout.do")
public String logout(HttpSession session) {
System.out.println("로그아웃 처리");
session.invalidate();
return "login.jsp";
}
}
로그아웃 처리를 위한 세션 객체가 필요하여 매개변수로 선언하였고 스프링 컨테이너가 로그아웃을 요청한 브라우저와 매핑된 세션 객체를 찾아서 넘겨주게 됩니다. 그러면 매개변수로 받은 세션 객체를 강제 종료하면 됩니다.
컨트롤러 통합
package com.springbook.view.board;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
public class BoardController {
@RequestMapping("/insertBoard.do")
public String insertBoard(BoardVO vo, BoardDAO boardDAO){
System.out.println("글 등록 처리");
boardDAO.insertBoard(vo);
return "getBoardList.do";
}
@RequestMapping("/getBoardList.do")
public ModelAndView getBoardList(BoardVO vo, BoardDAO boardDAO, ModelAndView mav) {
System.out.println("글목록 처리");
mav.addObject("boardList", boardDAO.getBoardList(vo));
mav.setViewName("getBoardList.jsp");
return mav;
}
@RequestMapping("/getBoard.do")
public ModelAndView getBoard(BoardVO vo, BoardDAO boardDAO, ModelAndView mav) {
System.out.println("글 상세 조회 처리");
mav.addObject("board", boardDAO.getBoard(vo));
mav.setViewName("getBoard.jsp");
return mav;
}
@RequestMapping("/updateBoard.do")
public String updateBoard(BoardVO vo, BoardDAO boardDAO){
System.out.println("글 수정 처리");
boardDAO.updateBoard(vo);
return "getBoardList.do";
}
@RequestMapping("/deleteBoard.do")
public String deleteBoard(BoardVO vo, BoardDAO boardDAO) {
System.out.println("글 삭제 처리");
boardDAO.deleteBoard(vo);
return "getBoardList.do";
}
}
간단히 구현되는 Controller를 관리하기 편하게 하나의 클래스로 묶어서 처리한 코드입니다.
요청 방식에 따른 처리
@RequestMapping을 이용해 GET, POST 방식에 따라서 달리 수행될 메소드를 설정할 수 있습니다.
@RequestMapping에 method 속성을 추가하여 설정할 수 있습니다.
예시
package com.springbook.view.user;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.springbook.biz.board.UserVO;
import com.springbook.biz.board.impl.UserDAO;
@Controller
public class LoginController{
@RequestMapping(value="/login.do", method=RequestMethod.GET)
public String loginView(UserVO vo) {
System.out.println("로그인 화면으로 이동");
vo.setId("test123");
vo.setPassword("test123");
return "login.jsp";
}
@RequestMapping(value="/login.do", method=RequestMethod.POST)
public String login(UserVO vo,UserDAO userDAO) {
System.out.println("로그인 인증 처리");
if(userDAO.getUser(vo) != null) return "getBoardList.do";
else return "login.jsp";
}
}
loginView() 메소드를 보면 로그인 화면으로 이동하는 메소드로 사용자 입력값이 없는데 UserVO 객체를 매개변수로 설정하였습니다.
이는 매개변수로 받은 Command 객체에 원하는 데이터 설정시, 리턴된 JSP 파일에서 사용 가능합니다.
JSP에서 Command 객체 사용
loginView() 매개변수로 설정된 UserVo 객체를 login.jsp에서 사용
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>로그인</title>
</head>
<body>
<center>
<h1>로그인</h1>
<hr />
<form action="login.do" method="post">
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<td bgcolor="orange">아이디</td>
<td><input type="text" name="id" value="${userVO.id }"></td>
</tr>
<tr>
<td bgcolor="orange">비밀번호</td>
<td><input type="password" name="password" value="${userVO.password }"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="로그인"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
@ModelAttribute 사용하여 Command 객체 이름 변경하기
원래 스프링 컨테이너가 생성한 Command 객체 이름 => 클래스 이름의 첫글자를 소문자로 변경한 이름
(login.jsp를 보면 UserVO 객체 => ${userVO} 로 사용)
변경을 원할시 @ModelAttribute 사용
예시
@RequestMapping(value="/login.do", method=RequestMethod.GET)
public String loginView(@ModelAttribute("user") UserVO vo) {
System.out.println("로그인 화면으로 이동");
vo.setId("test123");
vo.setPassword("test123");
return "login.jsp";
}
Servlet API 사용
로그인 성공시 사용자 이름을 세션에 저장 후, 글목록 화면 출력하기
package com.springbook.view.user;
import javax.servlet.http.HttpSession;
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.springbook.biz.board.UserVO;
import com.springbook.biz.board.impl.UserDAO;
@Controller
public class LoginController{
@RequestMapping(value="/login.do", method=RequestMethod.POST)
public String login(UserVO vo,UserDAO userDAO, HttpSession session) {
System.out.println("로그인 인증 처리");
UserVO user = userDAO.getUser(vo);
if(user != null) {
session.setAttribute("userName", user.getName());
return "getBoardList.do";
}
else return "login.jsp";
}
}
Controller 리턴 타입
그동안의 코드들을 보다시피, String 리턴 타입일 경우 완벽한 View 이름을 문자열로 리턴하고, ModelAndView일 경우 검색된 Model 데이터와 View 이름을 모두 저장하여 리턴하였습니다. 하지만 대부분 프로젝트는 일관성 있는 코드를 중시하기에 리턴타입을 통일하는 것이 좋습니다.
예시(getBoardList와 getBoard Controller 메소드의 리턴 타입을 String 으로 변경)
@RequestMapping("/getBoardList.do")
public String getBoardList(BoardVO vo, BoardDAO boardDAO, Model model) {
System.out.println("글목록 처리");
model.addAttribute("boardList", boardDAO.getBoardList(vo));
return "getBoardList.jsp";
}
@RequestMapping("/getBoard.do")
public String getBoard(BoardVO vo, BoardDAO boardDAO, Model model) {
System.out.println("글 상세 조회 처리");
model.addAttribute("board", boardDAO.getBoard(vo));
return "getBoard.jsp";
}
View 이름을 문자열로 리턴하면 스프링 컨테이너는 리턴된 JSP 파일을 찾아 실행하며 전달하고 싶은 데이터는 Model에 저장하여 전달합니다.
기타 어노테이션 사용
1) @RequestParam 사용
Command 객체에는 없는 파라미터 정보를 추출하여 Controller 클래스에서 사용할 경우
예시
@RequestParam(value="searchCondition",
defaultValue="TITLE",
required=false) String condition,
- value : 화면으로부터 전달될 파라미터 이름
- defaultValue : 화면으로부터 전달될 정보가 없을 때, 설정할 기본값
- required : 파라미터의 생략 여부
만약 getBoardList.jsp에서 검색 조건에 따른 결과값을 출력하려고 할 때
getBoardList.jsp 코드
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<center>
<h1>글 목록</h1>
<h3>${userName }님 환영합니다 ! <a href="logout.do">Log-out</a></h3>
<!-- 검색 시작 -->
<form action="getBoardList.jsp" method="post">
<table border="1" cellpadding="0" cellspacing="0" width="700">
<tr>
<td align="center">
<select name="searchCondition">
<option value="TITLE">제목</option>
<option value="CONTENT">내용</option>
</select>
<input name="searchKeyword" type="text" />
<input value="검색" type="submit" />
<input>
</td>
</tr>
</table>
</form>
<table border="1" cellpadding="0" cellspacing="0" width="700">
<tr>
<th bgcolor="orange" width="100">번호</th>
<th bgcolor="orange" width="200">제목</th>
<th bgcolor="orange" width="150">작성자</th>
<th bgcolor="orange" width="150">등록일</th>
<th bgcolor="orange" width="100">조회수</th>
</tr>
<c:forEach items="${boardList }" var="board">
<tr>
<td>${board.seq }</td>
<td align="left"><a href="getBoard.do?seq=${board.seq }">${board.title }</a></td>
<td>${board.writer }</td>
<td>${board.regDate }</td>
<td>${board.cnt }</td>
</tr>
</c:forEach>
</table>
<br />
<a href="insertBoard.jsp">새글 등록</a>
</center>
</body>
</html>
BoardController - getBoardList() 메소드 @RequestParam 적용 코드
@RequestMapping("/getBoardList.do")
public String getBoardList(@RequestParam(value="searchCondition", defaultValue="TITLE", required=false) String condition,
@RequestParam(value="searchKeyword", defaultValue="", required=false) String keyword, BoardDAO boardDAO, Model model) {
System.out.println("검색 조건 : " + condition);
System.out.println("검색 단어 : " + keyword);
// model 정보 저장
// model.addAttribute("boardList", boardDAO.getBoardList(vo));
return "getBoardList.jsp";
}
코드를 해석하면 searchCondition이 필수 파라미터는 아니지만 만약 파라미터 정보가 전달된다면 해당 값을 추출하여 condition 변수에 할당하고, 파라미터 정보가 전달되지 않으면 기본값으로 TITLE 문자열을 할당하라는 의미입니다.
만약 @RequestParam 어노테이션이 싫다면 BoardVO 클래스에 추가 멤버변수와 Setter 메소드를 선언하는 방법도 있습니다.
@ModelAttribute 사용하여 View에서 사용할 데이터 설정하기
@ModelAttribute가 설정된 메소드는 @RequestMapping 어노테이션이 적용된 메소드보다 먼저 호출되며 @ModelAttribute 메소드 실행 결과로 리턴된 객체는 자동으로 Model에 저장됩니다.
따라서 @ModelAttribute 메소드의 실행 결과로 리턴된 객체를 View 페이지에서 사용할 수 있습니다.
@Controller
public class BoardController {
@RequestMapping("/insertBoard.do")
public String insertBoard(BoardVO vo, BoardDAO boardDAO){
System.out.println("글 등록 처리");
boardDAO.insertBoard(vo);
return "getBoardList.do";
}
@ModelAttribute("conditionMap")
public Map<String, String> searchConditionMap(){
Map<String, String> conditionMap =new HashMap<String, String>();
conditionMap.put("제목", "TITLE");
conditionMap.put("내용", "CONTENT");
return conditionMap;
}
@RequestMapping("/getBoardList.do")
public String getBoardList(BoardVO vo, BoardDAO boardDAO, Model model) {
// model 정보 저장
model.addAttribute("boardList", boardDAO.getBoardList(vo));
return "getBoardList.jsp";
}
}
① 클라이언트가 "/getBoardList.do" 요청을 전송
② @ModelAttribute 가 설정된 searchConditionMap() 메소드가 먼저 실행
③ 그러면 @ModelAttribute 로 지정된 이름으로 searchConditionMap() 메소드가 리턴한 값을 Model 객체에 저장
④ 그러고 나서야 클라이언트가 호출한 getBoardList() 메소드 실행
⑤ 이때, boardList 라는 이름으로 검색 결과를 Model에 저장하면 최종적으로 Model에는 2개의 컬렉션이 저장
getBoardList.jsp 코드 수정 후 실행시 결과는 다음과 같습니다
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>글 목록</title>
</head>
<body>
<center>
<h1>글 목록</h1>
<h3>${userName }님 환영합니다 ! <a href="logout.do">Log-out</a></h3>
<!-- 검색 시작 -->
<form action="getBoardList.jsp" method="post">
<table border="1" cellpadding="0" cellspacing="0" width="700">
<tr>
<td align="right">
<select name="searchCondition">
<c:forEach items="${conditionMap }" var="option">
<option value="${option.value }" />${option.key}
</c:forEach>
</select>
<input name="searchKeyword" type="text" />
<input value="검색" type="submit" />
</td>
</tr>
</table>
</form>
<table border="1" cellpadding="0" cellspacing="0" width="700">
<tr>
<th bgcolor="orange" width="100">번호</th>
<th bgcolor="orange" width="200">제목</th>
<th bgcolor="orange" width="150">작성자</th>
<th bgcolor="orange" width="150">등록일</th>
<th bgcolor="orange" width="100">조회수</th>
</tr>
<c:forEach items="${boardList }" var="board">
<tr>
<td>${board.seq }</td>
<td align="left"><a href="getBoard.do?seq=${board.seq }">${board.title }</a></td>
<td>${board.writer }</td>
<td>${board.regDate }</td>
<td>${board.cnt }</td>
</tr>
</c:forEach>
</table>
<br />
<a href="insertBoard.jsp">새글 등록</a>
</center>
</body>
</html>
@SessionAttributes 사용하기
수정 작업 처리시 유용하게 사용하는 어노테이션입니다.
예시
package com.springbook.view.board;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
@Controller
@SessionAttributes("board")
public class BoardController {
@RequestMapping("/getBoard.do")
public String getBoard(BoardVO vo, BoardDAO boardDAO, Model model) {
System.out.println("글 상세 조회 처리");
model.addAttribute("board", boardDAO.getBoard(vo));
return "getBoard.jsp";
}
@RequestMapping("/updateBoard.do")
public String updateBoard(@ModelAttribute("board") BoardVO vo, BoardDAO boardDAO){
System.out.println("번호 : " + vo.getSeq());
System.out.println("제목 : " + vo.getTitle());
System.out.println("작성자: " + vo.getWriter());
System.out.println("내용 : " + vo.getContent());
System.out.println("등록일 : " + vo.getRegDate());
System.out.println("조회수 : " + vo.getCnt());
boardDAO.updateBoard(vo);
return "getBoardList.do";
}
}
위 코드의 과정을 요약하면
① 사용자가 상세 화면 요청시 getBoard() 메소드는 검색 결과인 BoardVO 객체를 board라는 Model에 저장합니다.
② 이때, BoardController 클래스에 선언된 @SessionAttributes ("board")로 인해 Model에 "board"라는 이름으로 저장된
데이터가 있다면 그 데이터를 세션(HttpSession)에도 자동으로 저장하게 됩니다.
(당연히 이 BoardVo 객체에는 상세 화면에 출력된 모든 정보(title,cnt 등..)이 저장된 상태)
③ 글 수정 버튼 클릭시 updateBoard() 메소드 호출 => 스프링 컨테이너는 @ModelAttribute("board") 설정을 우선적으로
해석하여 세션에 board 이름의 데이터 존재하는지 확인
④ 존재하다면 세션에서 꺼내 매개변수로 선언된 vo 변수에 할당
⑤ 사용자가 입력한 파라미터값을 vo 객체에 할당
=> 따라서 새로 수정한 정보(title, content)값만 새롭게 할당되고 나머지(seq,writer,regDate, cnt)는 상세 보기를 했을 때 세션에
저장된 데이터가 유지됩니다.
결과 화면
'SPRING FRAMEWORK' 카테고리의 다른 글
TIL_210624_Spring 파일 업로드 처리 (0) | 2021.06.23 |
---|---|
TIL_210623_SpringMVC_비즈니스 컴포넌트 사용, 비즈니스 컴포넌트 로딩, 검색 기능 구현 (0) | 2021.06.22 |
TIL_210622_Spring MVC_스프링 설정파일, 인코딩 설정 (0) | 2021.06.22 |
TIL_210621_스프링 트랜잭션 처리 (0) | 2021.06.21 |
TIL_210618_어노테이션 기반 AOP (0) | 2021.06.18 |