공부기록/Spring

Spring MVC1

jhs0129 2021. 12. 31. 15:31
320x100
반응형
320x100

Spring MVC기본 흐름

구성 요소 설명
DispatcherServlet 클라이언트 요청 전달받는다 컨트롤러로부터 view전달받아 응답 생성
HandlerMapping 요청 URL로부터 어떤 컨트롤러를 사용할 지 결정
HandlerAdapter 처리 요청을 컨트롤러에 전달
Controller 로직 처리 (개발자 구현 부분)
ViewResolver 물리적인 경로를 논리적 경로로 변경
View JSP thymeleaf html등 화면 구성 (개발자 구현 부분)

HandlerMapping, HandlerAdapter 구현객체

<mvc:annotation-driven/> 태그를 이용해서 설정

ViewResolver 구현객체

만약 전달받은 물리적 경로가 hello면 /WEB-INF/views/hello.jsp로 반환되어 전달

<bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/> <!--경로 앞부분-->
    <property name="suffix" value=".jsp"/> <!--경로 뒷부분-->
</bean>

컨트롤러 구현

모든 컨트롤러는 @Controller 어노테이션을 사용하여 적용된다

@Controller, @RequestMapping, Model

@Controller
public class HelloController {

    @RequestMapping("/")
    public String process(Model model){
        model.addAttribute("greeting", "hello");
        return "index";
    }
}

@Controller

@Controller 어노테이션은 @Component를 포함하고 있기 때문에 Spring에 의해서 빈으로 등록이 되어진다

빈으로 등록되어 지기 위해서는 dispatcher-servlet에 <context:component-scan base-package="controller"/>를 통해서 base-package를 기준으로 빈 등록을 하게 된다

해당 태그를 사용을 하게 되면 자동으로 등록이 되지만 사용을 하지 않는다면 spring di에서 했듯이 직접 xml파일을 열어 일일이 bean을 등록을 해주어야 하는 번거로움이 있다

Model

참고로 Model말고도 ModelAndView객체가 있는데 해당 객체는 모델 설정과 뷰 이름을 같이 DispatcherServlet으로 전송을 해주는 객체이다

두가지 방식중에 자신이 원하는 방식을 선택하여 사용하면 될 듯하다 하지만 ModelAndView객체를 추가 생성하고 하는 일이 번거롭다고 생각되기 때문에 위 예시처럼 경로를 반환하는 것을 사용하는 것이 좋다고 생가각된다

@RequestMapping("/modelAndview")
public ModelAndView process(){
    ModelAndView mv = new ModelAndView();
    mv.addObject("hello", "hello");
    mv.setViewName("index");
    return mv;
}

@RequestMapping

해당 경로로 요청이 왔을 경우 처리하도록 해준다

  • 메서드, 클래스 각각 적용이 가능하다관련이 있는 것들을 하나의 컨트롤러에서 관리를 할경우 해당 코드처럼 상위 경로는 객체에 하위 경로는 메서드에 적용을 할 수 있다
@Controller 
@RequestMapping("/basic") 
public class HelloController { 
    @RequestMapping("/") //경로 설정 생략가능 --> @RequestMapping 
    public String process(Model model){ 
    model.addAttribute("greeting", "hello"); 
    return "index"; 
}
@RequestMapping("/modelAndview") 
public ModelAndView process1(){ 
    ModelAndView mv = new ModelAndView(); 
    mv.addObject("hello", "hello"); 
    mv.setViewName("index"); 
    return mv; 
} 

ex) process1에 대해서 관리되는 경로는 /basic/modelAndView이다

  • Http 전송 방식 지정
    @RequestMapping("/hello", method=RequestMethod.GET)는 GET 전송 방식을 지정 한 것이다 @GetMapping("/hello")로 변경이 가능하다

GET, POST, PUT, PATCH, DELETE등 여러 방식이 가능하다

  • 경로변수 지정
    @RequestMapping("/members/{memberId}") 
    public String member(@PathVariable(memberId) String memberId){
      ... 
    return "member/detail"; 
    }

@PathVariable(memberId) String memberId처럼 경로 변수와 매개변수의 이름이 같을 경우 @PathVariable String memberId로 변경이 가능하다

  • 요청/응답 컨텐트 타입 지정

@RequestMapping("/members/{memberId}", consumes="application/json): 요청 타입 지정
@RequestMapping("/members/{memberId}", produces="application/json): 응답 타입 지정

  • 요청 파라미터 값 구하기

기존 방식

public String list(HttpServletRequest request){
    String name = request.getParameter("name");
    ...
}

어노테이션 사용

public String list(@RequsetParam(name) String name){
    String userName = name;
    ...
}

추가사항: 필수가 아니라면 속성 값중 required=false로 지정

기본 값이 있다면 defaultValue="value"지정

타입이 맞지 않다면 spring이 변환을 해주지만 a와 같은 문자를 숫자로 변환은 안되기 때문에 오류 발생하기 때문에 주위해야한다

객체 사용

@RequestMapping("/save-form")
public String save(){
    return "saveform";
}

@RequestMapping(value="/save", method=RequestMethod.POST)
public String result(@ModelAttribute(name="findMember) Member member, Model model){
    model.addAttribute("member", member);
    return "save-result";
}

만약 처리해야할 파라미터값이 많다면 일일이 @RequestParam을 설정을 하는것은 고역일 것이다

그럴때는 하나의 model을 만들어서(위의 예시에서는 Member) 사용을 하면 spring이 알아서 프로퍼티를 매핑을 해준다

name속성은 view에서 사용될 이름이다

@ModelAttribute어노테이션은 생략이 가능하다 --> 생략하면 view에서 객체의 첫글자를 소문자로 바꾼 이름으로 사용

 

model.addAttribute()를 이용하여 뷰에 모델도 전달을 해준다

 

 

참고: @ModelAttribute를 메서드 단위에 지정을 할경우 해당 컨트롤러에 있는 메서드중 Model객체를 가지는 것들에 모두 추가를 해준다

 

@ModelAttribute("regions") //Model을 가지고 있는 컨트롤러는 무조건 가지고 시작
    public Map<String, String> regions(){
        Map<String, String> regions = new LinkedHashMap<>();
        regions.put("SEOUL", "서울");
        regions.put("BUSAN", "부산");
        regions.put("JEJU", "제주");
        return regions;
    }

리다이렉트

뷰 이름 앞에 redirect:를 붙이면 된다

 

 

참조

 

1. 인프런_스프링 MVC 2편 - 백엔드 웹개발 핵심 기술_김영한 님 강의

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

320x100
반응형