묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
BasicItemControllerV2 코드 질문있습니다.
@PostMapping("/add") public String addItem2(@ModelAttribute("item") Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model){ //검증 오류 결과를 보관 Map<String,String> errors=new HashMap<>(); //검증 로직 if (!StringUtils.hasText(item.getItemName())) { bindingResult.addError(new FieldError("item","ItemName","상품 이름은 필수입니다.")); // errors.put("itemName", "상품 이름은 필수입니다."); } if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) { bindingResult.addError(new FieldError("item","Price","가격은 1,000 ~ 1,000,000 까지 허용합니다.")); // errors.put("price", "가격은 1,000 ~ 1,000,000 까지 허용합니다."); } if (item.getQuantity() == null || item.getQuantity() >= 9999) { // errors.put("quantity", "수량은 최대 9,999 까지 허용합니다."); bindingResult.addError(new FieldError("item","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); bindingResult.addError(new ObjectError("item","가격 * 수량의 합은 10,000원 이상이어야 합니다. 현재 값 = + resultPrice")); } } if (bindingResult.hasErrors()){ log.info("errors={}",errors); model.addAttribute("errors",errors); return "validation/v2/addForm"; }위에 코드는 BasicItemControllerV2 중 일부 입니다.FieldError는 item class에 있는 엔티티를 찾아서오류를 출력해주는건가요?ObjectError는 item class에 엔티티가 없어서 새로 item 객체를 생성해서 가격을 검사하는건가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ERROR null로 출력되는 문제
에러페이지인 error-ex, error-page/404, error-page/500 3개를 들어갔을 때 에러들이 출력되게 했습니다. 다른 질문들에서도 비슷한 오류를 가진 분들이 있어서 한번 해봤습니다.1차적으로 javax를 jakarta로 바꿨습니다.public static final String ERROR_EXCEPTION = "jakarta.servlet.error.exception"; public static final String ERROR_EXCEPTION_TYPE = "jakarta.servlet.error.exception_type"; public static final String ERROR_MESSAGE = "jakarta.servlet.error.message"; public static final String ERROR_REQUEST_URI = "jakarta.servlet.error.request_uri"; public static final String ERROR_SERVLET_NAME = "jakarta.servlet.error.servlet_name"; public static final String ERROR_STATUS_CODE = "jakarta.servlet.error.status_code";log.info에서 해당 상수들을 출력해보려고 했더니 error-ex페이지에서는 잘 출력되지만 404와 500에서는 모든 값이 null로 출력되었습니다.2차적으로 RequestDispatcher.ERROR_EXCEPTION처럼 모든 log.info에서 상수를 이용하는것이 아닌 RequestDispatcher.**를 사용했습니다. 이렇게 바꿨음에도 error-ex 페이지는 잘 출력되었지만 404와 500에서는 모든 값이 null로 출력되었습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증1부분에 html이 이상하게 조회됩니다.
화면에서 아래와 같이 이렇게 뜹니다. 뭐가 문제인지 알려줄 수 있나요? html은 건드른게 없어요.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
테스트코드 작성시
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]테스트 코드 작성시 Test Results라고만 나오고 하위에 save() 이렇게 나오지 않습니다. 왜 그런걸까요??
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@ModelAttribute @RequestParam
안녕하세요. 강의를 듣던중 궁금한 내용이 생겼는데 구글링을 해도 명확한 답변이 나오지않아 질문드립니다ㅠㅠ 강의 내용중 컨트롤러의 파라미터에서, @ModelAttribute MultipartFile file와 @RequestParam MultipartFile file의 차이가 무엇인지 질문드립니다..!강의 자료에서는 ' @ModelAttribute에서도 MultipartFile을 동일하게 사용할수있다 ' 고 되어있지만, 어차피 file.getOriginalFilename()을 사용하는것은 @ModelAttribute나 @RequestParam이나 동일한것같은데, 어떨때 @ModelAttribute를 사용해야하고, 어떨때 @RequestParam을 사용해야하는지 모르겠습니다.. 둘중 아무거나 사용해도 되는건가요..? 바로 뒤 강의에서는 @ModelAttribute로서 MultipartFile을 받아오는거같은데 어떨때 사용하는것인지 궁금해서 질문드립니다..! 감사합니다!
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
pdf 파일에 이거 추가하면 좋을 것 같습니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의에서 messages.properties에 한글로 저장을 하게 되는데, 인텔리제이를 사용하면 한글 깨짐이 발생하더라구요 Setting - File Encodings에서 Default encoding for properties files 를 ISO-8859-1 에서 UTF-8 로 변경후 Transparent native-to-ascil conversion 체크하면 해결돼서 혹시 도움이 될까 하고 남겨봤습니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
@GetMapping 같은 어노테이션 문법
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]@GetMapping, @RequestParam같은 걸 어노테이션이라고 한다는데 이거에 대한 문법같은걸 배우고 들어야 할까요?
-
미해결[NarP Series] MVC 프레임워크는 내 손에 [나프1탄]
강의 20강 질문 및 오류관련
20강 수강중입니다. membervo에서 pass는 int로 지정되어있짐만 memberInsertController에서는 String으로 되어있는지 궁금합니다.위 내용으로 인해 오류가 발생합니다. 도와주세요java: constructor MemberVo in class model.MemberVo cannot be applied to given types; required: int,java.lang.String,int,java.lang.String,int,java.lang.String,java.lang.String found: no arguments reason: actual and formal argument lists differ in length
-
미해결[리액트 1부] 만들고 비교하며 학습하는 리액트 (React)
sort() 질문 드립니다.
안녕하세요.최근 검색어 구현 중 Store.js에서 스토리지의 historyData를 받아와서 sort를 할 때,강의에서 나오는대로 > 부등호로 하면 정렬이 되지 않고- 를 해줘야 내림차순으로 정렬이 됩니다. 왜 강의와 똑같이 부등호로 했을 때 정렬이 안되는 것일까요? getHistoryList() { return this.storage.historyData.sort(this._sortHistory); // 날짜 역순 정렬 } _sortHistory(history1, history2) { // return history2.date > history1.date; return history2.date - history1.date; }
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
H2 데이터베이스 설정 관련 질물
h2.bat을 실행하면 cmd 창이 계속 떠 있습니다. (cmd 창을 죽이면 콘솔 접속이 안되네요)정상인가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
사이트 연결 오류
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강의와 똑같이 진행했는데 어떤부분이 오류 발생원인인지 파악을 못하겠습니다. ㅠㅠ [구글 드라이브 주소]https://drive.google.com/file/d/1HzSpLYQbb-IFI5ho7YYkSjGvV0ZOySYm/view?usp=drive_link
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증1 - Validation 강의에서 질문이 있습니다.
mvc1편에 이어서 작업한거 이후에 강의대로 v1~v4버전을 만들었는데요. 근데 item들어가면 화이트 페이지 뜹니다.제가 생각하기에는 basic에서 validation으로 변수 다 바꿔줬는데 안되는지 이해가 안됩니다. 아래는 전체코드입니다.
-
미해결스프링 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편 - 백엔드 웹 개발 핵심 기술
마지막챕터 아이템 등록 질문입니다.
코드: