[TIL] 3월 10일

yeon·2021년 3월 10일
0

@ExceptionHandler의 사용

Exception Handling in Spring MVC

@ControllerAdvice, @ExceptionHandler를 이용한 예외처리 분리, 통합하기(Spring에서 예외 관리하는 방법, 실무에서는 어떻게?)

userRepository에서 객체 꺼내올때 orElseThrow()이용

위의 두 블로그 보고 @ExceptionHandler 를 이용해서 예외발생시 nullErrorHandle 페이지 띄우도록 함

nullError.html 왜 파일 아이콘이 안뜨지 → 조원들한테 해당 문제 공유했는데 파일 이름때문인듯 하다. 근데 봉프는 아이콘이 잘뜬다고 한다. 뭐가 문제인지는 모르겠지만 파일 이름을 바꿔서 해결했다.

회원정보 수정하기

@PostMapping("/{id}")
public String updateForm(@PathVariable Long id, User newUser) {
    User user = userRepository.findById(id).orElseThrow(NullPointerException::new);
    user.update(newUser);
    return "redirect:/users";
}

여기서 자바지기님 영상에는 마지막에 userRepository.save(user)라고 해주라고 나오지만 쿠퍼의 pr을 보니 JPA에서 자동으로 변경감지를 해주기때문에 이부분을 안써도 된다고 한다.

→ 잘못된 부분임 save()써줘야함

https://jojoldu.tistory.com/415

블로그 글을 보니 Dirty checking이란 상태 변경 검사

JPA에서 트랜잭션이 끝나는 시점에 변화가 있는 엔티티 객체들을 데이터베이스에 자동반영해주는기능

HTTP의 put 메소드 이용하기

{{#user}}
<form name="user" method="post" action="/users/{{id}}">
    <input type="hidden" name="_method" value="put"/>
...
  • < input type="hidden" name="_method" value="put"/ > 추가

    • 서버에서 _method 라는 인자가 전달이 되면 value에 해당되는 메소드(put)를 호출한다.

      @PutMapping("/{id}")
      public String updateForm(@PathVariable Long id, User newUser) {
          User user = userRepository.findById(id).orElseThrow(NullPointerException::new);
          user.update(newUser);
          return "redirect:/users";
      }
  • 기존의 @PostMapping을 @PutMapping으로 변경해서 해당 메소드는 정보을 수정하는 역할을 한다는것을 명시
    - 하지만 html에서 실질적으로 사용하는건 post고 추가적인 값을 _method로 전달함으로서 put사용이 가능해진다.
    - application.properties에 spring.mvc.hiddenmethod.filter.enabled=true를 추가해야 한다. 아니면 수정하기 버튼 누르면 405에러 뜸

@RequestParam으로 비밀번호 일치하는지 확인하는 기능 추가

스프링 controller에서 파라미터를 받는 다양한 방법 ( @RequestParam, @RequestBody, @PathVariable)

putMapping 입력값 가져오기라는 키워드로 검색해서 @RequestParam 이라는 어노테이션을 이용하면 된다는걸 알았다.

→ @RequestParam("inputPassword")라고 하면 뷰에 있는 name 속성의 inputPassword를 가져온다는 의미로 이해하고 코드를 짰는데 잘 동작한다.

findOne() 사용하는걸로 바꿀라하는데 에러 발생

Can't use findOne() in my code with JpaRepository

You used an old version of spring-data-jpa, which had a findOne() method. Now you're using a more recent version, which doesn't have it anymore. As simple as that. findById() is what you should use in the newer version. Read the damn javadoc. That's what it's for. – JB Nizet Mar 29 '18 at 17:32

→ 옛날버전이니 대신에 findById()를 쓰라 함

REST API

[REST API] REST API 규칙/PUT과 POST 차이/PUT과 PATCH 차이

REST란?

Representational State Transfer

REST API는 웹의 장점을 최대한 활용할수 있는 아키텍쳐

  • REST의 구성

    • 자원(Resource) : URI

    • 행위(Verb) : HTTP method

    • 표현(Representations)

      → URI를 통해 자원을 표시하고, HTTP 메소드를 이용해서 해당 자원의 행위를 규정하고 그 결과를 받는것

  • POST와 PUT을 구분하기 위해 멱등성의 개념 필요

멱등성(Idempotence)이란?

여러번 수행해도 서버자원의 상태값이 동일함을 의미

  • GET, PUT, DELETE는 같은 경로로 여러번 호출해도 결과가 같다.
  • POST는 매 호출마다 새로운 데이터가 추가된다.
  • POST 연산은 결과가 Idempotent하지 않지만, PUT은 반복 수행해도 그 결과가 Idempotent하다.

Layered Architecture (계층화 아키텍쳐)

계층화 아키텍쳐(Layered Architecture)의 구성요소

Presentation Layer : View

  • 표현과 이벤트 처리, 데이터 포맷 책임
  • 사용자와의 접점에 위치
  • 데이터를 입력받고, 요청된 데이터를 출력하는 계층
  • 컨트롤러의 구성요소와 상호작용함

Control Layer : Controller

  • 구성요소간의 처리 흐름 제어, 데이터 조작 의뢰, 데이터 변환과 연산, Exception과 Error
  • 전달받은 데이터의 유효성 검증 처리
  • 로직에 요청을 전달
  • 로직에서 반환된 응답을 적절한 뷰로 연결

Business Layer : Service

  • Control Layer와 Persistence Layer를 연결하는 역할

    → 두 계층이 직접 통신하지 않게하여 애플리케이션의 유연성을 증가시킴

  • transaction 처리

  • 비즈니스 로직처리와 비즈니스와 관련된 도메인 모델의 적합성을 검증

Persistence Layer : DAO

  • 데이터를 꺼내서 객체화 시킨다.
  • 데이터베이스에 접근하여 데이터를 CRUD하는 계층

Domain Model Layer : VO, DTO

  • 데이터 객체
  • 관계형 데이터베이스의 엔티티와 비슷한 개념

MVC

Spring MVC 처리 순서

[Spring] Spring에서 말하는 Spring MVC 이란?

Spring MVC 구성 주요 컴포넌트 (블로그에 있는 그림보고 되새기면서 노트에 적어봄)

스크린샷 2021-03-10 오후 10 02 56

블로그에 있는 내용을 참고해서 흐름을 정리해보았다. (View와 ViewResolver 부분은 그림에 있는 번호와 아래 정리한 번호순서가 다름)

  1. Client가 URL로 접근하여 정보 요청

  2. DispatcherServlet은 해당 요청을 매핑한 Controller가 있는지 검색하기 위해 Request를 HandlerMapping에게 위임한다.

  3. HandlerMapping은 requestURL과 Controller 클래스의 매핑을 관리한다.(@RequestMapping)

    해당 Controller에게 요청을 처리하도록 위임한다.

  4. Controller는 @RequestMapping을 통하여 요청을 처리할 메서드에 호출된다.

    해당 요청을 처리할 Service를 주입(DI)받아서 Service에게 위임한다.

    connection pool을 담당하는 DAO가 주입(DI)받아 대신 DB에 접근한다. (@Repository)

    결과를 다시 Controller에게 전달한다.

    View에 전달할 결과 데이터(Model)와 이동할 화면(View)정보를 ModelAndView 인스턴스에 담아 DispatcherServlet에 반환한다.

  5. DispatcherServlet은 VeiwResolver에게 View Name을 전달한다.

  6. ViewResolver는 전달받은 View Name을 이용해 알맞는 View객체를 찾는다. View에 Model을 rendering하여 View 인스턴스를 다시 DispatcherServlet에 보낸다.

  7. DispatcherServlet은 최종결과를 클라이언트에 응답한다.


오늘 한일

  • 오늘도 역시 코드리뷰를 통해 많이 배웠다. 히로 덕분에 @Service에 개념을 더 잘 알게되었다. 일단은 루카스와 동영상을 따라하는 식으로 진행하고 있지만 추후에 기능이 더해지면 Controller에서 Service에게 요청을 전달하고, 비즈니스 로직은 Service가 갖도록 프로젝트를 구성해보자.
  • 블로그를 보고 전체적인 스프링 MVC의 처리 순서를 학습했다. qna프로젝트의 흐름에 대입해서 대략적으로 이해해보려고 했다.
  • REST API에 대해 학습했다. 생활코딩의 영상을 보고 추가적으로 학습해보자.

기계들의 대화법 - REST API

  • 계층화 아키텍쳐의 각 계층마다 담당한 역할에 대해 학습했다.

  • 미션 2 pr 보냈다.

    • @ExceptionHandler를 사용해봤다. NullPointerException 발생시 새로운 뷰를 출력하도록 했다. 맞게한건지는 모르겠지만 잘못되었다면 피드백이 올것이다.

    • 쿠퍼의 미션2 pr을 보고 회원정보 수정시 JPA가 자동으로 변경감지를 해줘서 save를 안해줘도 된다는 것을 배웠다.

    • 회원정보 수정하는 기능을 PUT방식으로 요청하는것을 구현함으로써 PUT방식과 POST방식의 차이를 알았다. 멱등성에 대해서도 학습했다.

      → POST는 동일한 요청을 여러번 수행하면 서버자원의 상태값이 바뀌므로 멱등성이 보장되지 않는다.

    • 사용자에게 입력받은 데이터를 파라미터로 받기위해 @RequestParam 어노테이션을 사용한다는 것을 배웠다. @PathVariable은 URL경로로부터 받아온다.

느낀점

  • 멱등성 글을 보다가 디온의 새로운 글(어떻게 하면 스터디를 잘 할 수 있는가?)을 봤다. 지금은 코드스쿼드 과정 따라가기도 벅차서 당장 스터디 참여를 할수는 없고, 내가 낼수 있는 노력의 80프로만 쓴다는 글을 인상깊게 보았다. 이게 번아웃에 빠지지 않는 비결이라고 한다. 나도 cs10과정을 통해 욕심내서 공부하면 금방 하기싫음을 느끼는걸 겪었다. 조급함때문에 약간 무리하게 학습하곤 했는데 이전에 비해서는 나아졌지만 아직도 욕심을 버리지 못하는거 같다. 나도 모르게 아직도 남들과 비교하면서 조급함을 느끼고있다는 증거인듯하다. 그래도 스프링 미션1을 했을때보다는 지식이 조금씩 쌓이는거 같아서 좋다.(아직도 하아아안참 멀었지만..)

Todo

  • 생활코딩 REST API 영상 보기
  • 루카스에 있는 DNS 원리 링크 보기
  • 데이터베이스 학습

2개의 댓글

comment-user-thumbnail
2021년 3월 11일

완전 정리 잘 하셨네요! 연 포스팅 보고 많이 배웠어요 ㅎㅎ

1개의 답글