묻고 답해요
130만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증1 - Validation-검증 직접 처리 - 개발 질문입니다.
@PostMapping("/add") public String addItem(@ModelAttribute("item") Item item, RedirectAttributes redirectAttributes,Model model){ //검증 오류 결과를 보관 Map<String,String> errors=new HashMap<>(); //검증 로직 if (!StringUtils.hasText(item.getItemName())) { errors.put("itemName", "상품 이름은 필수입니다."); } if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) { errors.put("price", "가격은 1,000 ~ 1,000,000 까지 허용합니다."); } if (item.getQuantity() == null || item.getQuantity() >= 9999) { errors.put("quantity", "수량은 최대 9,999 까지 허용합니다."); } //특정 필드가 아닌 복합 룰 검증 if (item.getPrice() != null && item.getQuantity() != null) { int resultPrice = item.getPrice() * item.getQuantity(); if (resultPrice < 10000) { errors.put("globalError", "가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = " + resultPrice); } } if (!errors.isEmpty()){ log.info("errors={}",errors); model.addAttribute("errors",errors); return "basic/addForm"; } Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId",savedItem.getId());//인코딩 redirectAttributes.addAttribute("status",true); return "redirect:/basic/items/{itemId}";//위에는 포스트로 상품 추가 해주고 밑에는 다시 get으로 호출시키는 방법. }@ModelAttribute("item") Item item <-이부분이 item class의 엔티티를 의미하고 Model model은 메소드에서만 사용하는 특정 임시 객체로 이해하면 되나요?@ModelAttribute은 model.addAttribute가 자동으로 생성되는데요. 큰 기숙사 안에서 동일한 룸에 에러코드도 들어가고 아이템 모델도 들어가는건가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
상품 수정 강의 질문있습니다.
@GetMapping("/{itemId}/edit") public String editForm(@PathVariable Long itemId, Model model) { Item item = itemRepository.findById(itemId); model.addAttribute("item", item); return "basic/editForm"; }GetMapping에 {itemId}가 있는데 이변수는 어디서 받아오는건가요?저는 item class에서 받아온다고 생각했는데 아래는 id로 소문자인데 itemId는 어디서 받아오는건가요?package hello.itemservice.domain.item;import lombok.Data;@Datapublic class Item { private Long id; private String itemName; private Integer price; private Integer quantity; public Item() { }
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
상품 출력 질문입니다.
맨 윗 사진이 사진1, 두번째 사진이 사진2라고 가정시. package com.example.itemstore.itemservice.web.basic;import com.example.itemstore.itemservice.domain.item.Item;import com.example.itemstore.itemservice.domain.item.ItemRepository;import jakarta.annotation.PostConstruct;import lombok.RequiredArgsConstructor;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import org.springframework.web.servlet.mvc.support.RedirectAttributes;import java.util.List;@Controller@RequestMapping("/basic/items")@RequiredArgsConstructorpublic class BasicItemController {private final ItemRepository itemRepository;@GetMappingpublic String items(Model model){List<Item> item=itemRepository.findAll();model.addAttribute("item",item);return "basic/items";}@GetMapping("/{itemId}")public String item(@PathVariable long itemId, Model model){Item item = itemRepository.findById(itemId);model.addAttribute("item",item);return "basic/items";}@GetMapping("/add")public String addForm() {return "basic/addForm";}/**테스트용 데이터 추가/@PostConstructpublic void init(){itemRepository.save(new Item("a",10,1));}}질문 : 위 코드는 사진 2처럼 나오고 아래코드는 사진1처럼 정상출력되는데 이유가 뭔가요? 변수명items과 model.addAttribute에 이름을 같게 넣어서 아래 위 코드 둘다 같은 결과가 나와야 한다고 생각하는데 막상 실행하면 결과가 다르게 나와서요.public class BasicItemController {private final ItemRepository itemRepository;@GetMappingpublic String items(Model model){List<Item> items=itemRepository.findAll();model.addAttribute("items",items);return "basic/items";}전체코드: https://drive.google.com/file/d/1wGf0aRjKQ-haXmTupwJy9KUVwoY8gIbY/view?usp=drive_link질문: 아래 링크 추가질문 올려놨는데 답변 부탁드립니다.https://www.inflearn.com/questions/1251246/%EC%83%81%ED%92%88-%EB%93%B1%EB%A1%9D-%EC%B2%98%EB%A6%AC-modelattribute-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
글자 인코딩 오류
글자 인코딩문제 해결법 있을까요
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
index.html이 열리지 않습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]index.html이 열리지 않습니다. 지난 동일한 질문에 대한 답변을 보았는데 이해가 되질 않았습니다. 자세하게 해결방법을 알려주시면 감사하겠습니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
스프링JdbcTemplete강의 내용 1:38초부분에서 의존성주입 질문이 있습니다
//JdbcTemplateMemberRepository public class JdbcTemplateMemberRepository implements MemberRepository { private final JdbcTemplate jdbcTemplate; public JdbcTemplateMemberRepository(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); //SpringConfig @Configuration public class SpringConfig { private final DataSource dataSource; public SpringConfig(DataSource dataSource) { this.dataSource = dataSource; } JdbcTemplate을 사용하도록 스프링 설정 변경하는 부분인데이전에 객체를 생성해서 직접 주입하면 안좋다고 하셨었는데jdbc템플릿을 적용하시는 부분에서는 직접 dataSource를 JdbcTemplate를 생성해서 넣으셨습니다.public SpringConfig(DataSource dataSource) { this.dataSource = dataSource; }대신에 JdbcTemplate를 빈에 등록해서 이렇게 사용하는게 이전에 배운내용에 따르면 의존성, 결합성 면에서 나은 코드라 생각했습니다.(@autowired를 사용하게끔 수정해본 코드)//JdbcTemplateMemberRepository public class JdbcTemplateMemberRepository implements MemberRepository { private final JdbcTemplate jdbcTemplate; @Autowired public JdbcTemplateMemberRepository(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); //SpringConfig @Configuration public class SpringConfig { private final DataSource dataSource; @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } } 이렇게 수정해서 사용하라고 설명해주시다가 이 JdbcTemplate강의에서는 직접 주입하시면서 설명해주셨는데,JdbcTemplate빈을 정의해서 주입하는 방식이 아닌Datasource를 직접 사용한 이유가 있을까요?뭔가 데이터접근할때는 다른부분이 있어서 이런 방법이 사용된건지 궁금합니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
DI 적용해보기
안녕하세요! 유익한 수업 너무 재밌게 잘 듣고 있습니다. 감사합니다.제가 많이 미흡하여 이상한 질문일 수 있는 점 미리 양해부탁드립니다.강사님께서 FrontControllerServletV5 의 handlerMappingMap, handlerAdpaterList 에 DI 를 할 수 있다는 말씀을 듣고 공부차원에서 시도해보았는데요.아래와 같이 handlerMappingMap, handlerAdpaterList 를 일급 컬렉션으로 만들어 HandlerMappingConfig 와 HandlerAdapterConfig 를 이용하여 @Bean 으로 등록했습니다. FrontControllerServletV5 에는 @RequiredArgsConstructor 를 이용해 의존관계를 주입했습니다.FrontControllerServletV5@RequiredArgsConstructor @WebServlet(name = "frontControllerServletV5", urlPatterns = "/front-controller/v5/*") public class FrontControllerServletV5 extends HttpServlet { private final HandlerMappingMap handlerMappingMap; private final HandlerAdapterList handlerAdapterList; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... } private Object getHandler(HttpServletRequest request) { return handlerMappingMap.getHandler(request); } private MyHandlerAdapter getHandlerAdapter(Object handler) { return handlerAdapterList.getHandlerAdapter(handler); } ... } HandlerAdapterConfig@Configuration public class HandlerAdapterConfig { @Bean public HandlerAdapterList handlerAdapterList() { return new HandlerAdapterList(registerHandlerAdapters()); } private List<MyHandlerAdapter> registerHandlerAdapters() { List<MyHandlerAdapter> handlerAdapters = new ArrayList<>(); handlerAdapters.add(new ControllerV3HandlerAdapter()); handlerAdapters.add(new ControllerV4HandlerAdapter()); handlerAdapters.add(new ControllerV2HandlerAdapter()); return handlerAdapters; } }HandlerMappingConfig@Configuration public class HandlerMappingConfig { @Bean public HandlerMappingMap handlerMappingMap() { return new HandlerMappingMap(registerHandlers()); } private Map<String, Object> registerHandlers() { HashMap<String, Object> urlMap = new HashMap<>(); urlMap.put("/front-controller/v5/v2/members/new-form", new MemberFormControllerV2()); urlMap.put("/front-controller/v5/v2/members/save", new MemberSaveControllerV2()); urlMap.put("/front-controller/v5/v2/members", new MemberListControllerV2()); urlMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3()); urlMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3()); urlMap.put("/front-controller/v5/v3/members", new MemberListControllerV3()); urlMap.put("/front-controller/v5/v4/members/new-form", new MemberFormControllerV4()); urlMap.put("/front-controller/v5/v4/members/save", new MemberSaveControllerV4()); urlMap.put("/front-controller/v5/v4/members", new MemberListControllerV4()); return urlMap; } }HandlerAdapterListpublic class HandlerAdapterList { private final List<MyHandlerAdapter> handlerAdapters; public HandlerAdapterList(List<MyHandlerAdapter> handlerAdapters) { this.handlerAdapters = handlerAdapters; } public MyHandlerAdapter getHandlerAdapter(Object handler) { for (MyHandlerAdapter handlerAdapter : handlerAdapters) { if (handlerAdapter.supports(handler)) { return handlerAdapter; } } throw new IllegalArgumentException("handler adapter 를 찾을 수 없습니다. handler=" + handler); } }HandlerMappingMappublic class HandlerMappingMap { private final Map<String, Object> handlerMappingMap; public HandlerMappingMap(Map<String, Object> handlerMappingMap) { this.handlerMappingMap = handlerMappingMap; } public Object getHandler(HttpServletRequest request) { String requestURI = request.getRequestURI(); return handlerMappingMap.get(requestURI); } }정상 작동하는 것은 확인하였지만, 몇가지 궁금한 사항이 있어서 질문 드립니다.1. @Configuration 과 @Bean, 일급 컬렉션을 이용한 방법 말고도 다른 DI 적용 방법이 있을까요?2. Map, List 를 일급 컬렉션으로 만드는 과정에서 getHandlerAdapter, getHandler 와 같은 메서드들을 의미있는 논리 메서드로 판단해서 각각의 컬렉션의 메서드로 뺐는데, 제가 맞게 판단한 것일까요?3. 여전히 registerHandlers, registerHandlerAdapters 에는 각각의 객체들을 더하는 코드들이 길게 나열되어 있어 지저분합니다. 이것들도 깔끔하게 자동으로 주입 받는 방법이 있을까요? (강사님께서 언급하신 @RequestMapping 어노테이션의 작동 원리와 관련이 있을까요? spring-webmvc 코드를 살펴보았을 때는 SimpleUrlHandlerMapping 의 protected void registerHandlers(Map<String, Object> urlMap) 을 통해 url 을 등록하는 것으로 보이는데, 이것과 연관이 있을까요?)긴 글 읽어주셔서 감사합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
마지막챕터 아이템 등록 질문입니다.
코드:
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
프로젝트 파일 문제
강사님이 제공해주시는 프로젝트 압축 풀어서 인텔리제에서 File -> Open -> build.gradle 선택해서 열었는데 다른 프로젝트들과 달리 src main test가 보이지 않습니다 어디가 잘못된것일까요......
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
gradlew 빌드가 계속 실패로 뜹니다.
cmd 실행 시 위와 같은 오류가 계속 발생하고 있습니다.위와 같이 옵션을 인텔리제이 idea로 바꿨음에도 오류가 발생합니다.jdk 21이며, 환경변수 모두 세팅되어 있습니다. (java -version, javac -version) 테스트 리포트는 아래와 같습니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
상품 등록 처리 - @ModelAttribute 질문입니다.
1.빨간색 박스끼리 서로 데이터를 받고 초록색끼리 데이터를 받는거 맞나요? // @PostMapping("/add") public String addItemV2(@ModelAttribute("item") Item item, Model model) { itemRepository.save(item); // model.addAttribute("item", item); //자동 추가, 생략 가능 return "basic/item"; }2. 위에 코드에서 ModelAttribute로 모델을 받아오는데 Model model이 부분은 또 왜쓰는건가요? @Data public class Item { private Long id; private String itemName; private Integer price; private Integer quantity; public Item() { 아래 부터는 상품 도메인 개발 강의 질문입니다. 기본생성자는 왜만드는건가요? @Data public class Item { private Long id; private String itemName; private Integer price; private Integer quantity; public Item() { }3분36초에서 4분까지 싱글톤을 넣기 위해서 static을 사용하시는 이유를 말씀하셨는데요.그런데 스프링부트는 자동으로 싱글톤 지원하는거 아닌가요?New를 작성하여 객체를 생성한다는게 자세하게 설명을 들을 수 있을까요? 9분 16초에서 지금은 스프링을 안쓴다고 하셨는데요. 스프링을 쓰는데는 강의에서 언제인가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
특정 리소스가 없을때에 예외페이지 처리 방법 질문드립니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]예를 들어서, 게시글을 조회하는 서비스가 있다고 가정해 보겠습니다./post/158위 URL을 요청할 경우, 웹 애플리케이션에서 id = 158인 게시글을 찾아 해당 내용을 클라이언트에게 주며, 만약 전달된 아이디에 해당하는 게시글이 없을 경우 예외(NoSuchPostException)을 반환하도록 구현을 했습니다.그런데 이 때, 아무런 설정이 없으면 예외가 WAS까지 전달이 되면 무조건 500 Error가 발생이 되는 것으로 알고 있습니다.제가 궁금한 것은위와 같은 상황에서 404 에러가 아닌, 500에러를 반환하도록 구현하는 것이 맞는 지 궁금합니다. 158이라는 아이디에 해당하는 리소스가 없을 경우에는 Not Found 404 상태코드를 반환하는게 맞다고 생각을 하였는데, 실무에서는 이런 상황에서 어떠한 상태코드를 사용하는 지 궁금합니다.특정 예외(이를테면 NoSuchPostException)상황에서는 404코드를 반환하도록 하고 싶은데, 이럴 경우 스프링에서 제공하는 BasicErrorController를 사용하지 못하고, 직접 에러 컨트롤러를 만들어서 처리해야 하나요? (스프링 인터셉터와 필터를 이용한 방법 모두 해보았는데 도저히 안되겠어서 질문드립니다)
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
콘솔에 "]"가 계속 출력됩니다.
콘솔에 계속 "]"가 출력됩니다.두 번째 사진은 회원가입 파라미터가 넘어가는 과정인데 username=kim&age=22]이렇게 나오는데 username=kim&age=22 이 파라미터를 프린터 한 적이 없는데 어느 과정에서 나오는 건지 모르겠습니다.아마 username=kim&age=22와 ]가 같이 프린트 되게 되어 있는 것 같은데 어떻게 찾아야할지를 모르겠어요
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
getUsername 메소드
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]사진과 같이 메서드 적용이 안되는데 혹시 이유를 알 수 있을까요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
hikari 커넥션 풀 초기화 정보 출력
이런거 저는 안 뜨는데 뭘 어떻게 해야 하나요 [MyPool connection adder] MyPool - Added connection conn0: url=jdbc:h2:.. user=SA[MyPool connection adder] MyPool - Added connection conn1: url=jdbc:h2:.. user=SA[MyPool connection adder] MyPool - Added connection conn2: url=jdbc:h2:.. user=SA[MyPool connection adder] MyPool - Added connection conn3: url=jdbc:h2:.. user=SA[MyPool connection adder] MyPool - Added connection conn4: url=jdbc:h2:.. user=SA...[MyPool connection adder] MyPool - Added connection conn9: url=jdbc:h2:.. user=SA
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
"MVC 패턴 - 적용" 강의에서 질문 있습니다.
localhost:8080/servlet-mvc/members/new-form으로 접속할 때는 잘 되는데 "전송"을 누를 시 자꾸 404 에러가 납니다.... 다른 분들 질문도 확인보았는데 도대체 뭐가 문제인지 모르겠습니다... ㅠㅠhttps://drive.google.com/file/d/1ewVIIKcmZ3zOXwJd2yXv-mYleVoPXYSo/view?usp=drive_link이 링크는 제 코드 작성한 링크입니다.이렇게 코드를 작성하고 http://localhost:8080/servlet-mvc/members/new-form 으로 접속 하면 아래와 같이 화면이 잘 나옵니다.그런데 여기서 kim ,20 을 입력하고 전송을 누르니 아래와 같이 WhiteLabel 페이지 뜨면서 404 에러가 납니다...제 코드에 오타가 있는 걸까요 ㅠㅠㅠ다른분들이 질문한것들 참고해봤는데 @ServletComponentScan 도 달려있고 스프링부트3.0 이상이 해야하는 의존성도 build.gradle에 추가해주었습니다. 오타는 진짜 제가 수없이 확인했는데 없는것 같은데...... 뭐가 문제인지 알려주시면 감사하겠습니다 ㅠㅠ
-
미해결스프링 부트 웹 개발 입문 - 따라하며 배우기
Spring Boot에서 jsp 연동 오류
안녕하세요 선생님,Spring framework로 jsp를 사용하려고 강의(강의명 : Spring framework의 천하통일)를 따라 진행하는데 도무지 해결할 수 없어 질문으로 남깁니다! 모든 코드는 복사붙여넣기하여 선생님과 동일하나 결과는 아래와 같습니다...어떻게 해결할 수 있을까요?(Java 1.8, JDK 8) 상황설명jsp 설정을 위해 implementation을 추가하고 새로 로드하였는데 아래와 같은 로그가 출력되었습니다.이 상태에서 애플리케이션을 실행하면 나오는 로그
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
/request-param-v1 질문있습니다.
@Slf4j @Controller public class RequestParamController { @RequestMapping("/request-param-v1") public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException { String username = request.getParameter("username"); int age = Integer.parseInt(request.getParameter("age")); response.getWriter().write("ok"); } @ResponseBody @RequestMapping("/request-param-v2") public String requestParamV2( @RequestParam("username") String memberName, @RequestParam("age") int memberAge) { log.info("username={}, age={}", memberName, memberAge); return "ok"; } 왜 requestParamV1 메소드는 Controller와 을 사용하고 @RestController을 사용해도 작동되는데 requestParamV2은 Controller 사용시 @ResponseBody를 붙여야 하잖아요. 인터넷에 찾아보니 메소드가 데이터(예: 문자열 "ok")를 반환하는 경우 ResponseBody를 작성해야 한다고 하는데요.근데 둘다. response.getWriter().write("ok");/ return "ok"; 데이터 반환 아닌가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
model.addAttribute시 질문!!
컨트롤러에서 model.addAtrtibute시 attributeName을 임의로 설정하면 왜 th:value="${attributeName.} ( 프로퍼티 접근) 시에 오류가 생기는건가요??attributeName을 어떤거랑 일치시켜야 하나요?!
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
findByName() 메서드 실행시 오류
프로젝트 압축파일입니다.https://drive.google.com/file/d/1IRv3FX6UTERveIoq1KaZY7N_DyVLGv0b/view?usp=sharing<회원 리포지토리 테스트 케이스 작성> 강의 9:40 경에findByName() 메서드 실행시 java.util.NoSuchElementException: No value present at java.base/java.util.Optional.get(Optional.java:143) at hello.hellospring.repository.MemoryMemberRepositoryTest.findByName(MemoryMemberRepositoryTest.java:45) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)라는 오류가 발생합니다.이 오류로 인해 findAll() 메서드까지 실행이 되지 않는 것 같습니다. get()과 관련된 오류 같아 구글링해보아도 해결이 어려워 문의남깁니다.답변 부탁드립니다. 감사합니다.