학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 강의를 듣다가 순간 애매해서 질문드립니다. V2config에서 해당 코드를 @Bean public ItemService itemService() { return new ItemServiceV2(itemRepositoryV2, itemQueryRepositoryV2()); } @Bean public ItemQueryRepositoryV2 itemQueryRepositoryV2(){ return new ItemQueryRepositoryV2(em); } @Bean public ItemService itemService() { return new ItemServiceV2(itemRepositoryV2, new ItemQueryRepositoryV2(em)); } /** @Bean public ItemQueryRepositoryV2 itemQueryRepositoryV2(){ return new ItemQueryRepositoryV2(em); } **/ 처럼 ItemQueryRepositoryV2부분은 주석처리 해서 @Bean으로 등록을 하지 않으면 작동이 안돼야 할까요?? 변경하고 작동해봤는데 문제가 없어서 질문드립니다.
JSON 요청 시, 타입을 맞지 않게 입력하게 되면, 컨트롤러 자체가 아예 호출되지 않는 것을 강의를 통해 확인했습니다. Post 폼 요청 시, 이런 타입에 대한 올바르지 않은 입력을 하게 되어도, 컨트롤러가 호출되고 검증 단계까지 도달할 수 있는 이유가 스프링 프레임워크가 자동으로 타입을 적절하게 형변환 해주기 때문인가요? 이유가 궁금합니다!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 강의 잘 보고 있습니다. 한 가지 궁금한 점이 생겼는데 바로 직전 강의에서는 똑같이 HandlerExceptionResolver를 아래와 같이 사용했는데 서블릿 컨테이너까지 에러를 전달해서 서블릿 컨테이너가 다시 서버 내부에서 BasicErrorController로 재요청하는 방식으로 이루어진 것 같은데, 왜 여기서는 HandlerException 에서 처리가 마무리 되었는지 헷갈립니다. 제가 생각하기에는 response.sendError 때문에 이전 강의에서는 서블릿 컨테이너까지 에러가 갔다가 다시 재요청을 한 것이고, 이번에는 response.sendError를 쓰지 않았기 때문에 HandlerExceptionResolver에서 마무리가 된 것 같은데 이게 맞나요?? 이전 강의와 현재 강의의 코드 비교 입니다. 이전 강의 코드 package hello.exception.resolver; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; @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()); return new ModelAndView(); } } catch (Exception e) { log.error("resolver ex", e); } return null; } } 현재 강의 코드 package hello.exception.resolver; import com.fasterxml.jackson.databind.ObjectMapper; import hello.exception.exception.UserException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import java.util.HashMap; import java.util.Map; @Slf4j public class UserHandlerExceptionResolver implements HandlerExceptionResolver { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { try { if (ex instanceof UserException) { log.info("UserException resolver to 400"); String acceptHeader = request.getHeader("accept"); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); if ("application/json".equals(acceptHeader)) { Map<String, Object> errorResult = new HashMap<>(); errorResult.put("ex", ex.getClass()); errorResult.put("message", ex.getMessage()); String result = objectMapper.writeValueAsString(errorResult); response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); response.getWriter().write(result); return new ModelAndView(); } else { // TEXT/HTML return new ModelAndView("error/400"); } } } catch (Exception e) { log.error("resolver ex", e); } return null; } }
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 강의를 듣는데 ErrorPageController의 request.getAttribute(ERROR_EXCEPTION); request.getAttribute(ERROR_STATUS_CODE); 사용이 궁금합니다. request에 setAttribute로 넣어준 값이 없는데 어떻게해서 저렇게 작동하는 것인지 잘 모르곘습니다. 얼핏 기억나는 내용으론 이전 강의 8장에서 디스패처 서블릿이 에러 내용을 넣어준다고 했던거 같은데 그게 맞나요? 맞다면 복습을 하고 싶은데 혹시 어떤 파트를 다시 보면 될지 알려주시면 감사하겠습니다.
@PathVariable 어노테이션 사용 시 위와 같이 GetMapping의 {userId} 와 변수 명이 같으면 name="userId" 옵션을 생략해도 된다고 말씀해주셨는데 옵션을 생략하면 500 에러가 나고, 옵션을 작성해주면 성공하는데 이런 경우에는 뭐가 문제인가요?
강의록을 보면 이전의 MemberFormServlet 코드에서는 응답 메시지 상단에 <!DOCTYPE HTML>을 명시해주었는데, 왜 이번 jsp에서는 html 태그 위에 <!DOCTYPE HTML>를 명시해주지 않아도 정상적으로 동작하나요? https://developer.mozilla.org/en-US/docs/Web/HTML/Quirks_Mode_and_Standards_Mode 위에서 <!DOCTYPE HTML>는 브라우저한테 어떤 document 타입을 사용하는지를 알려주기 위해 반드시 최상단에 명시해야 한다고 되어 있습니다. 만약 이것을 명시하지 않으면 quirk mode로 동작이 되서 현재 널리 채택된 full-standard mode와 다르게 렌더링될 수 있다고 되어있습니다.
@Configuration @RequiredArgsConstructor public class WebMvcConfig implements WebMvcConfigurer { private final AppConfig appConfig; @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new AuthResolver(appConfig)); } } 안녕하세요 제가 지금 프로젝트를 하나 하고있는데요 이 코드에서 resolver.add()를 하면 어떻게 되는건지 궁금합니다. AuthResolver에 대한 의존성을 추가해주는 코드인가요? resolvers.add()의 동작방식이 궁금합니다. 그리고 resolver의 정확한 의미가 뭔지 궁금합니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 선생님, 스프링을 통해서 제가 생각한 대로 설계해서 잘 만드는 백엔드 개발자가 꿈인 사람입니다. 앞부분에는 천천히 강의 설명을 잘 해주셔서 이상없이 잘 따라왔는데요. 순수 jdbc 강의부터 복사 붙여넣기로 강의 속도가 빨라지면서 낯선 메소드와 코드들이 보여서 이해가 안가고 있습니다. 실무에서 쓰는데 순수 jdbc 원리는 꼭 깊이 있게 짚고 나가지 않아도 될까요? 어렵습니다ㅠㅠ 게다가 SpringConfig에서 JdbcMemberRepository로 바꾸면서 db접근도 안되고 화이트라벨 에러만 계속 발생하고 있습니다..ㅠ chatgpt에 물어보고 검색을 해도 이 문제를 도저히 해결할 수가 없네요.. [에러 내용] java.lang.IllegalArgumentException: No DataSource specified 윈도우에서 사용하고 있으며, 스프링부트 버전은 3.x h2 데이터베이스도 최신버전으로 설치해서 실행했습니다. [구글 드라이브] https://drive.google.com/file/d/1HzXNwnwBzOTJIvrzJZisrvoO2LkbYIDI/view?usp=sharing
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. API 강의에서 @ResponseBody를 이용해 JSON 으로 객체를 변환받는 내용의 코드에서 name이 너무많아 반환받는 JSON 키를 "name2"로 변경해보고싶어 코드와 url등등 name2를 넣어 계속 실행해봣지만 계속 키는 "name"에서 변하지가 않습니다. 어디를 변경해야 하는걸까요??
섹션4_Model추가 V3 강의 내용 중 FrontControllerServletV3 클레스 에서 해당 render 메서드의 파라미터 mv.getModel()에는 createParamMap 메서드에서 만들어진 paramMap? 즉 key, value로 생성된 모든 request 값이 들어가고, view.render(mv.getModel(), request, response); 메서드 내부에 modelToRequestAttribute 메서드는 위에서 넘겨준 paramMap을 다시 request에 새팅해주는게 맞나요? 어질 어질 하네요.. ㅜㅜ
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용]HttpSession에 관해서 공부한 내용을 정리해보았는데 한번 피드백해주시면 감사하겠습니다 1. 정리한 부분 getSession()을 통해 이미 생성되어있는 세션 저장소에 할당할 HttpSession 빈 세션 객체 하나를 생성 후 반환 getSession()을 통해 생성된 HttpSession 빈 세션 객체에 setAttribute()를 통하여 map 형태의 세션 정보를 저장할 수 있다. 이때 세션 정보는 (세션 이름 , 회원 정보) 로 형태로 저장되고 이 순간 해당 세션을 식별하기 위한 세션id는 톰캣에서 자동으로 생성해줌 따라서 getSession()을 통해 세션 저장소에 저장될 한 세션 객체 HttpSession의 형태를 굳이 표현해보자면 (sessiondId , Map<String , Object>)이고 , 거기다가 setAttribute()를 통해 “세션 이름”과 “회원 정보”를 지정해서 저장하면 (UD3R9A33 , (“loginMember” , member)) 형태로 저장됨 그럼 이 순간 톰캣 서버가 자동으로 Set-Cookie: JSESSIONID=UD3R9A33를 지정해서 클라이언트에 전달함 그에 따라 서버와 클라이언트 간 쿠키를 통해 자동 지정된 세션id를 통해 사용자 여부를 식별할 수 있는 것 이렇게 이해하면 될까요? 2. 추가 질문 사항 세션 저장소의 한 공간을 차지하는 한 세션 객체 HttpSession에 setAttribute()를 여러 개 호출할 수 있는데 이는 한 HttpSession 공간에서 또 여러 개의 세션 정보를 가질 수 있다고 이해하면 될까요? 만약 이가 맞다면 getSession()을 통해 여러 개의 HttpSession을 생성하는 것과 setAttribute()를 통해 한 HttpSession 안에서 여러 개의 세션을 생성하는 것의 차이가 궁금합니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) YES 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) YES 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) YES [질문 내용] 여기에 질문 내용을 남겨주세요. 질문 주제 : Optional 에 대해상세 내용 : MemberService 의 조회용 메서드에서 단일 객체를 조회할 경우, 반환 타입을 Optional<Member> 로 정의하지만, List 등의 컬렉션에서는 Optional<List<Member>>을 사용하지 않고 List<Member> 이유가 궁금합니다. List에 담을 값이 없어도 List라는 객체가 반환되기 때문(null이 아니기 때문)에 괜찮은 걸까요? list.empty() 라는 메서드를 통해 조회 요청에 대해 반환할 객체가 없음을 알 수 있고, 이에 따른 후처리를 할 수 있기 때문인가요?