[KH정보교육원 당산] 72일 ( 어노테이션 방식)
어제 완성했던 XML방식의 Spring MVC를 이번에는 어노테이션 방식으로 변경
어노테이션을 사용하는 이유는 XML문서에 대한 과도한 설정을 방지하기 위해서 사용한다.
먼저 XML문서에서 context xml namespace를 추가한 후에 base-package지정
xmlns:context="http://www.springframework.org/schema/context" <--xml상단에 추가되었다.
<context:component-scan base-package="com.jdh.spring"></context:component-scan>
어노테이션을 이용하기에 등록해놨던 모든 bean들을 지워주고
context:component-scan 태그만 남겨놓는다.
base-package="기본패키지" <-- 지정한 패키지의 하위까지 검색하여 자동으로 객체를 등록
컨트롤러 역할을 담당하는 모든 클래스 선언부에 @Controller 어노테이션 부여
=> DispatcherServlet이 인식할 수 있는 컨트롤러 객체로 만들어준다.
** 만약 @Controller 어노테이션을 사용하지 않을 경우에는 스프링이 제공하는 Controller 인터페이스를 구현받아
handlerRequest() 메서드를 제정의 받아야한다.!!
InsertBoardController 클래스 수정
@Controller
public class InsertBoardController {
//<prop key="/insert.do">insertBoard</prop>와 같은 의미
@RequestMapping(value="/insertBoard.do")
public void insertBoard(HttpServletRequest request) {
String title = request.getParameter("title");
String content = request.getParameter("content");
String writer = request.getParameter("writer");
BoardVO vo = new BoardVO();
vo.setTitle(title);
vo.setContent(content);
vo.setWriter(writer);
BoardDAO dao = new BoardDAO();
dao.insertBoard(vo);
}
}
Controller 인터페이스 대신 어노테이션을 사용
@RequestMapping(value="/insertBoard.do")
** value 속성은 생략해도 무방하지만 정확한 경로를 알기위해서는 명시해줘야한다.
정확한 경로를 명시해줘서 검색시간을 최소화시킨다.
/insertBoard.do 요청이 들어왔을 때 해당 메서드가 호출될 수 있도록 매핑
이 때 사용자로부터 입력된 값은 매개변수인 HttpServletRequest request의 param 영역으로 전달된다.
일반적으로 사용자의 입력 값이 고정적일 경우에는 VO객체를 이용하여 DAO와 주고 받지만,
사용자의 입력값이 다양할 경우 VO객체를 여러가지 선언해야하는 단점이 발생한다.
이 단점을 보안하기 위하여 제공되는 객체가 Command객체
insertBoard()의 매개변수 타입을 BoardVO 타입으로 변경하여 스프링 컨테이너가 insertBoard()를 호출할 때 사용자 입력값들을 Command 객체에 넘겨주고 이 Command 객체를 insertBoard(BoardVO vo)의 매개변수인 vo 변수에게 전달하여 자동 매핑이 되도록 한다.
@Controller
public class InsertBoardController {
//<prop key="/insert.do">insertBoard</prop>와 같은 의미
@RequestMapping(value="/insertBoard.do")
public void insertBoard(BoardVO vo) {
BoardDAO dao = new BoardDAO();
dao.insertBoard(vo);
}
}
기존 타입의 request에서 BoardVO 타입으로 변경 후 코드가 짧아진것을 알수 있다.
BoardVO vo 매개변수 : 사용자 입력값과 자동 매핑 처리 => command객체
흐름)
클라이언트 요청(파라미터값으러 넘어감) -> Spring Container -> Command -> 해당 파라미터 보유한 VO클래스 검색 -> VO클래스 이용하여 VO객체 생성 -> VO객체의 setter메서드를 이용하여 값 저장
-> VO 객체를 해당 메서드의 매개변수한테 전달
**** 전달되는 파라미터 명과 VO클래스의 멤버변수명 반드시 일치해야한다.!!
데이터가 정상적으로 들어가는지 확인
데이터가 들어간후 어느페이지로 갈지 정하지 않았기 때문에 404에러는 당연한거다.
@Controller
public class InsertBoardController {
//<prop key="/insert.do">insertBoard</prop>와 같은 의미
@RequestMapping(value="/insertBoard.do")
public String insertBoard(BoardVO vo,BoardDAO dao) {
dao.insertBoard(vo);
return "redirect:getBoardList.do";
}
}
값이 넘어올때 dao 객체도 자동 생성
Controller 메서드가 실행되고 View 경로를 리턴하면 기본이 포워딩 방식
포워딩 방식으로 전달 되기 때문에 URL창을 확인해보면 URL이 변경되지 않는다.
=> 게시글 리스트 목록(getBoardList.do) 으로 넘어가도 URL상에서는 getBoard.do
그렇기에 포워딩이 아닌 리다이렉트로 전달할때는 redirect: 를 붙여서 경로를 반환한다.
페이지 전환 => return "redirect:getBoardList.do";
게시글 목록
@Controller
public class GetBoardListController {
@RequestMapping(value="/getBoardList.do")
public ModelAndView getBoardList(BoardVO vo, BoardDAO dao, ModelAndView mav) {
System.out.println("게시글 불러오기");
mav.addObject("board",dao.getBoardList(vo));
mav.setViewName("getBoardList.jsp"); //resolver가 없기때문에 정확히 명시
return mav;
}
}
마찬가지로 컨트롤러 어노테이션 사용
게시글 등록과 다른 부분은 getBoardList는 3개의 매개 변수를 가진다.
객체를 받을 vo, 데이터 접근을 위한 dao, 다음 저장한 값을 전달하기 위한 ModelAndView 객체
기존에는 List<BoardVO> 객체를 생성하여 그 안에 값을 담았는데
이번에는 굳이 그러지 않고 바로 값을 꺼낸 후에 boardList라는 변수명으로 담아서 전달.
다른 컨트롤러도 이와같이 해주면 된다.
위에서 했던 각각의 컨트롤러를 통합
BoardController 클래스 생성
@Controller
public class BoardController {
// 글등록
@RequestMapping(value = "/insertBoard.do")
public String insertBoard(BoardVO vo, BoardDAO dao) {
dao.insertBoard(vo);
return "redirect:getBoardList.do";
}
//게시글 목록
@RequestMapping(value="/getBoardList.do")
public ModelAndView getBoardList(BoardVO vo, BoardDAO dao,ModelAndView mav) {
System.out.println("게시글 불러오기");
mav.addObject("board",dao.getBoardList(vo));
mav.setViewName("getBoardList.jsp"); //resolver가 없기때문에 정확히 명시
return mav;
}
//상세보기
@RequestMapping(value="/getBoard.do")
public ModelAndView getBoard(BoardVO vo, BoardDAO dao, ModelAndView mav){
mav.addObject("board",dao.detailBoard(vo));
mav.setViewName("getBoard.jsp");
return mav;
}
//글 수정
@RequestMapping(value="/updateBoard.do")
public String updateBoard(BoardVO vo, BoardDAO dao){
dao.updateBoard(vo);
return "redirect:getBoardList.do";
}
//글 삭제
@RequestMapping(value="/deleteBoard.do")
public String deleteBoard(BoardVO vo, BoardDAO dao){
dao.deleteBoard(vo);
return "redirect:getBoardList.do";
}
}
UserController클래스 생성
@Controller
public class UserController {
@RequestMapping(value = "/login.do")
public String handleRequest(UserVO vo, UserDAO dao) throws Exception {
System.out.println("로그인");
UserVO user = dao.getUser(vo);
if (user != null) {
return "redirect:getBoardList.do";
} else {
return "redirect:login.jsp";
}
}
@RequestMapping(value = "/logout.do")
public String logout(HttpSession session) {
session.invalidate();
return "login.jsp";
}
}
코드를 보면 반환타입이 String타입 또는 ModelAndView로 되어있다.
이 코드를 String타입으로 통일시킬것이다.
기존 상세보기에서 반환타입이 ModelAndView로 되어있었다.
ModelAndView -> String으로 바꾸면 문제점이 return타입으로 경로만 넘어가고 값을 담은 board라는 객체는 넘어가지않는다. 이를 해결하기 위하여 Model 객체 생성하여 값을 저장 한 후에 넘기면 된다.
//상세보기
@RequestMapping(value="/getBoard.do")
public String getBoard(BoardVO vo, BoardDAO dao, Model model){
model.addAttribute("board",dao.detailBoard(vo));
return "getBoard.jsp";
}
검색 기능
게시글 목록을 나타내는 getBoardList.jsp 상단에 제목 또는 본문내용 검색을 통하여 게시글을 불러오는 기능 추가
<h2> 로그인 성공</h2> <a href="logout.do">로그아웃</a>
<form action="getBoardList.do" method="post">
<table border="1">
<tr>
<td align="center">
<select name="searchCondition">
<option value="title"> 제목
<option value="content"> 본문
</select>
<input type="text" name="searchKeyword" />
<input type="submit" value="검색" />
</td>
</tr>
</table>
</form>
넘어가는 파라미터명 : Select 태그의 seachCondition
option 태그의 title 또는 content
해당 파라미터명은 BoardVO에 멤버 변수로 설정되어있지 않다.
@RequestParam 어노테이션을 통하여 파라미터값을 직접 받을 것이다.
public ModelAndView getBoardList(@RequestParam(value="searchCondition", defaultValue="title") String condition,
@RequestParam(value="searchKeyword", defaultValue="") String keyword,
BoardVO vo, BoardDAO dao,ModelAndView mav) {
(@RequestParam(value="넘어오는파라미터명", defaultValue="값이없을때초기값") String 변수명) <--- 넘어온 값을 저장받을 변수
어노테이션 말고 기존방법대로 사용할려면 BoardVO에 해당 파라미터명의 멤버변수를 선언해서 사용하면된다.
검색 조건
@ModelAttribute("conditionMap")
public Map<String,String> seachConditionMap(){
Map<String,String> conditionMap = new HashMap<String,String>();
conditionMap.put("제목", "TITLE");
conditionMap.put("내용", "CONTENT");
return conditionMap;
}
@ModelAttribute("~~") => JSP 에서 사용될 변수명
검색 조건 메서드에 HashMap을 통하여 값을 설정 하였으므로 getBoardList.jsp 의 검색 창부분을 JSTL로 표현이 가능하다.
<select name="searchCondition">
<c:forEach items="${conditionMap }" var="option">
<option value="${option.value }">${option.key }</option>
</c:forEach>
</select>
이와같이 표현가능
Map이 가지고 있는 key와 value를 꺼낸다.
값을 추가할때는 Map에서 put메서드를 통하여 값을 넣어주면된다.
클래스 선언부에
@SessionAttributes("~~")
ex) @SessionAttributes("board") => 세션값 설정
해당 클래스에서 board라는 객체명으로 값이 전달 되면 세션선언 부분에 (board)라고 설정해놨기 때문에
세션으로 생성된다.
'Learn > KH정보교육원' 카테고리의 다른 글
[KH정보교육원 당산] 73일( Spring - Mybatis ) (0) | 2021.06.29 |
---|---|
[KH정보교육원 당산] 73일 (Spring - 파일업로드, 다국어처리, 데이터 변환) (0) | 2021.06.29 |
[KH정보교육원 당산] 71일 (model2 -> MVC 아키텍쳐) (0) | 2021.06.22 |
[KH정보교육원 당산] 70일(Spring - 트랜잭션, Model1 -> model2 -> Spring MVC) (0) | 2021.06.21 |
[KH정보교육원 당산] 68일 (Spring - JDBC / AOP ) (0) | 2021.06.17 |