Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 타임리프 - 기본기능
- 스프링 mvc1 - 스프링 mvc
- 자바의 정석 기초편 ch7
- 스프링 mvc1 - 서블릿
- 코드로 시작하는 자바 첫걸음
- 2024 정보처리기사 시나공 필기
- 스프링 mvc2 - 검증
- 자바의 정석 기초편 ch5
- 자바의 정석 기초편 ch2
- 자바의 정석 기초편 ch3
- 자바의 정석 기초편 ch14
- 자바의 정석 기초편 ch12
- jpa 활용2 - api 개발 고급
- 스프링 입문(무료)
- 스프링 db1 - 스프링과 문제 해결
- 자바의 정석 기초편 ch8
- 스프링 고급 - 스프링 aop
- 자바의 정석 기초편 ch11
- 자바의 정석 기초편 ch9
- jpa - 객체지향 쿼리 언어
- 게시글 목록 api
- 자바의 정석 기초편 ch4
- 스프링 mvc2 - 로그인 처리
- 스프링 db2 - 데이터 접근 기술
- 자바의 정석 기초편 ch1
- @Aspect
- 스프링 mvc2 - 타임리프
- 자바의 정석 기초편 ch13
- 자바의 정석 기초편 ch6
- 2024 정보처리기사 수제비 실기
Archives
- Today
- Total
나구리의 개발공부기록
스프링 MVC - 구조이해, 스프링 MVC (시작하기/컨트롤러 통합하기/실용적인 방식) 본문
인프런 - 스프링 완전정복 코스 로드맵/스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
스프링 MVC - 구조이해, 스프링 MVC (시작하기/컨트롤러 통합하기/실용적인 방식)
소소한나구리 2024. 2. 29. 23:25 출처 : 인프런 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (유료) / 김영한님
유료 강의이므로 정리에 초점을 두고 코드는 일부만 인용
1. 스프링 MVC - 시작하기
1) 스프링이 제공하는 컨트롤러
- 스프링이 제공하는 컨트롤러는 애노테이션 기반으로 동작하여 매우 유연하고 실용적임
- 과거에는 자바 언어에 애노테이션이 없었고 스프링도 처음부터 이런 유연한 컨트롤러를 제공하지 않았음
(1) @RequestMapping
- 스프링이 제공하는 매우 유연하고 실용적인 애노테이션 기반의 컨트롤러
- 과거에는 스프링 프레임워크가 MVC 부분이 약해서 스프링을 사용하여도 MVC웹기술은 다른 프레임워크를 사용했지만 @RequestMapping기반의 애노테이션 컨트롤러가 등장하면서 대부분의 실무에서 스프링 프레임워크를 사용함
- @RequestMapping의 앞글자를 따서 만든 RequestMappingHandlerMapping(핸들러 매핑)과 RequestMappingHandlerAdapter(핸들러 어댑터)가 애노테이션 기반의 컨트롤러를 지원하는 가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터이며 실무에서 99.9% 이 방식의 컨트롤러를 사용
(2) SpringMemberFormControllerV1 - 회원 등록 폼
- springmvc패키지 하위에 v1패키지 생성 후 작성
- @Controller : 스프링이 자동으로 스프링 빈으로 등록되며 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식함
내부에 @Component 애노테이션이 있어서 자동으로 컴포넌트 스캔의 대상이 됨 - @RequestMapping(메서드 레벨) : 요청 정보를 매핑, 해당 URL이 호출되면 메서드가 호출됨, 애노테이션을 기반으로 동작하기 때문에 메서드의 이름은 임의로 지으면 됨
- ModelAndView : 모델과 뷰 정보를 담아서 반환
package hello.servlet.web.springmvc.v1;
@Controller
public class SpringMemberFormController {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
** 주의 - 스프링 부트 3.0 이상!
- 스프링 부트 3.0(스프링 프레임워크 6.0)이전에는 클래스레벨에 @Component, @RequestMapping을 하면 스프링 컨트롤러로 인식하였지만 스프링 부트 3.0 이후 부터는 @Controller가 있어야 스프링 컨트롤러로 인식함
- RequestMappingHandlerMapping에서 @RequestMapping은 더이상 인식하지 않음
- @RequestMapping만 사용하고 직접 스프링 빈으로 등록하는 방식도 마찬가지로 사용 불가능하니 컨트롤러 사용시에는 깔끔하게 @Controller를 사용하면 됨
- 스프링 부트 3.0 미만에서도 동작하는 V1 컨트롤러
@Component //컴포넌트 스캔을 통해 스프링 빈으로 등록
@RequestMapping
public class SpringMemberFormControllerV1 {
// 메서드는 동일
}
@RequestMapping // 직접 스프링 빈으로 등록하면 컴포넌트 스캔이 없어도됨
public class SpringMemberFormControllerV1 {
// 메서드는 동일
}
(3) SpringMemberSaveControllerV1 - 회원 저장
- HttpServletRequest, Response로도 매개변수를 받을 수 있음
- mv.addObject("member", member): 스프링이 제공하는 ModelAndView를 통해 Model데이터를 추가할 때는 addObject()를 상용하면 되며 이 데이터는 이후 뷰를 렌더링할때 사용됨
package hello.servlet.web.springmvc.v1;
@Controller
public class SpringMemberSaveControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members/save")
public ModelAndView process(HttpServletRequest request, HttpServletResponse response) {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
(4) SpringMemberListControllerV1 - 회원 목록
package hello.servlet.web.springmvc.v1;
@Controller
public class SpringMemberListControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members")
public ModelAndView process() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.addObject("members", members);
return mv;
}
}
(5) 실행
- 애플리케이션 실행 후 각 컨트롤러에 매핑된 url로 접속해보면 정상적으로 동작함을 알 수 있음
2. 스프링 MVC - 컨트롤러 통합
1) @RequestMapping을 클래스 단위로 통합
- @RequestMapping이 클래스 단위가 아니라 메서드 단위에 적용 되어 있음
- 각 클래스로 나뉘어져있던 컨트롤러를 유연하게 하나의 클래스로 통합이 가능
(1) SpringMemberControllerV2
- v2패키지를 생성 후 작성
- 하나의 클래스로 통합이 되었지만 메서드레벨의 @RequestMapping에서 /springmvc/v2/members의 중복이 있음
- @RequestMapping("/springmvc/v2/members/new-form")
- @RequestMapping("/springmvc/v2/members")
- @RequestMapping("/springmvc/v2/members/save")`
package hello.servlet.web.springmvc.v2;
@Controller
public class SpringMemberControllerV2 {
// 코드 일부 생략
@RequestMapping("/springmvc/v2/members/new-form")
@RequestMapping("/new-form") // 코드 중복 제거
public ModelAndView newform() {
return new ModelAndView("new-form");
}
@RequestMapping("/springmvc/v2/members/save")
public ModelAndView save(HttpServletRequest request, HttpServletResponse response) {
// 메서드 구조는 동일
}
@RequestMapping("/springmvc/v2/members")
public ModelAndView members() {
// 메서드 구조는 동일
}
}
(2) 조합
- 컨트롤러 클래스를 통합하는 것을 넘어서 조합이 가능함
- 각 메서드에 @RequestMapping(/springmvc/v2/members)라는 부분이 중복된 부분을 제거하려면 @RequestMapping 애노테이션을 클래스 레벨로 설정하여 코드 중복을 제거할 수 있음
- 코드를 작성 후 실행해보면 모두 정상 동작함을 알 수 있음
package hello.servlet.web.springmvc.v2;
@Controller
@RequestMapping("/springmvc/v2/members") // 클래스 단위로 적용
public class SpringMemberControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form") // /spring/v2/members의 중복이 제거됨
public ModelAndView newForm() {
return new ModelAndView("new-form");
}
@RequestMapping("/save") // /spring/v2/members의 중복이 제거됨
public ModelAndView save(HttpServletRequest request, HttpServletResponse response) {
// 메서드 구조는 동일
}
@RequestMapping // /spring/v2/members의 중복이 제거됨
public ModelAndView members() {
// 메서드 구조는 동일
}
}
3. 스프링 MVC - 실용적인 방식
1) 실무에서 주로 사용하는 방식
- MVC 프레임워크 만들기를 하면서 v3 버전의 Controller는 ModelView를 개발자가 직접 생성해서 반환해서 불편했던 것을 v4 버전을 만들면서 실용적으로 개선했었음
- 스프링 MVC는 개발자가 편리하게 개발할 수 있도록 많은 편의기능을 제공하며 실무에서는 지금 설명하는 방식을 주로 사용함
(1) SpringMemberControllerV3
- v3패키지 생성 후 작성
- Model 파라미터 : save()와 members() 에서 Model을 파라미터로 받는데 스프링MVC에서 이러한 편의 기능을 제공함
- ViewName 반환 : 뷰의 논리 이름을 스트링으로 반환할 수 있음
- @RequestParam 사용 : HTTP 요청 파라미터를 받음,
request.getParameter와 거의 같은 코드라고 보면 되며 GET 쿼리파라미터, POST Form 방식을 모두 지원함 - @RequestMapping -> @GetMapping, @PostMapping으로 변경:
@RequestMapping은 URL만 매칭하는 것이 아니라 HTTP Method도 구분할 수 있음
예를 들어 HTTP Method가 GET인 경우를 모두 만족하는 매핑을 하려면 @RequestMapping(value = "/new-form", method = RequestMethod.GET)처럼 처리하면 됨
그러나 이것을 @GetMapping, @PostMapping으로 더 편리하게 사용가능하며 Put,Delete,Patch 등 모두 애노테이션으로 구현되어있음
package hello.servlet.web.springmvc.v3;
@Controller
@RequestMapping("/springmvc/v3/members") // 클래스 레벨에 @RequestMapping을 적용하여 코드 중복을 제거
public class SpringMemberControllerV3 {
private final MemberRepository memberRepository = MemberRepository.getInstance();
// @RequestMapping(value = "/new-form", method = RequestMethod.GET)
@GetMapping("/new-form") // 위와 동일한 애노테이션, HTTP Method가 GET이여야 함
public String newform() { // 인터페이스가 아닌 String으로 반환
return "new-form";
}
// @RequestMapping(value= "/save", method = RequestMethod.POST) // 매핑 중복 제거
@PostMapping("/save") // HTTP Method가 POST여야 함
public String save(@RequestParam("username") String username,
@RequestParam("age") int age,
Model model) {
Member member = new Member(username, age);
memberRepository.save(member);
model.addAttribute("member", member);
return "save-result";
}
// @RequestMapping(method = RequestMethod.GET) // 매핑 중복 제거
@GetMapping
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members", members);
return "members";
}
}