월 16,940원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타입에러-bindingResult
안녕하세요, 아래에 다른분께서 질문하신 내용의 답변을 토대로 다시 궁금증이 생겨 여쭙니다. 타입에러가 아닌 상태에서 바인딩이 된 상태에서 필드오류가 발생한다면 bindingResult 의 fieldError에 오류내용이 담기는것은 이해했습니다.만약 , 타입에러가 난다면 바인딩 이 안되는데, 이부분도validation 과 마찬가지로 스프링이 필드오류보다 먼저 binding result 에 오류값이 담기나요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
SessionManagerTest @Slf4j 사용하면 안되나요?
너무 기초적인 질문인것 같아서요Test Case 작성시@Slf4j 로그 어노테이션을 이용하여 로그를 출력하고 싶은데error: cannot find symbol log.info("SessionManagerTest1={}", member);이런 오류가 발생하네요
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
로그에 모든 경로의 url이 다 나옵니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 강의를 따라가다보니 저는 로그에 모든 url경로가 다 나오는데 선생님 강의에서는 localhost:8080은 제외한 이후 경로만 나옵니다. 제가 혹시 어느 부분을 놓친건지 궁금합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
에러메세지 만드는 거
https://drive.google.com/file/d/1z-zuoAUetdDnRiEBscuhmhDL95TM65C-/view?usp=sharing제 공유파일입니다. 수업듣고 혼자서 만들어 보는데 도무지 모르겠습니다. localhost:8080/member/save에서 아무것도 안 누르고 회원가입 눌렀는데 왜 에러메세지 안 뜨고 에러페이지가 뜰까요 ㅠㅠ 컨트롤러에 if(!StringUtils.hasText(memberDTO.getMemberId())) {//springutils spring꺼 임포트 해야함 bindingResult.addError(new FieldError("memberDTO","memberId","아이디는 공백이 안 됩니다.")); }이 부분도 추가 하고 다 했는데 ㅠ
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
httpSession 관련 질문드립니다.
request.getSession() 으로 생성된 httpsession은 sessionStore 인지 아니면 session 인지 궁금합니다.제 생각에는 sessionStore가 아니라 그냥 sessionStore에서 session을 검색해서 가져오거나, 없으면 session을 생성한 것이라고 생각합니다. 이렇게 생각하게 된 이유는, /session-info url로 크롬과 사파리로 브라우저를 다르게 하여 접속한 결과, 크롬에서 로그인을 했더라도, 사라피로 로그인하지 않고 session-info 로 접속한다면 session 이 없다고 떴기 때문입니다. 그렇기 때문에, request.getSession() 으로 생성된 session 에서 session.setAttribute("member", member) 이런식으로 attribute를 추가하는 것은 그냥 그 세션자체에 member라는 것을 추가하는 것으로 짐작됩니다. 따라서 직접 만들어본 SessionManager 의 createSession 과는 다르다고 생각하는게, createSession은 sessionStore에 직접 sessionId 와 member를 묶어서 직접 put을 해준것이고httpsession.setAttribute는 그저 session에 attribute를 추가해준 것이라고 생각하기 때문입니다.그리고 httpSession 은 어딘가에 있을 sessionStore에 저장되겠죠 << 사실 이 부분이 의문입니다. 어느시점에 session이 sessionStore에 저장되는지, 그 sessionStore는 어디있는지 궁금합니다.대충 시점은 getSession() 하는 순간 sesstionStroe를 탐색해서 없다면 sessionStore에 저장하면서 해당 session을 가져오고 그 세션에 setAttribute로 속성을 추가해주는 것 같다고 예상되긴 합니다. 그래서 궁금한 점은 httpSession의 sessionStore은 어디있는지 궁금합니다. 그리고 만약 존재한다면 어느시점에 생성되는건지 궁금합니다. 그리고 직접 확인이 가능한지도 궁금합니다.분명 여러유저가 접속한다면 sessionStore에 session이 쌓일텐데 그 쌓이는게 어떻게 쌓이는지 보고싶습니다. 그와 동시에 궁금해지는 점은 session.getAttribute("loginMember") 이런식으로 한번더 세션에 멤버 어트리뷰트가 존재하는지 확인하는 이유도 궁금합니다. 세션을 만들때 무조건 loginMember를 설정해줄것이고, 만약 세션자체가 사라진다면 그냥 사라질텐데, 세션을 만들때 session.setAttribute("loginMember", loginMember) 를 하지 않는 경우가 있나요??제 가정이 다 맞다고 가정하에, 그리고 브라우저 종료시에 쿠키가 즉시 브라우저에서 삭제된다고 가정할때, 로그아웃 하지 않고 바로 브라우저를 종료하고 로그인 하는 식으로 똑같은 사용자가 여러번 로그인을 한다면, 그때마다 브라우저는 항상 쿠키가 존재하지 않으니까, getSession으로 sessionStore에서 session을 찾지 못할 것이고 그렇다면 새로운 jsessionid 값에 똑같은 사용자를 가진 session을 게속 생성해서 sessionStore에 저장하게 되는 것이 아닌가요?? 그렇다면 세션이 시간이 만료되어서 자동으로 삭제 되기전까지 똑같은 사용자를 포함한 여러개의 세션이 세션스토어에 게속 쌓일것이라고 예상되는데, 그럼 여러가지 jsessionId로 하나의 계정에 접속이 가능한 것인지 궁금합니다. 혹시 제 예측이 틀린것이라면 어떻게 틀렸는지 설명해주시면 감사드리겠습니다.https://www.inflearn.com/questions/989189/request-getsession-%EA%B3%BC-sessionstore위 링크의 질문도 봤는데 아무리 생각해도 sessionStore를 여러개 생성한다는 개념은 뭔가 이상하다고 생각해서 의문이 해결되지 않습니다.
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
HttpSession과 쿠키
안녕하세요 해당 강의를 듣고 복습하던 중 의문점이 생겨 질문 드립니다!getSession()이 세션이 있는 경우에는 해당 세션을 가져오고, 없는 경우에는 새로 생성한다고 하셨는데 세션이 있는지 없는지는 요청에 있는 쿠키의 JSESSIONID 값을 기준으로 판별하는 건가요? 만약 한 사용자가 로그아웃을 하지 않은 상태로 브라우저를 종료하고 다시 로그인을 수행하면, 쿠키가 삭제되어 이전의 JSESSIONID 값이 사라지게 되어서 getSession()이 해당 세션은 없다고 판단하고 새로운 세션을 생성하게 되나요? 타임아웃이 없다고 가정한다면, 세션 저장소에는 같은 사용자에 대한 세션 정보가 여러개 저장되는건가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
bindingREsult.hasErrors() 부분 재사용
if(bindingResult.hasErrors()) { log.info("errors = {}", bindingResult); //model.addAttribute("errors", errors); -> model로 넘겨주지않아도 bindingResult 자체로 자동으로 뷰에넘어간다. return "validation/v2/addForm"; }위 코드를 다시 addItemV4의 첫부분에 재사용하는 이유가 먼저 타입오류가 발생하면 밑의 가격 range 오류를 검증하지 않고 바로 "validation/v2/addForm" 뷰로 리턴하여 타입오류 메시지만(하나만) 출력하고 싶을때 이런식으로 하는거죠?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ItemType 같이 enum 으로 관리되는게 변경의 여지가 있다면 코드테이블로 관리하는게 좋을까요?
ItemType 같이 enum 으로 관리되는게 변경의 여지가 있다면 어떻게 관리하는게 좋을지 생각해 봤는데요,상수를 따로 관리하는 테이블을 생성해서세션이나 캐시로 관리하는게 어떨까 싶은데 현업에선어떻게 관리되는지 궁금합니다.아무래도 세션보단 캐시가 더 효율적이겠죠?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@ModelAttribute와 html/text에 대하여 질문이 있습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.컨버전 서비스는 @RequestParam, @ModelAttribute, @PathVariable, 뷰 템플릿에 적용된다는 내용에 궁금증이 생겨 질문을 드립니다. @ModelAttribute는 @RequestParam의 기능에서 객체를 생성하고 model에 담는 기능이 추가되었다고 생각했었습니다. 이렇게 객체가 생성될 때 컨버전 서비스가 작용되는 걸까요? 하지만, String을 다른 타입으로 바꾸어 받을 수 있는 @PathVariable이나 @RequestParam과는 달리 객체를 생성하거나 set하는 @ModelAttribute는 컨버전과 관계가 없게 느껴집니다. 어떤 경우 @ModelAttribute에도 컨버전 서비스가 적용되는 것인가요?html/form형식에서 post방식을 통해 http요청의 바디에 데이터가 들어온다고 학습하였습니다. 이때 데이터가 바디에있지만 @ResponseBody가 아닌 마치 get방식처럼 @RequestParam, @ModelAttribute을 이용해야 하는 것은 스프링의 api때문으로 이해하면 될까요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:class 부분 th:if /th: classappend
위 코드에서 th: class= ${errors?.containsKey('itemName')} ? ~~~ 를 if 조건식으로 참 거짓 구분하여 참이면 클래스 뒤에 append를 해주는 방식으로 해주었는데 이방식으로 하면 아예 상품명 공간이 사라지네요 ㅜ 다른방식으로도 해보고 싶은데 강사님이 알려주신 th:class 밖에 없는것일까요?타임리프 기본 문법을 다시 보면서 변형해보고있는데 잘 안되서요 😅 th:if="${errors?.containsKey('itemName')}" th:classappend="field error"
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@CookieValue Long memberId
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)Long type 자동 변환된 memberId를memberRepository.findById(memberId)하니 Integer 이하 생략 그림참조에러떠서 진행이 안됩니다.
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
하이버네이트 빈 밸리데이션 언어 관련 질문
@NotEmpty 어노테이션 사용하면 기본메세지가 한국어로 되어있던데이게 어떤 걸 영향받아서 한국어로 기본메세지를 출력하는 것인지 궁금합니다. 영어로 설정하면 영어가 나올까 싶어서 구글 브라우저 언어순위에 영어를 상단으로 올려보고, 크롬 언어자체를 영어로 바꿔봐도 한국어로비어 있을 수 없습니다라고 출력이되는데 이 어노테이션이 어디에 영향을 받아서 한국어로 출력하는 것인지 궁금합니다. 따로 errors.properties 에 설정되어있지도 않아서 더 궁금합니다. ++@NotEmpty 어노테이션 타고들어가니까 기본메세지가 여러가지 언어로 국제화되어있었어요이상해서 다시 크롬 언어설정에서 영어 최상단하고 해보니까 영어로바뀌네요 아까는 안되었는데 왜 지금은 되는건지 의문;;
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
사소하지만 다음과 같이 되는게 맞을까요?
예외를 통해 에러코드 500이 만들어 진것을수정하여 400으로 고치는 로직이므로error/400페이지를 보여주는게 맞는 흐름일 것 같은데아닐까요? // TEXT/HTML return new ModelAndView("error/400");
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Model객체가 url에 쿼리스트링으로 보여지는게 아니였나요?
이 매핑 컨트롤러 테스트 할때 url에localhost:8080/..?param1=data1¶m2=data2이렇게 나올 줄 알았는데 쿼리스트링엔 생략되서 나오더라고요?..그래서 아래와 같이 테스트하니 url에 파라미터 가 추가 되는걸 확인할 수 있었습니다. 원래 Model 객체는 url에 쿼리스트링 추가해주는것이 아니였나요? 지금까지 그렇게 알고 있었는데 막상 테스트해보니RedirectAttributes객체만 되는것 같네요
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
sendError부분과 setStatus이 차이가 아직 잘이해가 되지않습니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]@Slf4j public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try{ if(ex instanceof IllegalArgumentException){ log.info("IllegalArgumentException resolver to 400"); response.sendError(HttpServletResponse.SC_BAD_REQUEST,ex.getMessage()); ModelAndView mv=new ModelAndView("test"); System.out.println(mv.getViewName()); mv.addObject("message","안녕하세요"); return mv; } }catch (IOException e){ log.error("reslover ex",e); } return null; } }해당 부분에 대해서 궁금한점이 생겨 질문드립니다.sendError같은경우에는 setStatus와는 다르게 제가 이해하기로는 ModelAndView가 있더라도ModelAndView mv=new ModelAndView("test");1.톰캣(WAS)에 에러가 발생했다는것을 알려주고 또한 톰캣은 해당에러를보고 BasicErrorController로 설정한 뷰를 보여주기떄문에 제가설정한 "test"뷰는 무시되고 retrun되는게 맞나요?2.그리고 또궁금한게 해당 부분이 만약에 맞다고 하면 mv.addObject("message","안녕하세요");제가 만든 "test"라는 ModelAndView객체에 모델 데이터를 담았기떄문에 BasicErrorController설정된 뷰화면에 모델데이터가 넘어가지않아야 정상으로 생각이 되는데 BasicErrorController의 뷰에도 해당 모델데이터가 넘어가는데 이유가 뭔지 궁금합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
typemismatch
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. @PostMapping("/add") public String addItemV4(@ModelAttribute Item item, BindingResult bindingResult , RedirectAttributes redirectAttributes, Model model) { //파라미터 순서 중요 /* ValidationUtils.rejectIfEmptyOrWhitespace(bindingResult, "itemName", "required");*/ //검증로직 if (bindingResult.hasErrors()) { log.info("errors={}", bindingResult); return "validation/v2/addForm"; } log.info("objectName={}", bindingResult.getObjectName()); log.info("target={}", bindingResult.getTarget()); if (!StringUtils.hasText(item.getItemName())) { /* errors.put("itemName", "상품이름값은 필수입니다.");*//* /* bindingResult.addError(new FieldError("item", "itemName",item.getItemName(),false,new String[]{"required.item.itemName"},null, "상품이름은 필수입니다")); */ bindingResult.rejectValue("item", "required"); } if (item.getPrice() == null || item.getPrice() > 1000000 || item.getPrice() < 1000) { /* errors.put("price", "가격은 1000부터 100000까지만 입력하세요");*/ /* bindingResult.addError(new FieldError("item", "price",item.getPrice(),false,new String[]{"range.item.price"},new Object[]{100,1000000}, "가격은 1000부터 100000까지만 입력하세요")); */ bindingResult.rejectValue("price", "range", new Object[]{1000, 10000000}, null); } if (item.getQuantity() == null || item.getQuantity() >= 9999) { /* errors.put("quantity", "수량은 9999이하만 입력가능합니다");*/ /* bindingResult.addError(new FieldError("item", "quantity",item.getQuantity(),false,new String[]{"max.item.quantity"},new Object[]{9999}, "상품이름은 필수입니다")); */ bindingResult.rejectValue("quantity", "max", new Object[]{9999}, null); } //특정 필드가 아닌 복합 필드 값 검증 if (item.getPrice() != null && item.getQuantity() != null) { int resultPrice = item.getPrice() * item.getQuantity(); if (resultPrice < 10000) { /*errors.put("globalErrors", "수량과 값의 합이 10000이상 이어야합니다. 현재 값은 = " + resultPrice);*/ /* bindingResult.addError(new ObjectError("item",new String[]{"totalPriceMin"},null, "수량과 값의 합이 10000이상 이어야합니다. 현재 값은 = " + resultPrice)); */ bindingResult.reject("totalPriceMin", new Object[]{10000, resultPrice}, null); } }#required.item.itemName=상품 이름은 필수입니다. #range.item.price=가격은 {0} ~ {1} 까지 허용합니다. #max.item.quantity=수량은 최대 {0} 까지 허용합니다. #totalPriceMin=가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1} #==ObjectError== #Level1 totalPriceMin.item=상품의 가격 * 수량의 합은 {0}원 이상이어야 합니다. 현재 값 = {1} #Level2 - 생략 totalPriceMin=전체 가격은 {0}원 이상이어야 합니다. 현재 값 = {1} #==FieldError== #Level1 required.item.itemName=상품 이름은 필수입니다. range.item.price=가격은 {0} ~ {1} 까지 허용합니다. max.item.quantity=수량은 최대 {0} 까지 허용합니다. #Level2 - 생략 #Level3 required.java.lang.String = 필수 문자입니다. required.java.lang.Integer = 필수 숫자입니다. min.java.lang.String = {0} 이상의 문자를 입력해주세요. min.java.lang.Integer = {0} 이상의 숫자를 입력해주세요. range.java.lang.String = {0} ~ {1} 까지의 문자를 입력해주세요. range.java.lang.Integer = {0} ~ {1} 까지의 숫자를 입력해주세요. max.java.lang.String = {0} 까지의 문자를 허용합니다. max.java.lang.Integer = {0} 까지의 숫자를 허용합니다. #Level4 required = 필수 값 입니다. min= {0} 이상이어야 합니다. range= {0} ~ {1} 범위를 허용합니다. max= {0} 까지 허용합니다. typeMismatch.java.lang.Integer=숫자를 입력해주세요. typeMismatch=타입 오류입니다.이렇게 따라했는데이런식으로 가격에 오류코드가 안뜨고 화이트라벨오류가 뜹니다 뭐가 문제인가요??타입미스매치를 에러프로퍼티에 명시해놨는데도 안됩니다ㅠ
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
HandlerExceptionResolver부분에 대해서 질문이있습니다.
[질문 내용]HandlerExceptionResolver시작 17:23초 경 @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try{ if(ex instanceof IllegalArgumentException){ log.info("IllegalArgumentException resolver to 400"); response.sendError(HttpServletResponse.SC_BAD_REQUEST,ex.getMessage()); return new ModelAndView("test"); } }catch (IOException e){ log.error("reslover ex",e); } return null;해당 부분에서 IllegalArgumentException발생되면ModelAndView를 동작시킨다고 하셨는데 response.sendError인해서 400에러가 was까지 전달된후 다시 was는 해당 Error를 읽고 다시 BasicErrorController로 설정된 값이 return 되기때문에 우리가 ModelAndView부분은 sendError로 인해서 반환이 못되는 상태가 아닌가요??제가 잘못 이해했나해서 질문드립니다!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
AJAX통신
안녕하세요, 김영한 강사님!ajax 통신 관련 강의도 들어야 한다고 생각하는데요!혹시 강사님 강의중에 프론트단과 데이터 통신을 하는 부분의 강의나 ajax 관련강의가 있을까요?ajax 를 몰라서요!강의 목차를 여러개의 강의를 들어가봐서 확인을 해봤더니 ajax 와 관련된 강의를 찾지 못해서요 😃있다면 어느 강의인지 말씀해주시면 감사하겠습니닿ㅎ 백엔드 부분도 ajax 알아야하는것 맞죠?!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
AI 답변에 대한 재문의
아!.. 제가 궁금한것은/addForm()에서 생성된 빈 객체가1. addITem 메소드 호출시 바인딩 되는 객체와 동일한 객체인지 와editForm 메소드에서 findById 로 찾는 객체와같은 객체인지 궁금합니다!또한,Item 객체가 단순히 자바빈으로 등록되어있는것이지, 싱글톤은 아니죠?( 꼬리에 꼬리를 무는생각으로 이어진고민입니다.).aI 답변을 받았는데 아직 이해가 잘 가지 않아서 재질문 드립니다!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
postmapping 에서의 모델바인딩 객체
폼에서 작성한 데이터들이 @PostMapping("/add)로 넘어가서 @ModelAttribute 를 통해 item 객체에요청 파라미터를 프로퍼티 접근법으로 값을 세팅하고 모델에 item 객체를 item 의 이름으로 바인딩 되는것이 맞죠?맞다면, @ModelAttribute 를 통해 바인딩 되는 객체는addForm 메소드에서 만들어주어서 타임리프에 활용가능하게 넘겨주었던 그 item 객체인가요?(같은 객체를 재사용하는건지) ,아니면 새로운 객체를 또 만들어서 새로운객체에 값을 세팅해주고 모델에 바인딩을 해주는것인지 궁금합니다 수정폼에서 Item item = itemRepository.findById(itemId); 에서 찾는 item (entity?) 도 addForm 에서 새로 생성했던던 그 객체인것이죠?