인프런 김영한 님의 강의를 참고했습니다.
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의
웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -
www.inflearn.com
저번에 만들었던 서블릿들을 이제 스프링 부트에 맞게 바꾸어 보도록 하자.
스프링은 기존에 작성했던 서블릿과는 다르게 @annotation을 많이 활용한다.
우선 저번에 만들었던 Form을 이렇게 수정했다.
package hello.servlet.web.springmvc.version1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class SpringStudentFormControllerV1 {
@RequestMapping("/springmvc/v1/students/new-form")
public ModelAndView process(){
return new ModelAndView("new-form");
}
}
@Controller를 달아서 스프링에서 컨트롤러로 인식하도록 한다, 그리고 메서드에 @RequestMapping으로 URL을 mapping 한다.
return은 저번에 작성했던 것과 비슷하게 ModelAndView 클래스에 생성자로 뷰 path를 넘겨주면 된다.
Save 부분도
package hello.servlet.web.springmvc.version1;
import hello.servlet.domain.student.Student;
import hello.servlet.domain.student.StudentRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class SpringStudentSaveControllerV1 {
private StudentRepository studentRepository = StudentRepository.getInstance();
@RequestMapping("/springmvc/v1/students/save")
public ModelAndView process(HttpServletRequest request, HttpServletResponse response){
String studentName = request.getParameter("studentName");
int year = Integer.parseInt(request.getParameter("year"));
Student student = new Student(studentName, year);
studentRepository.save(student);
ModelAndView modelAndView = new ModelAndView("save-result");
modelAndView.addObject("student", student);
return modelAndView;
}
}
이렇게 Mapping을 해주고 ModelAndView를 사용해서 Path 입력해주고 객체를 넣어주면 된다.
List도 같은 방식으로 작성한다.
package hello.servlet.web.springmvc.version1;
import hello.servlet.domain.student.Student;
import hello.servlet.domain.student.StudentRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
public class SpringStudentListControllerV1 {
private StudentRepository studentRepository = StudentRepository.getInstance();
@RequestMapping("/springmvc/v1/students")
public ModelAndView process(){
List<Student> students = studentRepository.findAll();
ModelAndView modelAndView = new ModelAndView("students");
modelAndView.addObject("students", students);
return modelAndView;
}
}
이제 여기서 리펙토링을 해보도록 하자.
어차피 mapping은 메서드에 하나씩 들어가게 된다.
그러면 한 컨트롤러에 작성할 수도 있지 않을까?
물론 된다.
한 컨트롤러에 작성하고 다른 주소들을 Mapping 해주면 된다.
package hello.servlet.web.springmvc.version2;
import hello.servlet.domain.student.Student;
import hello.servlet.domain.student.StudentRepository;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
@Controller
@RequestMapping("/springmvc/v2/students")
public class SpringStudentControllerV2 {
private StudentRepository studentRepository = StudentRepository.getInstance();
@RequestMapping("/new-form")
public ModelAndView newForm(){
return new ModelAndView("new-form");
}
@RequestMapping("/save")
public ModelAndView save(HttpServletRequest request, HttpServletResponse response){
String studentName = request.getParameter("studentName");
int year = Integer.parseInt(request.getParameter("year"));
Student student = new Student(studentName, year);
studentRepository.save(student);
ModelAndView modelAndView = new ModelAndView("save-result");
modelAndView.addObject("student", student);
return modelAndView;
}
@RequestMapping
public ModelAndView students(){
List<Student> students = studentRepository.findAll();
ModelAndView modelAndView = new ModelAndView("students");
modelAndView.addObject("students", students);
return modelAndView;
}
}
이렇게 메서드들의 이름만 분리해서 작성할 수 있다.
이제 마지막으로 @RequestParam까지 이용해보자.
이걸 이용하면 request에서 getParam을 쓸 필요가 없어진다.
바로 파라미터에서 가져올 수 있게 된다.
package hello.servlet.web.springmvc.version3;
import hello.servlet.domain.student.Student;
import hello.servlet.domain.student.StudentRepository;
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 java.util.List;
@Controller
@RequestMapping("/springmvc/v3/students")
public class SpringStudentControllerV3 {
private StudentRepository studentRepository = StudentRepository.getInstance();
@GetMapping("/new-form")
public String newForm(){
return "new-form";
}
@PostMapping("/save")
public String save(
@RequestParam("studentName") String studentName,
@RequestParam("year") int year,
Model model){
Student student = new Student(studentName, year);
studentRepository.save(student);
model.addAttribute("student", student);
return "save-result";
}
@GetMapping
public String students(Model model){
List<Student> students = studentRepository.findAll();
model.addAttribute("students", students);
return "students";
}
}
이렇게 ModelAndView를 리턴하는게 아니라 String을 리턴하면 자동으로 해당 Path를 찾아가게 된다.
Mapping에 Get, Post를 설정할 수 있으며 Model에 값을 추가하여 ModelAndView처럼 동작하게 할 수 있다.