스프링 버전으로 기존의 뉴스 웹 서비스를 수정하기 위해서 컨트롤러를 새로 만들어야한다.
하지만 뷰와 모델 부분은 약간의 수정만 하면된다.
따라서 컨트롤러 코드는 기존 컨트롤러에서 재활용 하게 될것이다.
1️⃣ 모델 코드 수정
News.java는 수정할 부분이 없고
NewsDAO는 아래처럼 스프링 빈 등록을 위해 @Component 어노테이션만 추가해주면된다.
@Component
public class NewsDAO {
final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
final String JDBC_URL = "jdbc:mariadb://localhost:3306/spring"; //spring내부에 news 테이블
...
}
2️⃣ NewsWebController 작성
개요
NewsWebController 클래스의 경우 각각의 요청(등록, 목록, 상세보기, 삭제)에
동작하는 메소드는 복사해서 사용하고 일부 코드만 수정해줄것이다.
WebMVC 컨트롤러와 요청 경로를 지정하기 위한 어노테이션을 추가후
컨트롤러에서 사용할 NewsDAO 빈을 주입하기 위해 필드 선언과 로깅을 위한 Logger 객체 선언부를 추가해줄것이다.
생성자 주입을 사용해 NewsDAO를 참조한다.
파일을 저장하기 위한 경로를 저장할 변수는 프로퍼티 파일로부터 @Value 어노테이션을 통해 가져올것이다.
package com.example.news;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/news")
public class NewsWebController {
final NewsDAO dao;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
//프로퍼티 파일에서 저장경로참조
@Value("${news.imgdir}")
String fdir;
@Autowired
public NewsWebController(NewsDAO dao) {
this.dao = dao;
}
}
뉴스웹컨트롤러 클래스는 스프링부트에서 자동으로 컨트롤러로 등록된다.
/news로 시작하는 URL요청에 동작하게 된다.
NewsDAO는 뉴스웹컨트롤러 인스턴스 생성시 참조 가능한 상태가 된다.
컨트롤러에서 변경되는 부분
기존 서블릿 기반의 컨트롤러와 달리 action 파리미터에 따라
메소드가 실행되도록 하는 코드는 필요 X.
각 요청에 실행될 메소드에 어노테이션만 추가하면된다.
기존 메소드는 모두 재활용하여 어노테이션 추가 외 몇몇 공통적으로 달라지는 부분만 찾아서 수정할것이다.
달라지는 부분은 다음과 같다.
- HttpServletRequest
기존 메소드는 전달된 데이터의 참조와 뷰에 데이터를 전달하기 위한 용도로 HttpServletRequest
객체를 인자로 하고 있다.
스프링에선 필요없으므로 삭제할것이다.
- BeanUtil
HTML 폼 데이터 매핑을 위해 사용한 apache commons BeanUtils 라이브러리도 필요없다.
- ctx.log()
서블릿 콘텍스트를 참조해 로그 메시지를 남기기 위한 부분은
앞에서 초기화한 Logger 클래스를 사용하는것으로 대체해야 한다.
//기존
ctx.log("뉴스 추가 과정에서 문제 발생!!");
//변경
logger.info("뉴스 추가 과정에서 문제 발생!!");
- aid 참조
상세 보기와 삭제의 경우 요청 파라미터로 aid값을 받아 dao연동에 사용했다.
여기서 request 인자를 제거 했기 때문에
설계에 따라 요청 파라미터 / 경로 파라미터 방식을 사용할수있다.
//기존 아래 코드 제거
int aid = Integer.parseInt(request.getParameter("aid"));
- 뷰 연동
컨트롤러에서 뷰에 데이터를 전달하기 위해서 request.setAttribute()를 사용했지만
스프링에서 제공하는 Model인자를 사용하는것으로 바꿀것이다.
//기존
public String listNews(HttpServletRequest request) {
...
list = dao.getAll();
request.setAttribute("newslist", list);
}
//변경
public String listNews(Model m) {
...
list = dao.getAll();
m.addAttribute("newslist", list);
}
뷰를 리턴할 때 문자열로 하는건 동일하다.
리디렉션으로 이동하는 경우 기존 컨트롤러에서 스프링 프레임워크와 동일한 방식으로 처리하도록 구현했었다.
따라서 같은 코드를 사용할것이다.
다만 프로젝트 변경으로 경로가 바뀐 부분은 바꿔주자.
//기존
return "ch10/newsList.jsp";
return "redirect:/news.nhn?action=listNews";
//변경
return "news/newsList";
return "redirect:/news/list";
3️⃣ 컨트롤러 요청 처리 메소드 구현
변경될 부분을 요청 처리 메소드로 구현할것이다.
뉴스 추가
ㅎㅇ
@PostMapping("/add")
public String addNews(@ModelAttribute News news, Model m, @RequestParam("file") MultipartFile file) {
try {
//저장 파일 객체 생성
File dest = new File(fdir+"/"+file.getOriginalFilename());
//파일저장
file.transferTo(dest);
//News 객체에 파일일므 저장
news.setImg(dest.getName());
dao.addNews(news);
}
catch (Exception e) {
e.printStackTrace();
logger.info("뉴스 추가 과정에서 문제 발생!!!");
m.addAttribute("error", "뉴스가 정상적으로 등록되지 않았습니다!!");
}
return "redirect:/news/list";
}
내용
뉴스 삭제
ㅎㅇ
@GetMapping("/delete/{aid}")
public String deleteNews(@PathVariable int aid, Model m) {
try {
News n = dao.delNews(aid);
}
catch (SQLException e) {
e.printStackTrace();
logger.warn("뉴스 삭제 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스가 정상적으로 삭제되지 않았습니다!");
}
return "redirect:/news/list";
}
내용
뉴스 목록 보기
ㅎㅇ
@GetMapping("/list")
public String listNews(Model m) {
List<News> list;
try {
list = dao.getAll();
m.addAttribute("newslist", list);
}
catch (Exception e) {
e.printStackTrace();
logger.warn("뉴스 목록 생성 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스 목록이 정상적으로 처리되지않았습니다!");
}
return "news/newsList";
}
내용
뉴스 상세 보기
ㅎㅇ
@GetMapping("/{aid}")
public String getNews(@PathVariable int aid, Model m) {
try {
News n = dao.getNews(aid);
m.addAttribute("news", n);
}
catch (SQLException e) {
e.printStackTrace();
logger.warn("뉴스를 가져오는 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스를 정상적으로 가져오지 못했습니다!!");
}
return "news/newsView";
}
내용
전체코드는 아래와 같다.
package com.example.news;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.sql.SQLException;
import java.util.List;
@Controller
@RequestMapping("/news")
public class NewsWebController {
final NewsDAO dao;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
//프로퍼티 파일에서 저장경로참조
@Value("${news.imgdir}")
String fdir;
@Autowired
public NewsWebController(NewsDAO dao) {
this.dao = dao;
}
//뉴스추가
@PostMapping("/add")
public String addNews(@ModelAttribute News news, Model m, @RequestParam("file") MultipartFile file) {
try {
//저장 파일 객체 생성
File dest = new File(fdir+"/"+file.getOriginalFilename());
//파일저장
file.transferTo(dest);
//News 객체에 파일일므 저장
news.setImg(dest.getName());
dao.addNews(news);
}
catch (Exception e) {
e.printStackTrace();
logger.info("뉴스 추가 과정에서 문제 발생!!!");
m.addAttribute("error", "뉴스가 정상적으로 등록되지 않았습니다!!");
}
return "redirect:/news/list";
}
//뉴스삭제
@GetMapping("/delete/{aid}")
public String deleteNews(@PathVariable int aid, Model m) {
try {
dao.delNews(aid);
}
catch (SQLException e) {
e.printStackTrace();
logger.warn("뉴스 삭제 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스가 정상적으로 삭제되지 않았습니다!");
}
return "redirect:/news/list";
}
//뉴스목록
@GetMapping("/list")
public String listNews(Model m) {
List<News> list;
try {
list = dao.getAll();
m.addAttribute("newslist", list);
}
catch (Exception e) {
e.printStackTrace();
logger.warn("뉴스 목록 생성 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스 목록이 정상적으로 처리되지않았습니다!");
}
return "news/newsList";
}
//뉴스 상세 보기
@GetMapping("/{aid}")
public String getNews(@PathVariable int aid, Model m) {
try {
News n = dao.getNews(aid);
m.addAttribute("news", n);
}
catch (SQLException e) {
e.printStackTrace();
logger.warn("뉴스를 가져오는 과정에서 문제 발생!!");
m.addAttribute("error", "뉴스를 정상적으로 가져오지 못했습니다!!");
}
return "news/newsView";
}
}
4️⃣ 뷰 구현
newsList.jsp
form action 속성을 아래와 같이 수정해주자.
<form method="post" action="/news/add" enctype="multipart/form-data">
상세보기, 삭제 링크를 아래와 같이 수정해주자.
<li class="list-group-item list-group-item-action d-flex justify-content-between align-items-center">
<a href="/news/${news.aid}" class="text-decoration-none">
[${status.count}] ${news.title}, ${news.date}
</a>
<a href="/news/delete/${news.aid}">
<span class="badge bg-secondary"> ×</span>
</a>
</li>
newsView.jsp
수정 X
이제 테스트해보자.
http://localhost:포트/news/list에 접속해서 등록, 수정, 삭제, 상세보기를 모두해보자.
[메인으로 돌아가기]
'Java Spring > 책공부 1 (JSP와 스프링)' 카테고리의 다른 글
33. 스프링 뉴스 API 구현 (0) | 2022.07.20 |
---|---|
31. 프로젝트 개요 및 설정 (0) | 2022.07.19 |
30. 스프링 RestController구현 (0) | 2022.07.19 |
29. 스프링 MVC 컨트롤러 구현 (0) | 2022.07.19 |
28. 스프링 개발환경 설정 (0) | 2022.07.19 |