묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 프레임워크는 내 손에 [스프1탄]
47강 강의 내용관련 질문이 있습니다.
47강 회원정보 수정부분에서 session을 왜 추가적으로 넣어주어야 하는지 궁금합니다. 로그아웃 하기 전에 세션은 사라지지 않는 것 아닌가요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
DB가 제공하는 클라이언트의 의미가 이것이 맞나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]build.gradle의 dependencies에 추가한runtimeOnly 'com.h2database:h2'이것이 DB가 제공하는 클라이언트라고 하셨는데 인텔리제이로 실행한 후 웹 브라우저로 localhost:8080에서 회원 등록을 하고, 회원 조회를 할 수 있잖아요? 제가 회원 등록 및 조회를 할 때의 웹 브라우저에 붙어 있는 게 클라이언트이고, h2.bat을 통해 실행시킨 프로그램이 서버라고 보면 되나요? 비슷하게 이해한 건지 궁금합니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
회원등록관련 질문있습니다.
회원등록과 회원목록조회의 경우, 서버기동 중에만 메모리에 등록되고 서버를 죽이면 데이터(?)가 사라지는 걸로 알고있습니다. 근데, 서버재기동 후 이전에 했던 회원정보로 회원가입하면 아래와같이이미 존재하는 회원이라는 에러처리가 발생합니다. 서버 재기동시 store객체는 초기화 되는거 아닌가요?에러처리가 발생하는게 정상인지? 정상이면 왜 그런지 알고싶습니다.
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
@Transaction 적용 시 수동 빈 등록 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]@Transaction을 사용 시, 스프링 AOP가 적용되어야 하기 때문에 테스트 코드에서는 @SpringBootTest와 함께 트랜잭션 적용에 필요한 다양한 객체를 수동으로 등록하고 적용하는 법을 배웠습니다. (PlatforTransactionManager, DataSource 등) 그러면 테스트 환경이 아닌 서비스 로직에서 @Transaction을 사용할 경우에는 강의에서 진행한 수동 빈 등록 절차를 거치지 않아도 되는 건가요? @Transcation을 썼을 때 트랜잭션에 필요한 빈들을 자동으로 등록한다는 내용이 이 뜻인건지 궁금합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
2강에서 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. JDK11 쓰고, start.spring에서 JAVA 11을 선택했는데도 17이 뜹니다.. 그리고Run을 시키면 "No matching variant of org.springframework.boot:spring-boot-gradle-plugin:3.0.10 was found.The consumer was configured to find a library for use during"이란 에러가 뜹니다! 어떻게 해결해야 할까요 ?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
No suitable driver found for 08001/0
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의대로 create table member도 실행했고select로 조회도 가능합니다.그런데 왼쪽에 No suitable driver found for 08001/0라는 메시지가 있는데 혹시 이 메시지 때문에 문제될 게 생길까요? 강의 그대로 했는데 왜 저는 이런 게 뜰까요..h2는 D 드라이브의 study 폴더에 설치했고test.mv.db는 C 드라이브에 있던데 혹시 이게 문제일까요? 이 강의에선 DB 조회 같은 거에 문제가 생기진 않았는데다음 시간부터 뭔가 문제가 생길까 봐 질문드립니다. No suitable driver found for를 클릭하면 다음과 같은 메시지가 뜹니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
여러개의 Resource 반환
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요 강의 잘 들었습니다.현재 진행하고 있는 게시판 프로젝트에서, 로컬 컴퓨터(서버)의 C://폴더명(프로젝트 외부 폴더임) 하위에 이미지를 저장하고 있는데, 사진 게시판에 접근할 때, 여러개의 사진(10개씩)을 동시에 response로 줘야 하는 상황에서 어떻게 하는지 잘 모르겠습니다. ResponseEntity에 List<Resource>를 담았더니 잘 안되는 것 같습니다. + +또한, 이미지 뿐만 아니라, 하나의 이미지에 대한 정보(제목, 좋아요 수, 조회 수) 까지 함께 보내야 하는 상황입니다. AWS 같은 서비스를 사용하지 않고, 서버 컴퓨터에 파일을 저장하는 경우, 여러개의 파일을 동시에 클라이언트에 전송할 때, 어떤 방식을 사용하는지 궁금합니다.또한, 여러개의 이미지를 전송할 때, 이미지 하나당 묶여있는 데이터를 어떻게 해야 함께 보낼 수 있는지, 일반적인 방법을 알고 싶습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@ModelAttribute, @SessionAttribute name 속성 차이
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================안녕하세요 강의를 보고 프로젝트에 적용 중 궁금증이 생겨서 해결한 문제가 있어서 옳은 결론을 낸 것인지 궁금하여 질문 드립니다. @ModelAttribute는 name 속성을 작성하지 않을 경우 파라미터의 class 명의 첫글자를 소문자로 바꾼 후 적용한다고 강의에서 들었습니다. ex) @ModelAttribute LoginUser loginUser 일 경우 loginUser로 model에 저장. @SessionAttribute를 사용하다가 무언가 이상해서 여러 테스트를 해보니 이 애노테이션은 name 속성을 사용하지 않았을 경우 클래스 명이 아닌 변수 이름을 사용하는 것으로 확인했습니다. ex) @SessionAttribute User loginUser 일 경우 loginUser로 session에 속성 값 저장. 제가 확인한 방법이 옳은 것인지, 틀리다면 어떤 것이 맞는지, 더 확인해야할 부분이 있는지 궁금합니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
디렉터리에 있는 / 관련해서 질문드립니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]@GetMapping("/members/new") public String createForm() { return "members/createMemberForm"; } 강의에선 이렇게 되어 있는데@GetMapping에선 /members/new이고return에선 members/createMemberForm인데전자는 members 앞에 /가 있고 후자엔 members 앞에 /가 없는데 맨 앞에 /를 붙이나 안 붙이나 상관없다고 보면 되나요?제가 실행할 땐 /를 뺐다가 안 뺐다가 해도 정상 동작하는 것 같긴 해서요.. 아니면 권장하는 표기법이 따로 있나요? 그리고 자바에선 디렉터리 구분은 .로 하잖아요com.example.car 이런 식으로 .으로 구분하는데위에서 .가 아닌 /인 이유는 해당 디렉터리가 HTML 파일들에 대한 디렉터리라서 그런 건가요?그래도 위 코드 자체는 자바 코드라서 .일 줄 알았었어요
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
save()메소드만 실행하는법?
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]여기에 질문 내용을 남겨주세요.저도 강사님처럼 save()메소드만을 실행하고 싶은데 그런 옵션이 안보입니다.강사님은 옵션이 이렇게 뜨는데 저는 달라요 ㅠ어떻게 해야 강사님처럼 save() 메소드만을 실행할 수 있나요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
build.gradle 오류 및 localhost:8080 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]https://drive.google.com/file/d/1YQ9xwVxwzAN7xvYTOm0Jbky6vjB2e0cd/view?usp=share_link 안녕하세요,build.gradle에서 불러오기가 계속 안되는 것 같은데, 혹시 어떤점을 수정해야 할까요? 우선 강의 끝부분인 AOP 까지 모두 설계 완료한 상태입니다. localhost:8080 웹페이지도 계속 생성이 안되어, 전체적으로 어느 부분에서 오류가 생겼는지 몰라 질문 드리게 되었습니다. 상단 링크에 첨부된 프로젝트 참고해주시어 수정사항 말씀해주시면 감사하겠습니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
RedirectAttributes와 @PathVariable차이 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]리턴에서 리다이렉트를 위한 URL을 지정할 때,위에는 RedirectAttributes를 사용하여 itemId를 파라미터로 받았고 아래는 @PathVariable을 사용하여 itemId를 파라미터로 받았습니다.이것의 차이는 무엇인가요?itemId를 받아올 수 있는 기능이 있다라는 것은 공통적이고RedirectAttributes는 RedirectAttributes에 더 특화된 기능을 사용하기 위해 불러오는 것이고 @PathVariable는 단순히 파라미터를 가져오는 기능이다라고 이해하면 될까요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
th:action이 잘 이해가 안됩니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]이 부분에서 th가 붙은 타임리프 문법은 html을 동적으로 움직이게 하는 역할이라고 이해했습니다. 근데 위의 코드에서 th:action은 어떤 동적인 역할을 하게 만드는 것인가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
addForm 페이지에 들어가면 오류가 발생합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]아래 코드는 addForm.html 코드이고<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"> <link href="../css/bootstrap.min.css" th: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> <h4 class="mb-3">상품 입력</h4> <form action="item.html" th:action method="post"> <div> <label for="itemName">상품명</label> <input type="text" id="itemName" name="itemName" class="form- control" placeholder="이름을 입력하세요"> </div> <div> <label for="price">가격</label> <input type="text" id="price" name="price" class="form-control" placeholder="가격을 입력하세요"> </div> <div> <label for="quantity">수량</label> <input type="text" id="quantity" name="quantity" class="form- control" placeholder="수량을 입력하세요"> </div> <hr class="my-4"> <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='@{/basic/items}'|" type="button">취소</button> </div> </div> </form> th:onclick="|location.href='@{/basic/items}'|" type="button">취소</button> </div> <!-- /container --> </body> </html>package hello.itemservice.web.basic; import hello.itemservice.domain.item.Item; import hello.itemservice.domain.item.ItemRepository; import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.util.List; @Controller @RequestMapping("/basic/items") /** * basic/items로 get 방식으로 오면 @GetMapiing 메소드가 실행이 된다. */ @RequiredArgsConstructor /** * @RequiredArgsConstructor을 쓰면 * final이 붙은 멤버에게는 * @Autowired * public BasicItemController(ItemRepository itemRepository) { * this.itemRepository = itemRepository; * }라는 생성자를 자동으로 만들어준다. */ public class BasicItemController { /** * 1.BasicItempContorller가 스프링 빈에 등록이 되면서 * 2.생성자 주입으로 스프링 빈으로 등록되어 있는 ItempRpository가 스프링 빈에서 주입이 된다. * * 1.Spring 컨테이너 초기화: 애플리케이션이 시작될 때 Spring 컨테이너가 초기화되고 구성 파일을 로드합니다. * 이 때 @Autowired 어노테이션을 확인하고 의존성 주입을 준비합니다. * 2.빈 객체 생성: Spring은 컨테이너에서 관리하는 빈(bean) 객체를 생성합니다. * 빈 객체는 @Component, @Service, @Repository, @Controller 등과 같은 어노테이션으로 표시된 클래스들을 기반으로 생성됩니다. * 3.의존성 주입: @Autowired 어노테이션이 적용된 생성자, 필드 또는 메서드를 확인하고 해당 의존성을 주입합니다. * 이때, BasicItemController 클래스에 있는 @Autowired 어노테이션이 적용된 생성자가 호출되면서 ItemRepository의 인스턴스가 주입됩니다. * @Autowired란 스프링 컨테이너에 등록한 빈에게 의존관계주입이 필요할 때, * DI(의존성 주입)을 도와주는 어노테이션이다. 스프링 컨테이너에 빈들을 모두 등록한 후에, 의존성 주입 단계가 이루어진다. * 4.애플리케이션 실행: 모든 초기화 작업이 완료되면 Spring은 애플리케이션을 실행합니다. */ private final ItemRepository itemRepository; @GetMapping public String items(Model model){ List<Item> items = itemRepository.findAll(); model.addAttribute("items",items); return "basic/items"; // Return 되는 뷰 위치. } @GetMapping("/{itemId}") public String item(@PathVariable long itemId,Model model) { Item item = itemRepository.findById(itemId); model.addAttribute("item",item); return "basic/item"; } /** * 실제로 데이터를 넣는 것이 아닌 form만 보여준다. * * form을 열때는 get * 실제 저장을 할 떈 post 사용 * URL을 똑같게 지정한다. 이떄, 같은 URL로 오더라도 Get이나 post에 따라 addForm을 실행하거나 save를 실행한다. */ @GetMapping("/add") public String addForm(){ return "basic/addForm"; } /** * * addForm.html form에 있는 name과 변수명을 동일하게 해야한다. * 이 코드에서 @ModelAttribute 가 html 의 name 속성과 Item class 를 매칭시켜주고 * 그래서 itemRepository에 저장 로직에서 사용된다는 거까지는 이해했습니다 */ // @PostMapping("/add") public String addItemV1(@RequestParam String itemName, @RequestParam int price, @RequestParam Integer quantity, Model model){ Item item=new Item(); item.setItemName(itemName); item.setPrice(price); item.setQuantity(quantity); itemRepository.save(item); model.addAttribute("item",item); return "basic/item"; } // @PostMapping("/add") public String addItemV2(@ModelAttribute("item") Item item,Model model){ itemRepository.save(item); // model.addAttribute("item",item); return "basic/item"; } //@PostMapping("/add") public String addItemV3(@ModelAttribute Item item){ itemRepository.save(item); // model.addAttribute("item",item); return "basic/item"; } // @PostMapping("/add") public String addItemV4(Item item){ itemRepository.save(item); return "basic/addForm"; } /** * PRG - Post/Redirect/Get */ @PostMapping("/add") public String addItemV5(Item item) { itemRepository.save(item); return "redirect:/basic/items/" + item.getId(); } @GetMapping("/{itemId}/edit") public String editForm(@PathVariable Long itemId,Model model){ Item item = itemRepository.findById(itemId); model.addAttribute("item",item); return "basic/editForm"; } @PostMapping("/{itemId}/edit") public String edit(@PathVariable Long itemId,@ModelAttribute Item item){ itemRepository.update(itemId,item); // @ModelAttribute Item item라고 작성을 하면 item객체를 가져옴 return "redirect:/basic/items/{itemId}"; // 이렇게 리다이렉트로하면 PathVariable에 있는 것을 사용할 수 있음. //리다이렉션 부분 상품 수정 7분부터 다시 들어보기 이해안됨 /** * 상품명을 itemD로 변경하면 edit이 호출되고 http 상태가 302가 된다 * 이때, location은 items/2로 되는데 이것은 eidt의 결과가 리다이렉트라서 웹 브라우저가 2번으로 실제 item 2번으로 간다. */ } /** * 테스트용 데이터 추가 */ @PostConstruct public void init(){ itemRepository.save(new Item("itemA",1000,20)); itemRepository.save(new Item("itemB",2000,40)); } } 이것은 BasicItemController 코드입니다. 상품 등록 버튼을 누르면 위와 같은 오류가 발생합니다.그리고2023-09-18T23:32:41.550+09:00 ERROR 29201 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "/basic/items/add" (template: "basic/addForm" - line 17, col 30)] with root cause 라는 오류가 발생합니다.아무리 봐도 오류를 따라가서 수정을 해도 무엇이 문제인지 모르겠습니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcMemberRepository 와 JdbcTemplateMemberRepository 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]https://drive.google.com/file/d/1YQ9xwVxwzAN7xvYTOm0Jbky6vjB2e0cd/view?usp=share_link안녕하세요, repository 파일 내 JdbcMemberRepository 와 JdbcTemplateMemberRepository 가 지속적으로 implement 가 되지 않습니다. SpringConfig도 문제없고 데이터베이스도 실행중임을 확인하였는데, 무엇이 문제인지 여쭙습니다. 상단의 프로젝트 링크 참고 부탁드립니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
try, catch 문이 애매한 이유가 있나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] @Testpublic void 중복_회원_예약(){//givenMember member1 = new Member();member1.setName("spring");Member member2 = new Member();member2.setName("spring");//whentry{memberService.join(member2);fail();}catch (IllegalStateException e){assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다. ");}//then}try, catch 문을 사용하기에 애매한 이유가 정확하게 뭔지 궁금합니다. 사용하면 안되는 이유가 있나요?
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
파일 다운로드 404 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.스프링 MVC 2편까지 수강한 이후에 내용을 복습하려고 1편과 2편의 내용을 통합하여 상품 관리 시스템을 만드는 중인데 파일 다운로드에서 문제가 생겼습니다.상품 등록 폼에서 상품 이미지를 포함한 상폼 정보를 저장하고 상품 상세 폼에서 상품 이미지를 불러와서 상품 정보들과 함께 나타내려고 합니다.파일을 업로드해서 로컬 컴퓨터에 저장하는 것 까지는 잘 작동이 되는데 상품 상세 폼에서 파일을 다운로드하는 것이 되지 않고 파일 src로 들어가보면 404 에러코드가 나타납니다. 저장은 잘 되는데 무엇을 잘못한 걸까요? 아무리 찾아보고 고쳐봐도 잘 모르겠네요ㅠㅠhttps://drive.google.com/file/d/1llC0gBVa9VNnmXQEYZ0fp5qFpWCiBwHA/view?usp=sharing
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
beforeEach를 추가했음에도 afterEach가 필요한 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의 마지막에 beforeEach 메소드를 추가하여 매번 객체를 생성하게 되잖아요.그러면 굳이 afterEach() 메소드로 매번 clear할 필요가 없다고 생각했었는데 afterEach() 메소드를 주석 처리하면 오류가 나더라고요. 제 생각엔 MemoryMemberRepository의 store 변수가 static이기 때문에 beforeEach() 메소드로 매번 객체를 새로 생성하더라도 static 변수는 새로 생기지 않고 기존의 것이 계속 공유되고 있기 때문에 afterEach()가 필요한 거 아닐까 싶은데제가 정확히 이해한 게 맞는지, 제 생각에 오류가 있는지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Model이 생략되는 이유가 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Q1.addItemV1 코드를 보면1.파라미터로 받아오는 변수들을 item이라는 객체에 저장한다.2.item이라는 객체를 itemRepository에 저장한다.라는 부분까지는 이해했습니다.근데 model.addAttribute 부분은 어떤 역할을 하는건가요?그리고 Model이라는 개념은 자바 스프링에서 "데이터"라고이해를 했습니다.근데 Model이라는 객체가 따로 존재하는거 같은데 이건 무슨 역할을 하는건가요?지금와서 전부 헷갈리네요 설명 부탁드립니다 Q2.해당 코드 중에서 model이 생략되는 메소드에서는어떻게 model.addAttribute 역할을 대신할 수 있는건가요? Q3public String addItemV1(@RequestParam String itemName, @RequestParam int price, @RequestParam Integer quantity, Model model){ Item item=new Item(); item.setItemName(itemName); item.setPreice(price); item.setQuantity(quantity); itemRepository.save(item); model.addAttribute("item",item); return "basic/addForm"; } 라는 코드에서 item이라는 객체를 model.addAttribute 하는 이유가item 객체를 model이라는 객체에 전달하면자바 스프링에서 자동으로 model 안에 존재하는 객체가 view로 전달이 되기 때문인가요??
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemoryMemberRepository 클래스의 store 변수의 static 유무에 따라 실행 결과가 달라요.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]11:36 부분 내용처럼 MemberServiceTest의 join() 관련 테스트 코드 부분에서 setName()에 hello가 아닌 spring을 매개값으로 주고 실행하면 강의에서 보여주신 거와 마찬가지로 저도 오류가 나더라구요. 저는 회원 중복 검증하는 부분에서 오류가 났습니다. 물론 afterEach()는 안 한 상태에서요. 그런데 MemoryMemberRepository의 store 변수에 있는 static을 지우면 afterEach()를 작성하지 않았음에도 MemberServiceTest를 실행해도 오류가 나지 않습니다. 이유가 뭔가요?MemberServiceTest 클래스에선 memberService 객체를 하나 만들었고 그 하나 가지고 코드를 짰으니깐, store 변수가 static이든 아니든 그게 그거 아닌가요? 어차피 memberService 객체 하나를 공유하니까요. 여러 개를 만들었다면 모를까..왜 static 유무에 따라 오류가 나고 오류가 안 나는 것일까요? 아래 코드는 MemoryMemberRepository 클래스의 store 변수에 static이 있는 상태라서 Test 클래스를 실행하면 오류가 나지만, store 변수에 static을 지우고 Test 클래스를 실행하면 오류가 안 납니다. package hello.hellospring.repository; import hello.hellospring.domain.Member; import java.util.*; public class MemoryMemberRepository implements MemberRepository { private static Map<Long, Member> store = new HashMap<>(); private static long sequence = 0L; @Override public Member save(Member member) { member.setId(++sequence); store.put(member.getId(), member); return member; } @Override public Optional<Member> findById(Long id) { return Optional.ofNullable(store.get(id)); } @Override public Optional<Member> findByName(String name) { return store.values().stream() .filter(member -> member.getName().equals(name)) .findAny(); } @Override public List<Member> findAll() { //return (List<Member>)store.values();도 가능한지 확인해 보기. return new ArrayList<>(store.values()); } public void clearStore() { store.clear(); } } package hello.hellospring.service; import hello.hellospring.domain.Member; import hello.hellospring.repository.MemberRepository; import hello.hellospring.repository.MemoryMemberRepository; import java.util.List; import java.util.Optional; public class MemberService { private final MemberRepository memberRepository = new MemoryMemberRepository(); public Long join(Member member) { validateDuplicateMember(member); // 중복 회원 검증 memberRepository.save(member); return member.getId(); } private void validateDuplicateMember(Member member) { memberRepository.findByName(member.getName()) .ifPresent(m -> { throw new IllegalStateException("이미 존재하는 회원입니다."); }); } public List<Member> findMembers() { return memberRepository.findAll(); } public Optional<Member> findOne(Long memberId) { return memberRepository.findById(memberId); } } package hello.hellospring.service; import hello.hellospring.domain.Member; import hello.hellospring.repository.MemberRepository; import hello.hellospring.repository.MemoryMemberRepository; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class MemberServiceTest { MemberService memberService = new MemberService(); // MemoryMemberRepository memberRepository = new MemoryMemberRepository(); // // @AfterEach // public void afterEach() { // memberRepository.clearStore(); // } @Test void join() { // given Member member = new Member(); member.setName("spring"); // when Long saveId = memberService.join(member); // then Member findMember = memberService.findOne(saveId).get(); assertThat(member.getName()).isEqualTo(findMember.getName()); } @Test void 회원_중복_검증() { Member member1 = new Member(); member1.setName("spring"); Member member2 = new Member(); member2.setName("spring"); memberService.join(member1); IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2)); assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다."); // try { // memberService.join(member2); // fail(); // } catch(IllegalStateException e) { // Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다."); // } } @Test void findMembers() { } @Test void findOne() { } }