묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
[질문글아님!] addForm. editForm, item html 파일 참고하세요!
제가 공부하면서 주석으로 정리한 것 있는데하찮은 실력이지만 다른 공부하시는 분들께 도움이 될 수 있을까 해서 공부한 내용을 올려봅니다!범위는 "체크박스-멀티"까지 내용입니다! addForm.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link th:href="@{/css/bootstrap.min.css}" href="../css/bootstrap.min.css" rel="stylesheet"> <style> .container { max-width: 560px; } </style> </head> <body> <div class="container"> <div class="py-5 text-center"> <h2>상품 등록 폼</h2> </div> <form action="item.html" th:action method="post" th:object="${item}"> <!-- ${item} : addForm() 에서 model 에 담겨서 넘어온 새로운 객체 (아래 코드 주석) model.addAttribute("item", new Item()); --> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요"> <!-- <input type="text" id="itemName" name="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요"> --> </div> <div> <label for="price">가격</label> <input type="text" id="price" th:field="*{price}" class="form-control" placeholder="가격을 입력하세요"> <!-- <input type="text" id="price" name="price" class="form-control" placeholder="가격을 입력하세요"> --> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" th:field="*{quantity}" class="form-control" placeholder="수량을 입력하세요"> <!-- <input type="text" id="quantity" name="quantity" class="form-control" placeholder="수량을 입력하세요"> --> </div> <hr class="my-4"> <!-- single checkbox --> <div>판매 여부</div> <div> <div class="form-check"> <!-- 히든필드 추가 <input type="checkbox" id="open" name="open" class="form-check-input" /> <input type="hidden" id="_open" name="_open" value="on" /> --> <!-- HTML checkbox 는 체크하지 않으면 서버로 값 자체를 보내지 않는다. (히든필드 사용하지 않을 경우) HTML 메시지: itemName=11&price=11&quantity=11 spring: item.open = null 즉. HTML checkbox 는 사용하기 불편할 수 있다. 그래서 spring 은 히든필드를 운용한다. HTML checkbox 는 체크되지 않으면 서버로 히든필드만 전송한다. 그럼 spring 은 필드가 false 라고 판단한다. HTML 메시지: itemName=22&price=22&quantity=22&_open=on spring: item.open = false HTML checkbox 가 체크되면 필드와 히든필드를 서버로 전송된다. HTML 메시지: itemName=33&price=33&quantity=33&open=on&_open=on. 그럼 spring 은 필드가 true 라고 판단한다. spring: item.open = true --> <input type="checkbox" id="open" th:field="*{open}" class="form-check-input" /> <!-- th 를 사용하면 알아서 히든필드를 만들어내기 때문에 HTML checkbox 를 편하게 사용할 수 있다. --> <label for="open" class="form-check-label">판매 오픈</label> </div> </div> <!-- multi checkbox --> <div> <div>등록 지역</div> <div th:each="region : ${regions}" class="form-check form-check-inline"> <!-- @ModelAttribute 에 담겨서 넘어온 것(regions()) 반복문 돌리기 ${regions} : Map<String, String>. 사용자가 선택해서 넘어온 것이 아니라 FormItemController 에서 @ModelAttribute 자체가 그대로 넘어왔기 때문. --> <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input"> <!-- th 가 name, value, id 을 만들어줌. 이 때, id는 field 에 숫자가 붙여져 고유하게 만들어진다. *{regions} : ${item.regions}의 생략 버전. Map<String, String>. 사용자가 선택해서 넘어온 것이 아니라 FormItemController 에서 @ModelAttribute 자체가 그대로 넘어왔기 때문. ${region.key} : 위 div 태그의 Map의 key 중 하나. "SEOUL", "BUSAN", "JEJU" 중 하나 (반복문이니깐). 사용자가 각 체크박스를 체크해서 POST 요청 보낼 때 regions.key가 날아감. 이후 item.regions 에 값이 바인딩될 것. --> <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label> <!-- ${#ids.prev('필드명')} : 바로 이전 태그에서 사용되었던 id를 그대로 가져와서 사용. 물론 위 태그에서 th가 id 자동생성해줬다. ${region.value} : 위 div 태그의 Map의 value 중 하나. "서울", "부산", "제주" 중 하나 (반복문이니깐) --> </div> </div> <div> <div>상품 종류</div> <div th:each="type : ${itemTypes}" class="form-check form-check-inline"> <!-- @ModelAttribute 에 담겨서 넘어온 것(itemTypes()) 반복문 돌리기 ${regions} : ItemTypes[]. 사용자가 선택해서 넘어온 것이 아니라 FormItemController 에서 @ModelAttribute 자체가 그대로 넘어왔기 때문. --> <input type="radio" th:field="*{itemType}" th:value="${type.name()}" class="form-check-input"> <!-- *{itemType} : --> <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label"> BOOK </label> <!-- --> </div> </div> <div class="row"> <div class="col"> <button class="w-100 btn btn-primary btn-lg" type="submit">상품 등록</button> </div> <div class="col"> <button class="w-100 btn btn-secondary btn-lg" onclick="location.href='items.html'" th:onclick="|location.href='@{/form/items}'|" type="button">취소</button> </div> </div> </form> </div> <!-- /container --> </body> </html> editForm.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link th:href="@{/css/bootstrap.min.css}" href="../css/bootstrap.min.css" rel="stylesheet"> <style> .container { max-width: 560px; } </style> </head> <body> <div class="container"> <div class="py-5 text-center"> <h2>상품 수정 폼</h2> </div> <form action="item.html" th:action method="post" th:object="${item}"> <!-- ${item} : editForm() 에서 model 에 담겨서 넘어온 특정 객체 (아래 코드 주석) Item item = itemRepository.findById(itemId); model.addAttribute("item", item); --> <div> <label for="id">상품 ID</label> <input type="text" id="id" class="form-control" th:field="*{id}" readonly> <!-- th 가 name, value, id 를 만들어준다. <input type="text" id="id" name="id" class="form-control" value="1" th:value="${item.id}" readonly> --> </div> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" class="form-control" th:field="*{itemName}"> <!-- th 가 name, value, id 를 만들어준다. <input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}"> --> </div> <div> <label for="price">가격</label> <input type="text" id="price" class="form-control" th:field="*{price}"> <!-- th 가 name, value, id 를 만들어준다. <input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}"> --> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" class="form-control" th:field="*{quantity}"> <!-- th 가 name, value, id 를 만들어준다. <input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}"> --> </div> <hr class="my-4"> <!-- single checkbox --> <div>판매 여부</div> <div> <div class="form-check"> <input type="checkbox" id="open" th:field="*{open}" class="form-check-input"> <label for="open" class="form-check-label">판매 오픈</label> </div> </div> <!-- multi checkbox --> <div> <div>등록 지역</div> <div th:each="region : ${regions}" class="form-check form-check-inline"> <!-- @ModelAttribute 에 담겨서 넘어온 것(regions()) 반복문 돌리기 ${regions} : Map<String, String>. 사용자가 선택해서 넘어온 것이 아니라 FormItemController 에서 @ModelAttribute 자체가 그대로 넘어왔기 때문. --> <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input"> <!-- th 가 name, value, id 을 만들어줌. 이 때, id는 field 에 숫자가 붙여져 고유하게 만들어진다. *{regions} : ${item.regions}의 생략 버전. 빈 리스트. 사용자가 각 체크박스를 체크해서 POST 요청 보낼 때 regions.key가 날아감. item.regions 에 값이 바인딩될 것. ${region.key} : 위 div 태그의 Map의 key 중 하나. "SEOUL", "BUSAN", "JEJU" 중 하나 (반복문이니깐). 사용자가 각 체크박스를 체크해서 POST 요청 보낼 때 regions.key가 날아감. 이후 item.regions 에 값이 바인딩될 것. --> <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label> <!-- ${#ids.prev('필드명')} : 바로 이전 태그에서 사용되었던 id를 그대로 가져와서 사용. 물론 위 태그에서 th가 id 자동생성해줬다. ${region.value} : 위 div 태그의 Map의 value 하나. "서울", "부산", "제주" 중 하나 (반복문이니깐) --> </div> </div> <div class="row"> <div class="col"> <button class="w-100 btn btn-primary btn-lg" type="submit">저장</button> </div> <div class="col"> <button class="w-100 btn btn-secondary btn-lg" onclick="location.href='item.html'" th:onclick="|location.href='@{/form/items/{itemId}(itemId=${item.id})}'|" type="button">취소</button> </div> </div> </form> </div> <!-- /container --> </body> </html> item.html<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link th:href="@{/css/bootstrap.min.css}" href="../css/bootstrap.min.css" rel="stylesheet"> <style> .container { max-width: 560px; } </style> </head> <body> <div class="container"> <div class="py-5 text-center"> <h2>상품 상세</h2> </div> <!-- 추가 --> <h2 th:if="${param.status}" th:text="'저장 완료'"></h2> <div> <label for="itemId">상품 ID</label> <input type="text" id="itemId" name="itemId" class="form-control" value="1" th:value="${item.id}" readonly> </div> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" name="itemName" class="form-control" value="상품A" th:value="${item.itemName}" readonly> </div> <div> <label for="price">가격</label> <input type="text" id="price" name="price" class="form-control" value="10000" th:value="${item.price}" readonly> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" name="quantity" class="form-control" value="10" th:value="${item.quantity}" readonly> </div> <hr class="my-4"> <!-- single checkbox --> <div>판매 여부</div> <div> <div class="form-check"> <input type="checkbox" id="open" th:field="${item.open}" class="form-check-input" disabled> <!-- th 가 name, value, id 을 만들어줌 체크박스가 체크되어 있다면 checked="checked" 속성까지 만들어줌. 체크되지 않았다면 속성 만들어지지 않음. --> <label for="open" class="form-check-label">판매 오픈</label> </div> </div> <!-- multi checkbox --> <div> <div>등록 지역</div> <div th:each="region : ${regions}" class="form-check form-check-inline"> <!-- @ModelAttribute 에 담았던 것 반복문 돌리기 --> <!-- @ModelAttribute 에 담겨서 넘어온 것(regions()) 반복문 돌리기 ${regions} : Map<String, String>. 사용자가 선택해서 넘어온 것이 아니라 FormItemController 에서 @ModelAttribute 자체가 그대로 넘어왔기 때문. --> <input type="checkbox" th:field="${item.regions}" th:value="${region.key}" class="form-check-input" disabled> <!-- th 가 name, value, id 을 만들어줌. 이 때, id는 field 에 숫자가 붙여져 고유하게 만들어진다. ${item.regions} : List. 사용자가 선택했던 요소들이 담긴 리스트이므로 ["SEOUL", "BUSAN"] 등의 리스트. ${region.key} : 위 div 태그의 Map의 key 하나. "SEOUL", "BUSAN", "JEJU" 중 하나 (반복문이니깐) value("SEOUL", "BUSAN", "JEJU" 중 하나)가 field(Map<String, String>) 의 요소에 존재한다면 th가 checked="checked" 속성을 만들어줌. --> <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label> <!-- ${#ids.prev('필드명')} : 바로 이전 input 태그에서 사용되었던 id를 그대로 가져와서 사용. 물론 위 태그에서 th가 id 자동생성해줬다. ${region.value} : 위 div 태그의 Map의 value 하나. "서울", "부산", "제주" 중 하나 (반복문이니깐) --> </div> </div> <div class="row"> <div class="col"> <button class="w-100 btn btn-primary btn-lg" onclick="location.href='editForm.html'" th:onclick="|location.href='@{/form/items/{itemId}/edit(itemId=${item.id})}'|" type="button">상품 수정</button> </div> <div class="col"> <button class="w-100 btn btn-secondary btn-lg" onclick="location.href='items.html'" th:onclick="|location.href='@{/form/items}'|" type="button">목록으로</button> </div> </div> </div> <!-- /container --> </body> </html>
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증1-validation 강의 관련 질문
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]검증1 - validation 강의에서 validator 분리2 섹션에서 설명하실때 파라미터 바인딩한다고 하셨는데 파라미터 바인딩이란게 정확히 뭔가요??넘어오는 파라미터를 매개변수로 매핑하는 건가요??
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
hello-mvc 오류
# hello-template.html <!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <body> <p th:text="'hello '+ ${name}">hello. empty</p> </body> </html>package sebdev.prac1.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class HelloController { @GetMapping("hello") public String hello(Model model){ model.addAttribute("data","spring"); return "hello"; } @GetMapping("hello-mvc") public String helloMvc(@RequestParam("name") String name, Model model){ model.addAttribute("name", name); return "hello-template"; } } 리턴값 hello-template에 맞춰 hello-template.html으로 맞춰주었는데이런식으로 오류가 납니다.
-
미해결스프링 핵심 원리 - 기본편
서버 구동 시 롬복
단순한 호기심인데요,롬복 사용시에 gradle 라이브러리 뿐만 아니라 tool에 plugin 설치 등 다양한 작업들이 필요 해 보이는데lombok을 사용해서 구현한 프로젝트를 빌드해서 IDE 환경 없이 jar 파일로 실행하는 경우에도 에러 없이 동작하는 건가요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
자바 강의
안녕하세요 이 강의를 본격적으로 듣기 전에 자바강의를 충분히 이해하고 싶습니다 그래서 이것이 자바다 와 자바의 정석중에 고민이 됩니다 자바의 정석은 서점에 가도 밀봉되어있어 책 내용을 알수가없어서 고민이됩니다. 각자의 장단점이 뚜렷하겠지만 혹시 선생님이 추천해주실만한 자바 강의가 있을까요? 그리고 자바를 공부하는데 어느 부분이 제일 필요한지도 궁금합니다
-
미해결스프링 부트 웹 개발 입문 - 따라하며 배우기
수업내용과 어느정도 일치하지만 좀 다른게 궁금해서 문의드립니다
컨트롤러에서int i = menuSvc.doUpdate(coffeeMenu);앞에 int i 변수선언을 하는 이유가 있을까요??강의 내용중 Mybatis 가 숫자를 반환해준다고 하신거같은데 살짝 이해가 안가서요 혹시 제가 국비 다니고있습니다.프로젝트 진행중인데 프론트 쪽이 리엑트 쓰는데JSON형식으로 넘겨줘야한다고 하더라고요RestComtroller 또는 Controller 클래스 레벨에 선언후메소드에서 Responsbody 선언하고 똑같이 리턴은String 으로 해서 View 페이지에 보내면될까요? 제가 다니는 학원에서는 리엑트를 안배우고 vue2 를 배워서 이부분이 너무 무지해서 좀 막막합니다
-
해결됨스프링 핵심 원리 - 기본편
@Configuration을 해도 싱글톤이 지켜지지가 않습니다.
섹션 5의 '@Configuration과 싱글톤' 강의에서AppConfig class에 @Configuration으로 어노테이션을 하면 'ConfigurationSingletonTest'에서 memoryMemberRepository의 constructor가 세번 호출 되는 것처럼 보이지만, 실제로는 한번 호출이 되어야하고, OrderServiceImpl, MemberServiceImpl, MemoryMemberRepository 빈에서의 memoryMemberRepository가 모두 같은 인스턴스여야한다고 하셨는데,저는 constructor도 3번이 호출되고, 모두 다른 객체입니다ㅠ또한 AppConfig bean = ac.getBean(AppConfig.class);System.out.println("bean = " + bean.getClass());하면 "bean = class hello.AppConfig$$EnhancerBySpringCGLIB$$~~~"가 아닌"bean = class hello.core.AppConfig$$SpringCGLIB$$0"가 출력됩니다.강사님 코드와 동일하게 작성했는데 제가 잘못 작성한 부분이 있는 걸까요?답변 기다리겠습니다. 감사합니다. :)Test 결과 사진: AppConfig.java 코드package hello.core; import hello.core.discount.DiscountPolicy; import hello.core.discount.RateDiscountPolicy; import hello.core.member.MemberRepository; import hello.core.member.MemberService; import hello.core.member.MemberServiceImpl; import hello.core.member.MemoryMemberRepository; import hello.core.order.OrderService; import hello.core.order.OrderServiceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public MemberService memberService() { System.out.println("call AppConfig.memberService"); return new MemberServiceImpl(memberRepository()); } @Bean public OrderService orderService() { System.out.println("call AppConfig.orderService"); return new OrderServiceImpl(memberRepository(), discountPolicy()); } @Bean public static MemberRepository memberRepository() { System.out.println("call AppConfig.memberRepository"); return new MemoryMemberRepository(); } @Bean public DiscountPolicy discountPolicy() { return new RateDiscountPolicy(); } } ConfigurationSingletonTest.java 코드:package hello.core.singleton; import hello.core.AppConfig; import hello.core.member.MemberRepository; import hello.core.member.MemberServiceImpl; import hello.core.member.MemoryMemberRepository; import hello.core.order.OrderServiceImpl; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class ConfigurationSingletonTest { @Test void configurationTest() { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class); OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class); MemberRepository memberRepository3 = ac.getBean("memberRepository", MemberRepository.class); System.out.println("memberService -> memberRepository = " + memberService.getMemberRepository()); System.out.println("orderService -> memberRepository2 = " + orderService.getMemberRepository()); System.out.println("memberRepository = " + memberRepository3); } @Test void configurationDeep() { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); AppConfig bean = ac.getBean(AppConfig.class); System.out.println("bean = " + bean.getClass()); } }
-
미해결스프링 핵심 원리 - 기본편
Autowired 의존관계 자동 주입
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]AppConfig를 사용할 때는 의존성 주입을 AppConfig가 해줬는데 Component와 Autowired로 bean들을 한번에 컨테이너에 넣을 수 있다는 것은 이해가 갔습니다. 하지만 OrderService와 OrderServiceImpl과 MemberService와 MemberServiceImpl은 어디서 주입되나요? Autowired 의존관계 자동 주입에 이 부분은 나와있지 않아서 질문합니다!
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Model 추가-v3 수강 중 jstl 오류 & 500 오류
안녕하세요, 수강 중에 오류가 발생하여 글 남깁니다.회원가입은 정상적으로 이루어지는데 회원 조회를 클릭하면Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as a fallback.Tue Aug 08 14:37:44 KST 2023There was an unexpected error (type=Internal Server Error, status=500).라는 화면이 뜨고 콘솔창에는 아래와 같은 두가지 에러가 발생한다고 뜹니다! 2023-08-08T14:37:44.788+09:00 ERROR 23036 --- [nio-8080-exec-2] o.a.c.c.C.[.[localhost].[/].[jsp] : Servlet.service() for servlet [jsp] threw exception 2023-08-08T14:37:44.803+09:00 ERROR 23036 --- [nio-8080-exec-2] a.c.c.C.[.[.[.[frontControllerServletV3] : Servlet.service() for servlet [frontControllerServletV3] in context with path [] threw exception [The absolute uri: [http://java.sun.com/jsp/jstl/core] cannot be resolved in either web.xml or the jar files deployed with this application] with root cause 해결방법 알려주시면 감사하겠습니다.
-
미해결스프링 핵심 원리 - 기본편
강사님처럼 실행시 log출력은 어떻게 하나요 ?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.3:39 쯤에 보면 Overriding bean definition 을 출력하는데 저는 저것 외에도 아무런 로그도 출력하지 않고 그냥 test pass 되네요 logback을 따로등록해야되나요 ?아니면 스프링 2.x 3.x 차이인지
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
model.addAttribute 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. model.addAttribute 하고 안에 값 넣었는데 이게 안먹네요 어떻게해야 해결할 수 있을까요?import 구문 따로 넣는게 있나요?
-
미해결실전! 스프링 데이터 JPA
연관관계없이 테이블 설계 및 JPA Domain Class 작성 문의
안녕하세요. 현재 김영한님의 JPA관련 강의들을 수강하면서 기존 프로젝트에서 JPA 로 변경시 문제가 있어 문의드립니다.배운 것을 실적용할 경우 문제는, 테이블 설계시 제약사항이 테이블 간 연관관계 설정을 하지 않는 것입니다.이 경우 도메인클래스를 어떻게 작성해야 할지 적절한 기준과 방법을 몰라 문의드립니다.간략히 예를들어 DBA권고에 따라 외래키 설정은 모두 하지 않는다고 가정해서 아래와 같이 테이블을 생성했을 시에| COMMENT | | COMMENT_IMAGE | | comment_id(PK)| | comment_img_id(PK)| | user_name(PK) | ------- X ------ | comment_img_name | | comment_id | /* DO NOT USE CONSTRAINT foreign key() references */따라서 기존에 아래와 같은 DTO가 있다면,public class Comment { .... private Long id; private String name; private List<CommentImage> commentImages; .... }로 작성되어 있을 경우 아래와 같이 수정중인데... @IdClass(CommentId.class) public class Comment { .... @Id private Long id; @Id private String name; //@? private List<CommentImage> commentImages; .... }기존에는 따로 CommentImage List<>를 조회해서 넣어주면 됐지만cmt = DAO.getComment(id, name); cmt.setCommentImages( DAO.getCommentImageList( cmt.getId() ) ); return cmt; /* getComment SQL SELECT * FROM COMMENT WHERE COMMENT_ID = :id AND USER_NAME = :name; getCommentImageList SQL SELECT * FROM COMMENT_IMAGE WHERE COMMENT_ID = :comment_id; */ JPA의 경우 Domain 클래스에서 Join관련 어노테이션 설정이 없으면 Could not determine recommended JdbcType 오류가 발생합니다. 이 경우 연관관계 생성없이 도메인을 설계하고 사용하는 방법을 알 수 있을까요?
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
DTO를 Result<T> 클래스에 담아서 반환할 때의 예외처리
안녕하세요!영한님 강의를 들으면서 추가적으로 RestTemplate에 대해 알게되어 지금까지 배운 것을 복습할 겸 api와 DTO 통신에 대해 연습하고 있었습니다.DTO를 반환할 때, 그냥 주기보다는 Result<T>의 data같은 속성에 담아서 주는 것이 바람직하다고 하여 그 응용을 연습해 볼겸 Result<T>에 status 속성을 추가해보았습니다.status 속성은 외부 api에서 조건을 충족하는 api를 찾아 와서 반환할 DTO가 있을 경우 "success"를, 조건을 충족하는 api를 찾지 못하여 HttpClientErrorException 예외가 발생할 경우 "fail"을 담아서 반환하고자 하였습니다.아래의 코드를 통해 구현은 성공하였으나, Service 클래스에서 try-catch문을 사용하는게 좀 찜찜하여 혹시 try-catch문 없이 구현하는게 더 좋을지 아니면 그냥 사용해도 좋은지가 궁금하여 질문을 하게 되었습니다.(status가 "fail"이면 data는 null을 반환하게끔 설계해보았습니다) @RestController @RequiredArgsConstructor @RequestMapping("/summoners") public class SummonerController { private final SummonerService summonerService; @GetMapping public ResponseEntity<Result<SummonerDTO>> findSummonerApi(@RequestParam String name) { SummonerDTO summonerDTO = summonerService.findSummonerApi(name); if (summonerDTO == null) { return ResponseEntity.ok().body(new Result<>("fail", null)); } return ResponseEntity.ok().body(new Result<>("success", summonerDTO)); } }@Slf4j @Service @RequiredArgsConstructor public class SummonerService { @Value("${apiKey}") private String apiKey; private final SummonerRepository summonerRepository; private final RestTemplate restTemplate; // riot에서 소환사 정보 api를 받아오는 메서드 public SummonerDTO findSummonerApi(String name) { String url = "https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/{summonerName}"; HttpHeaders headers = new HttpHeaders(); headers.set("X-Riot-Token", apiKey); try { return restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), SummonerDTO.class, name).getBody(); } catch (HttpClientErrorException e) { return null; } } }Controller와 Service의 코드는 위와 같습니다. (restTemplate은 별도의 설정파일에 빈으로 구현하였습니다)
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
테스트 실패 후 tryLock waitTime 설정 변경 뒤 테스트 성공에 대한 질문
waitTime을 10초로 설정했어도 leaseTime이 1이기 때문에 테스트는 성공했어야 할 것 같은데 왜 실패하나요?그리고 waitTime을 10초에서 15초로 변경하면 왜 성공하나요?
-
미해결실전! 스프링 데이터 JPA
안녕하세요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 성능 테스트를 해보고 QueryHint 를 적용할지 고민하라고 하셨는데 성능 테스트란 정확하게 어떤 걸 의미하나요? 부하 테스트 인지 맞다면 예시가 뭐인지 궁금합니다.그리고 성능 테스트를 하면 QueryHint 를 쓰는게 더 성능이 좋게 나올텐데 그럼 쓰는 게 낫지 않나 하는 궁금증이 듭니다.
-
미해결스프링 핵심 원리 - 기본편
인텔리제이 깃 다운시 질문드립니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요. 강의 내용을 git으로 private로 커밋하여 다른 강의를 옮겨듣던 기존의 노트북에 내려받았습니다.내려받은 경우 화면과 같이 애너테이션이 작동하는건지 안하는건지.. 그냥 디스플레이 설정이 다른건지는 잘 모르겠는데 좌측에 .bean 초록색이나 실행버튼이 노출되지 않는 현상은 어떠한 현상일까요..?
-
미해결스프링 핵심 원리 - 기본편
도대체 뭐가 문제인지 모르겠녜요..
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 2시간동안 계속 찾아봤는데 뭐가 문지인지 모르겠습니다... nullpoint가 계속 뜨네요ㅕ
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
40강 git bash 에서 git 사용에 관한 질문입니다.
안녕하세요 강사님,강의 정말 잘 듣고 있습니다!40강 관련 질문입니다.git init 명령어를 터미널에서 사용하니 C:/Users/library-app/.git: Permission denied이런 오류가 발생해서 git bash에서 git init을 사용해 보았더니 되더군요.그런데 git add . 입력하면 위와 같은 Permission denied가 또 발생합니다..git status를 입력 하면 아래와 같이 나왔습니다구글링 해 보니 ssh key를 등록하라고 해서 따라서 해 보고 github repository도 삭제했다가 다시 만들어서 실행 해 보았는데도 이렇습니다.무슨 이유에서 인지 .gitignore 파일도 만들어지지 않습니다.제가 구글링으로 해결하려고 이것저것 따라 하다가 더 꼬인 것 같긴 한데....도저히 어디서 부터 잘못된 것인지 모르겠어서 질문드립니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
컨트롤러가 정적 리소스를 호출하는 방법
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]static/basic/hello-form.html 경로에 있는 정적 리소스를 직접 "http://localhost:8080/basic/hello-form.html"로 요청하는 것 말고 컨트롤러가 정적 리소스를 반환해줄 수 있나요? 컨트롤러가 정적 리소스를 반환하는 것이 논리적으로 부적절한 행동인가요? 만약 그렇다면 클라이언트가 직접 해당 리소스의 위치(URI)로 ex) http://localhost:8080/basic/hello-form.html 요청을 하는 것이 좋은 방법인가요? 위 코드와 같이 redirect를 시키는 방법 외에 추가적으로 컨트롤러가 정적 리소스를 반환해주는 방법이 궁금합니다
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
다국언어를 지원하는 웹사이트에서 LocaleResolver의 사용
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 선생님강의 복습 도중 질문이 생겨서 글 작성하게 되었습니다.웹사이트들을 보다보면 다국적 기업들의 웹사이트의 경우 사용자가 선택하면 다른 언어의 웹사이트가 표시되도록 국가 리스트를 선택할 수 있게 해둔 경우가 많은데요이때 보면 url의 뒤에 /ko, /en, /us, /cn 등URL Pattern을 붙여서 구분하는 경우가 많은데 이 부분은 스프링 국제화와는 다소 거리가 먼 것 같습니다/ko /en은 urlPattern의 차이를 두는 방식이고 스프링 메세지 국제화는 브라우저의 request accept-header를 기준으로 하는 것으로 이해했는데요혹시 저렇게 /ko /en /us /cn등을 사용하지 않고 국제화를 사용하기 위해서 국가 리스트에서 특정 국가를 선택하면 요청헤더의 accept-lang을 바꾸는 개발방법도 많이 이용되기는 하는지 궁금합니다.