📌 웹 계층의 구현
- 웹 계층에서 가장 먼저 설계하는 것은 URI의 설계

URL이동 : Redirect 방식
📌 진행 작업의 순서
- 목록 페이지 - 모든 진입 경로인 동시에 입력을 가는 링크
- 등록 입력 / 처리 - 게시물 등록 및 처리, 처리 후 이동
- 조회 - 목록 페이지에서 특정 게시물로 이동
- 수정 / 삭제 - 조회 페이지에서 수정 / 삭제 선택해 처리
📌 BoardController 목록의 처리
- 게시물(BoardVO)의 목록을 Model에 담아서 전달
📝게시물 목록처리
자 그러면 컨트롤러를 만들어보자

위의 사진처럼 BoardController.java라는 이름의 컨트롤러를 만들고 로그에 list.........를 찍어서 test로 확인해보려고한다.
test클래스를 만들어주자

코드
package org.zero.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
//Test for Controller
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({
"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
//@AllArgsConstructor
@Log4j
public class BoardControllerTests {
@Setter(onMethod_={@Autowired})
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
@Test
public void testList() throws Exception {
log.info(
mockMvc.perform(MockMvcRequestBuilders.get("/board/list"))
.andReturn()
.getModelAndView()
.getModelMap());
}
}
testList메서드를 실행시켜보면?

이렇게 잘 나온다.
그럼 이제 서버를 실행시켜서 확인해보자
우선 서버의 실행 경로부터 바꿔주자.

"/controller"에서 "/"로 기본 경로로 바꾸어주고 서버를 실행시킨다.
그러면


이렇게 jsp를 찾을 수 없다는 표시와 list에 controller에 접근을 했다는 것을 알수있다.
그러면 404페이지말고 jsp파일을 만들어서 띄워보자
위에 경로에 맞게


list.jsp파일을 만들어 저장하면

이렇게 페이지가 잘나온다.
그러면 이 리스트페이지에 이제 정보를 띄워보자

final로 주입을 해주고 model로 list를 받아온 다음

list를 뽑아본 결과는??

이렇게 잘 가져온다.
여기까지 목록 처리 끝났으니 등록 처리를 해보자.
📝게시물 등록처리
- Post방식으로 처리되는 데이터를 BoardVO 타입의 인스턴스로 바인딩해서 메서드에서 활용
- BoardService를 이용해서 등록처리
- 'Redirect'를 이용해서 다시 목록으로 이동
우선 BoardController에 postmapping으로 잡아준다.

그리고 test코드에 아래 사진과 같이 작성한다.

결과는?

이렇게 원하는 정보가 들어갔다.
이렇게 post방식을 선택하면 후에 처리를 해주어야한다.
📌Post방식 후 처리
- 등록 / 수정 / 삭제의 최종처리는 POST방식을 이용
- 브라우저에는 어떤 결과를 보여줄 것인가?
- 별도의 결과 페이지를 만들어서 보여주는 방식
- 회원가입 완료페이지 등
- 목록 페이지로 이동하는 방식
- 목록 페이지에서 알림 메시지를 보여주는 방식
- 별도의 결과 페이지를 만들어서 보여주는 방식
- POST방식 후에는 'redirect:/...'를 고려하자
📌RedirectAttributes는 언제 사용하는가?
- 시나리오
- GET방식으로 입력페이지 /board/register
- POST 방식으로 입력 처리 /board/register
- 처리가 끝난 후 화면 이동을 해도 브라우저의 URL은 POST방식 처리 URL 그대로
- 만일 브라우저를 새로고침하면?
- 'redirect:/...'를 이용해서 브라우저와 연결을 한번 종료
- 브라우저는 새롭게 특정 URL을 요구
그래서 이제 post방식으로 전달을 하기로 정하였으니 parameter를 추가하여 redirect를 해보자
rttr.addAttribute로 전달한 값은 url뒤에 붙으며, 리프레시해도 데이터가 유지된다.
rttr.addFlashAttribute로 전달한 값은 url뒤에 붙지 않는다.
일회성이라 리프레시할 경우 데이터가 소멸한다.
또한 2개이상 쓸 경우, 데이터는 소멸한다.
따라서 맵을 이용하여 한번에 값전달해야한다.

📝게시물 수정

📝게시물 삭제

수정과 삭제는 로직이 거의 같다.
위에서 잘 따라왔다면 어려운 부분이 없기때문에
부연설명은 생략하겠다.
BoardController.java 코드
package org.zero.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
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.servlet.mvc.support.RedirectAttributes;
import org.zero.domain.BoardVO;
import org.zero.service.BoardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j;
@Controller
@RequiredArgsConstructor
@RequestMapping("/board/*")
@Log4j
public class BoardController {
private final BoardService service;
@GetMapping
public void list(Model model) {
log.info("list.................");
model.addAttribute("list",service.getList());
}
@PostMapping("/register")
public String register(BoardVO board, RedirectAttributes rttr) {
log.info("board: " + board);
service.register(board);
log.info("BNO: " + board.getBno());
rttr.addFlashAttribute("result", board.getBno());
return "redirect:/board/list";
}
@PostMapping("/modify")
public String modify(BoardVO board, RedirectAttributes rttr) {
int count = service.modify(board);
if(count == 1 ) {
rttr.addFlashAttribute("result","success");
}
return "redirect:/board/list";
}
@PostMapping("/remove")
public String modify(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
//@RequestParam은 안써줘도 된다. 명확히 하기위함
int count = service.remove(bno);
if(count == 1 ) {
rttr.addFlashAttribute("result","success");
}
return "redirect:/board/list";
}
}
다음 글에서 만들어 놓은 컨트롤러를 화면 처리하겠다.

'Spring' 카테고리의 다른 글
[Part 2] 템플릿 적용하기 #6 (0) | 2023.01.21 |
---|---|
[Part 2] 비즈니스 계층 #4 (0) | 2023.01.18 |
[Part 2] 게시물 조회/삭제/수정 #3 (0) | 2023.01.18 |
[Part 2] BoardVO클래스와 매퍼테스트 #2 (0) | 2023.01.17 |
[Part 2] 스프링 프로젝트 구성 #1 (0) | 2023.01.15 |