
상품 등록 폼 상품 등록 폼 BasicItemController에 추가 @GetMapping("/add") public String addForm() { return "basic/addForm"; } 상품 등록 폼 뷰 정적 HTML을 뷰 템플릿(templates) 영역으로 복사하고 다음과 같이 수정. /resources/static/addForm.html => /resources/templates/basic/addForm.html 상품 등록 폼 상품 입력 상품명 가격 수량 상품 등록 취소 이 부분 보면 th:action = "/basic/items/addForm" method = "post 이렇게 쓴다 보통 속성 변경 - th:action 취소

상품 상세 컨트롤러와 뷰 BasicItemController - 상세 조회 메서드 추가(GET) @GetMapping("/{itemId}") public String item(@PathVariable long itemId, Model model) { // 경로 변수로부터 받은 itemId를 사용하여 상품을 조회합니다. Item item = itemRepository.findById(itemId); // 조회한 상품을 모델에 추가합니다. 이후 뷰 템플릿에서 사용할 수 있습니다. model.addAttribute("item", item); // "basic/item" 뷰 템플릿을 호출하여 상품 상세 정보를 화면에 표시합니다. return "basic/item"; } 그래서 현재까지 최종 코드는 @Contro..

본격적으로 컨트롤러와 뷰 템플릿 개발 시작 BasicItemController @Controller @RequestMapping("/basic/items") @RequiredArgsConstructor public class BasicItemController { private final ItemRepository itemRepository; @GetMapping public String items(Model model) { // 상품 목록을 조회 List items = itemRepository.findAll(); // 조회한 상품 목록을 모델에 추가 model.addAttribute("items", items); // "basic/items" 뷰 템플릿을 호출하여 상품 목록을 화면에 표시 return..

부트스트랩 HTML, css 파일 참고로 /resources/static 에 넣어두었기 때문에 스프링 부트가 정적 리소스를 제공한다. http://localhost:8080/html/items.html 그런데 정적 리소스여서 해당 파일을 탐색기를 통해 직접 열어도 동작하는 것을 확인할 수 있다. 상품 목록 HTML resources/static/html/items.html 상품 상세 상품 ID 상품명 가격 수량 상품 수정 목록으로 상품 상세 HTML resources/static/html/item.html 상품 상세 상품 ID 상품명 가격 수량 상품 수정 목록으로 상품 등록 폼 resources/static/html/addForm.html 상품 등록 폼 상품 입력 상품명 가격 수량 상품 등록 취소 상품 ..

프로젝트 기본 세팅 build.gradle plugins { id 'java' id 'org.springframework.boot' version '2.7.15' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'hello' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-bo..

요청 매핑 핸들러 구조 - HTTP 메시지 컨버터는 스프링 MVC 어디쯤에서 사용되는 것일까? 이 구조에서는 없다. SpringMVC 구조 모든 비밀은 애노테이션 기반의 컨트롤러, 그러니까 @RequestMapping 을 처리하는 핸들러 어댑터인 RequestMappingHandlerAdapter (요청 매핑 헨들러 어뎁터)에 있다. RequestMappingHandlerAdapter 동작 방식 ArgumentResolver 생각해보면, 애노테이션 기반의 컨트롤러는 매우 다양한 파라미터를 사용할 수 있었다. HttpServletRequest, Model 은 물론이고, @RequestParam, @ModelAttribute 같은 애노테이션 그리고 @RequestBody, HttpEntity 같은 HTTP ..

HTTP 메시지 컨버터 HTTP 메시지 컨버터뷰 템플릿으로 HTML을 생성해서 응답하는 것이 아니라, HTTP API처럼 JSON 데이터를 HTTP 메시지 바디에서 직접 읽거나 쓰는 경우 HTTP 메시지 컨버터를 사용하면 편리하다. @ResponseBody 사용 원리 [그림] 다시 돌아가서 HTTP 메시지 컨버터 인터페이스 /** * HTTP 요청 및 응답 메시지를 변환하는 데 사용되는 인터페이스입니다. * 이 인터페이스를 구현하는 클래스는 HTTP 요청 메시지를 Java 객체로 변환하거나, * Java 객체를 HTTP 응답 메시지로 변환하는 작업을 수행할 수 있습니다. * * @param 변환할 객체의 타입을 나타내는 제네릭 타입 매개변수 */ public interface HttpMessageConv..
JWT는 Header, Payload, Signature 이렇게 3개 부분으로 구성되어 있다. Header는 Signature을 해싱하기 위한 알고리즘 정보들이 담겨있고, Payload는 서버와 클라이언트가 주고받는, 시스템에서 실제로 사용될 정보에 대한 내용들을 담고 있다. Signature은 토큰의 유효성 검증을 위한 문자열이다. - 이 문자열을 통해 서버에서는 이 토큰이 유효한 토큰인지를 검증할 수 있다. JWT 장점 - 중앙의 인증서버, 데이터 스토어에 대한 의존성 없음, 시스템 수평 확장 유리 - Base64 URL Safe Encoding => URL, Cookie, Header 모두 사용 가능(범용성) JWT 단점 - Payload의 정보가 많아지면 네트워크 사용량 증가, 데이터 설계 고려가..