너무 쉬운건 제외하고, 알면 편한 기본적인 타임리프 문법을 정리한다. # th:if (조건문) 비밀번호가 틀립니다. 조건문이 참일경우만 해당 태그가 작동한다. # th:each (반복문) eList는 model로 내려진 iterable한 객체이다. # th:href, @{} 링크식에 쿼리 파라미터는 이렇게 넣으면 된다. # th:with (지역 변수 선언) # input form에서 POST로 넘긴 데이터 받는법 (하나) method="POST"로 무조건 대문자로 해준다 넘길 데이터의 이름은 name="식별자" 로 넘긴다 컨트롤러에서는 @RequestParam("식별자") 로 받는다 # input form에서 POST로 넘긴 데이터 받는법 (여러개=객체) th:object="${넘길 객체 이름}" 으로 ..
스프링 부트, 안드로이드 레트로핏2 통신 연동을 하면서 삽질했던 것들을 기록, 공유한다. # 애뮬레이터 로컬호스트 접근 안드로이드 애뮬레이터는 localhost로 서버에 접근할 수 없고, http://10.0.2.2:8080 꼭 이 주소로 접근해야함 (8080은 톰캣포트) # 레트로핏 @DELETE 쿼리에 바디 사용하기 원칙상 HTTP DELETE 메소드에는 바디를 사용할 수 없는데, 부득이하게 사용해야 하는 경우가 존재할 수 있다.(ex. 비밀번호 폼을 넘겨서 회원 탈퇴하기) 그럴땐 이렇게 메소드 매핑을 해주면 된다. @HTTP(method = "DELETE", path = "/users", hasBody = true)
2024.01.03 업데이트 # 서론 개발을 하다 보니 서버-서버로 HTTP 요청을 보내야 하는 상황이 생겼다. 그래서 몇 가지 조사를 해본 결과 스프링에서 기본적으로 제공하는 HTTP 전송용 모듈이 몇 개 있는 걸 발견했다. 그중 기본 내장되어 있는 게 RestTemplate이라는 모듈인데, 동기방식으로 요청을 처리하고 JSON 객체 변환하는 걸 도와주는 모듈이다. (그런데 지금은 WebClient라는 새로운 모듈에 자리를 뺏겨 더 이상 쓰이지 않을 예정이라고 한다.) WebClient는 비동기 방식으로 뭐 non-blocking 도 지원한다고 하는데, Spring WebFlux라는 라이브러리를 도입해야 해서 이는 찾아보니까 Spring MVC 구조랑 조금 다른 것 같았다. (Mono, Flux 어지러..
API 명세서를 처음에는 구글 스프레드 시트로 작성했다. 이러니까 공유하는 것에 불편함이 있어서 노션으로 바꾸었는데, 이러면 스프링에서 URI를 수정했을때 노션도 수동으로 수정해줘야 하는 번거로움이 있었다. 그래서 API 문서 자동화를 도와주는 툴인 Swagger를 도입했다. # Gradle 의존성 추가 implementation group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0' 3.0.0버전이 최신 버전인데 스프링과 호환 이슈가 조금 있는 것 같았다. 근데 저렇게 group, name, version을 명시하니 잘 호환되었다. 그냥 Gradle만 도입하면 이렇게 디폴트 Swagger UI를 제공한다. UI 접속 방법이 조금 ..
https://mopil.tistory.com/23 [Spring] 인증 구현1(로그인/로그아웃) - 쿠키 # 서론 HTTP는 무상태 프로토콜이다. 즉, 요청을 한번 처리하고 서버와 클라이언트는 연결이 끊긴다. 따라서 다음 요청을 보낼 때, 서버는 클라이언트가 누구인지 매번 확인해야 한다. 서버가 클 mopil.tistory.com 지난 포스트에서 사용자 인증을 쿠키로 구현했다 하지만, 여러가지 보안상 이슈가 있어서 해당 부분을 보완해야 했었다 보완해야 하는 부분은 다음과 같다 쿠키 값이 예측가능하면 안된다 예측 불가능한 쿠키 값을 서버쪽에서 유저 데이터와 매핑해서 관리하고, 쿠키 지속시간을 짧도록 유지한다 # 세션 도입 사실, 세션이라는 개념은 그리 거창한 개념은 아니다 완전한 랜덤값으로된 쿠키를 사용..
# 서론 HTTP는 무상태 프로토콜이다. 즉, 요청을 한번 처리하고 서버와 클라이언트는 연결이 끊긴다. 따라서 다음 요청을 보낼 때, 서버는 클라이언트가 누구인지 매번 확인해야 한다. 서버가 클라이언트가 누구인지, 어떻게 계속 확인할까? 이는 로그인의 기본 개념이다. 아이디어1 쿼리로 계속 사용자 정보를 넘겨준다. 이는 매우 비효율적일뿐더러, 보안이 취약하다. (개발자가 모든 요청 로직에 사용자 정보를 URL에 담도록 개발을 해야 한다.) 아이디어2 쿠키 활용 한 번 로그인하면 서버에서 쿠키를 만들어서 클라이언트에게 내려준다. 쿠키 특성상 매 요청 시 HTTP 헤더에 포함돼서 보내지기 때문에, 서버 측에선 쿠키의 여부에 따라 사용자를 식별할 수 있을 것이다. 일단 아이디어1의 비효율적인 문제를 해결할 것..
# 모델, 뷰, 컨트롤러의 역할 모델 데이터를 담는 일종의 박스 뷰 사용자에게 보여질 페이지를 렌더링 컨트롤러 사용자의 요청(URL)을 받아서 처리할 로직을 확인한 뒤, View를 반환(or HTTP 응답)하는 역할 (실질적인 비즈니스 로직은 서비스에서 처리) # 웹 요청 처리의 전반적인 흐름도 클라이언트가 요청 DispatcherServlet이 해당 URL요청을 제일 먼저 받음 (문지기 역할) HandlerMapping : 해당 URL를 처리할 수 있는 컨트롤러를 탐색 컨트롤러 호출 : URL 처리 및 ModelAndView를 받아옴 컨트롤러 실행 결과를 뷰 리졸버에게 전달 뷰 렌더링 (응답 출력) 컨트롤러 내부에서 모델에 데이터를 설정하고 뷰로 보내면, 뷰에서 해당 데이터를 사용할 수 있다 @GetM..
서블릿과 톰캣 우선 서블릿을 이해하기 위해 클라이언트가 서버로 HTTP 요청을 보내서 서버가 처리하는 기본적인 프로세스를 상상해보자 (클라이언트에서 Form으로 서버에게 "회원가입" HTTP 요청을 보냈다고 가정한다) 그러면 서버 측에서는 다음과 같은 일련의 과정을 실행한다 0. TCP/IP 대기, 소켓 연결 1. HTTP 요청 메시지 헤더 부분 파싱 2. 어떤 방식인지 파악 (POST, GET 등등) 3. Content-type 파악 4. HTTP 바디 부분 파싱 5. 비즈니스 로직(회원가입) 실행 (이름, 나이를 받아와서 DB에 저장) 6. HTTP 응답 메시지 작성 시작 (라인 생성, 헤더 작성, 바디에 HTML 생성) 7. TCP/IP 응답 전달, 소켓 종료 이렇게 클라이언트의 요청을 수행하고 응..