skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

Spring Mvc #2

Open skarltjr opened 4 years ago

skarltjr commented 4 years ago

Model - View -Controller

MVC 패턴의 장점

● 동시 다발적(Simultaneous) 개발 - 백엔드 개발자와 프론트엔드 개발자가 독립적으로 개발을 진행할 수 있다. ● 높은 결합도 - 논리적으로 관련있는 기능을 하나의 컨트롤러로 묶거나, 특정 모델과 관련있는 뷰를 그룹화 할 수 있다. ● 낮은 의존도 - 뷰, 모델, 컨트롤러는 각각 독립적이다. ● 개발 용이성 - 책임이 구분되어 있어 코드 수정하는 것이 편하다. ● 한 모델에 대한 여러 형태의 뷰를 가질 수 있다.

MVC 패턴의 단점

● 코드 네비게이션 복잡함 ● 코드 일관성 유지에 노력이 필요함


-WebConfig로 WebMvcConfiguerer 구현해서 addInterCeptor -리소스핸들러 : 정적리소스처리를 위한 핸들러 / 디폴트서블릿 서블릿컨테이너가 기본으로 제공하는 서블릿. 정적리소스처리

skarltjr commented 4 years ago

@GetMapping("/hello") @ResponseBody public ResponseEntity hellohello() { //특정타입 객체를안다면 로 넣어서 ex> DTO // 응답에 status나 헤더 본문등을 동적으로 보내고싶을 때 //ResponseEntity build = ResponseEntity.ok().build(); return ResponseEntity.ok().build(); //이렇게 빌드하면 위에코드랑 똑같고 이를 리턴해주는것 /* 어쨋든 ResponseBody니까 본문에 응답한다/ }

skarltjr commented 4 years ago

@RequestParam / @ModelAttribute 간단 복기

// =========== RequestParam

    @GetMapping("/events2")
    public String eventsForm(Model model) {
        Event event = new Event();
        event.setLimit(50);
        event.setName("기본");
        model.addAttribute("event",event);
        return "events/form";
    }
    @PostMapping("/events2")
    @ResponseBody
    public Event getEvent3(@RequestParam(value = "name") String name, @RequestParam(value = "limit") Integer limit) {
        Event event = new Event();
        event.setName(name);
        event.setLimit(limit);
        return event;
    }

// ===== ModelAttribute 복합타입의 객체로 받는다 .유연함

    @GetMapping("/events3")
    public String eventsForm2(Model model) {
        Event event = new Event();
        event.setLimit(50);
        event.setName("기본");
        model.addAttribute("event",event);
        return "events/form";
    }
    @PostMapping("/events3")
    @ResponseBody           // 검증은 valid랑 validator만들어서 하면되는거고
    public Event getEvent4(@Valid @ModelAttribute EventForm eventForm, Errors errors) {
//        if (errors.hasErrors())
//        { ~~ } 에러있으면 처리해줘야하니까
        Event event = new Event();
        event.setLimit(eventForm.getLimit());
        event.setName(eventForm.getName());
        return event;
    }
skarltjr commented 4 years ago

@SessionAttributes("event") // model.addAttribute("event",event); -> event의 해당하는 modelattribute를 세션에도저장 ~Controller

/** @SessionAttributes = 만약 장바구니나 여러페이지에 걸쳐서 폼을 채워야한다면

  • 사용할 수 있는데 받은 정보를 바로 처리하는게 아니라 여러 폼에 걸쳐서 입력받은 후
  • 처리해야하니까 이것을 세션에 저장해놨다가 처리할 수 있도록해주는것
  • modelAttribute가 이런 세션정보도 매핑해준다*/

    //여기서 이름만넣도록하고

    @GetMapping("/events/form/name")
    public String eventForm_Name(Model model) {
        model.addAttribute("event", new Event());                                                      // 여기 이 event말하는것 맨위
        return "/events/form-name";
    }

    // 이름만받고 세선에도 event객체가 저장 modelAttribute는 세션에있는 정보도 바인딩해준다

    @PostMapping("/events/form/name")
    public String eventEventName(@Valid @ModelAttribute Event event, Errors errors) {
        if (errors.hasErrors()) {
            return "/events/form-name";
        }
        return "redirect:/events/form/limit";
    }

    //limit을 입력받는 폼으로 넘겨주고 넘겨줄 때 세션에서 event받은= 이름만 들어있는거 넘겨준다

    @GetMapping("/events/form/limit")
    public String eventForm_limit(@ModelAttribute Event event, Model model) {
        model.addAttribute("event", event);
        return "events/form-limit";
    }

    // 이름만받고 세선에도 event객체가 저장 modelAttribute는 세션에있는 정보도 바인딩해준다

    
    @PostMapping("/events/form/limit")
    public String eventEventLimit(@Valid @ModelAttribute Event event, Errors errors) {
        if (errors.hasErrors()) {
            return "events/form-limit";
        }
        return "redirect:/events/list";
    }
@GetMapping("/events/list")
public String getEvents(@ModelAttribute Event event, Model model, SessionStatus sessionStatus) {

    System.out.println(event.getName()+ " " + event.getLimit());
    List<Event> eventList = new ArrayList<>();
    eventList.add(event);
    model.addAttribute("eventList", eventList);
    sessionStatus.setComplete();// 다 채웠으면 세션을 비워준다
    return "events/list";
}

정리
-- >> get에서 모델로 정보를 담을 폼을 전달하고 post에서 폼을 채우는것을 여러 단계에 걸쳐서 하도록 해준다.
-->> 이 때 여러단계에 걸쳐서 정보를 담을 폼. 혹은 객체를 컨트롤러에 어노테이션으로 @SessionAttributes("event") 지정해준것
skarltjr commented 4 years ago
@PostMapping("/tags/add")
@ResponseBody
public ResponseEntity addTag(@CurrentUser Account account, @PathVariable String path,
                             @RequestBody TagForm tagForm) {
    Study study = studyService.getStudyToUpdateTag(account, path); //설정하고자 하는 스터디 가져오고
    Tag tag = tagService.findOrCreateNew(tagForm.getTagTitle()); // 태그가 존재하면 그대로가져오고 아니면 저장하고
    //태그 가져왔으면
    studyService.addTag(study, tag);
    return ResponseEntity.ok().build();
}

@ResponseBody ->본문으로 응답하겠다
@RequestBody  -> 본문에 데이터요청해서 받아오고 이를 컨버터로 변환한 객체를 받아올 수 있다.
skarltjr commented 4 years ago

//ResponseBody -> 아래에서 보면 리턴타입인 Event를 httpMessageConverter를 사용해서 응답본문에 담아준다. 즉 매서드에서 리턴하는 값을 컨버터를통해 응답본문에 담아준다 // RequestBody -> 반대로 받아올 때 응답본문에서 (여기서는 event)객체타입으로 메세지컨버터로 변환해서가져온다

@RestController
@RequestMapping("/api/events")
public class EventApi {

     @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
    public Event createEvent(@RequestBody @Valid Event event, Errors errors) {
        if (errors.hasErrors()) {
              return ResponseEntity.badRequest().build();
            //~~~ 에러있으면 처리하고
        }
        return event;
    }
}

===============

  @Test
    public void createEvent() throws Exception {
        Event event = new Event();
        event.setName("kiseok");
        event.setLimit(23);

        mockMvc.perform(post("/api/events")
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(event))) //본문내용을 json으로
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("name").value("kiseok"))
                .andExpect(jsonPath("limit").value("23"));
    }

============== 만약 return을 Event가 아니라 ResponseEntity로하면 굳이 RestController( == ResponseBody)를 쓸필요는 없다

    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE,produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Event> createEvent2(@RequestBody @Valid Event event, Errors errors) {
        if (errors.hasErrors()) {
                return ResponseEntity.badRequest().build();
            //~~~ 에러있으면 처리하고
        }

       //  new ResponseEntity<Event>(헤더 status등 설정할 수 )
        //이렇게 생성자로 만들어서 리턴하거나
        return ResponseEntity.ok(event);
    }