묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:field에 대해서
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요 <!-- radio button --> <div> <div>상품 종류</div> <div th:each="type : ${itemTypes}" class="form-check form-check-inline"> <input type="radio" th:field="${item.itemType}" th:value="${type.name()}" class="form-check-input" disabled> <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label"> BOOK </label> </div> </div> <!-- radio button --> <div> <div>상품 종류</div> <div th:each="type : ${itemTypes}" class="form-check form-check-inline"> <input type="radio" th:field="${type}" th:value="${type.name()}" class="form-check-input" disabled> <label th:for="${#ids.prev('type')}" th:text="${type.description}" class="form-check-label"> BOOK </label> </div> </div>첫 번째 코드는 원래 코드이고 두번째 코드는 제가 살짝 수정한 코드입니다. th:field="${type}""${#ids.prev('type')}"위의 두 부분을 원래 item.itemType->type'itemType'->type으로 수정해주었습니다. item.itemType이 가르키는 것과 type이 가르키는 것이 같으므로 같다고 생각했습니다.제가 수정한 코드는 왜 틀린것인가요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
HelloSpringApplication.main() 빌드 과정이 끝나지 않습니다.
HelloSpringApplication에서 main 메서드를 실행시키면아래 캡처 화면과 같이 Spring은 정상적으로 뜨는데빌드 과정(로딩 중 아이콘이 계속 뜸)이 끝나지 않습니다.강의 듣는데 크게 문제되지는 않지만계속 신경이 쓰여 글 남겨봅니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
순수 JDBC 강의 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.데이터베이스(H2) 연동을 하고 데이터를 추가해 보았는데(thymeleaf view template에서 데이터 넣고 엔터) 다음과 같은 에러가 나옵니다.org.h2.mvstore.MVStoreException: The file is locked: C:/Users/user/test.mv.db [2.2.224/7]at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:996) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.SingleFileStore.lockFileChannel(SingleFileStore.java:143) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:117) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.SingleFileStore.open(SingleFileStore.java:81) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.MVStore.<init>(MVStore.java:286) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.MVStore$Builder.open(MVStore.java:2035) ~[h2-2.2.224.jar:2.2.224]at org.h2.mvstore.db.Store.<init>(Store.java:133) ~[h2-2.2.224.jar:2.2.224]at org.h2.engine.Database.<init>(Database.java:326) ~[h2-2.2.224.jar:2.2.224]at org.h2.engine.Engine.openSession(Engine.java:92) ~[h2-2.2.224.jar:2.2.224]at org.h2.engine.Engine.openSession(Engine.java:222) ~[h2-2.2.224.jar:2.2.224]at org.h2.engine.Engine.createSession(Engine.java:201) ~[h2-2.2.224.jar:2.2.224]at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:343) ~[h2-2.2.224.jar:2.2.224]at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:125) ~[h2-2.2.224.jar:2.2.224]at org.h2.Driver.connect(Driver.java:59) ~[h2-2.2.224.jar:2.2.224]at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:120) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:360) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:202) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:461) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:550) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:98) ~[HikariCP-5.1.0.jar:na]at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:111) ~[HikariCP-5.1.0.jar:na]at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:160) ~[spring-jdbc-6.1.11.jar:6.1.11]at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:118) ~[spring-jdbc-6.1.11.jar:6.1.11]at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:81) ~[spring-jdbc-6.1.11.jar:6.1.11]at com.drycow.freeform.freeform_creator.repository.JdbcTodoRepository.getConnection(JdbcTodoRepository.java:138) ~[classes/:na]at com.drycow.freeform.freeform_creator.repository.JdbcTodoRepository.findByName(JdbcTodoRepository.java:116) ~[classes/:na]at com.drycow.freeform.freeform_creator.service.TodoService.validateDuplicateTodo(TodoService.java:32) ~[classes/:na]at com.drycow.freeform.freeform_creator.service.TodoService.create(TodoService.java:25) ~[classes/:na]at com.drycow.freeform.freeform_creator.controller.TodoController.create(TodoController.java:37) ~[classes/:na]at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.11.jar:6.1.11]at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.11.jar:6.1.11]at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.11.jar:6.1.11]at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.11.jar:6.1.11]at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.11.jar:6.1.11]at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.11.jar:6.1.11]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.11.jar:6.1.11]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.11.jar:6.1.11]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.11.jar:6.1.11]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.11.jar:6.1.11]at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.11.jar:6.1.11]at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.26.jar:10.1.26]at java.base/java.lang.Thread.run(Thread.java:1570) ~[na:na] **위 에러를 해결해보자 jdbc URL을 jdbc:h2:tcp://localhost~/test 로 변경해주면 다음과 같은 에러가 나옵니다.Connection is broken: "java.net.UnknownHostException:2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
멀티 체크 박스에서의 th:value
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요 <!-- multi checkbox --> <div> <div>등록 지역</div> <div th:each="region : ${regions}" class="form-check form-check-inline"> <input type="checkbox" th:field="*{regions}" th:value="${region.key}" class="form-check-input"> <label th:for="${#ids.prev('regions')}" th:text="${region.value}" class="form-check-label">서울</label> </div> </div>위의 코드는 addForm.html에 있는 멀티 체크박스 관련 코드입니다.저는 위의 코드 중th:value="${region.key}" 부분이 없어도 동작할거라고 예상했는데 오류페이지가 나더라구요. 적어도 editForm.html, item.html 같은 경우는 위의 코드를 사용함으로써 checkbox에 체크를 할 지 말 지를 정하므로 납득이 되는데 addForm.html같은 경우는 아직 아무것도 선택되지 않은 상태이므로 굳이 위의 코드를 넣어야 하나라는 의문이 들어 질문 드려 봅니다,
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
localhost8080/index 페이지 404오류 뜹니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
테스트 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. > Task :compileJava UP-TO-DATE> Task :processResources UP-TO-DATE> Task :classes UP-TO-DATE> Task :compileTestJava> Task :processTestResources NO-SOURCE> Task :testClasses> Task :testNov 23, 2024 12:22:03 PM org.junit.platform.launcher.core.EngineDiscoveryOrchestrator lambda$logTestDescriptorExclusionReasons$7INFO: 0 containers and 4 tests were Method or class mismatchresult = Member(id=null, loginId=null, name=null, password=null)expired = nullBUILD SUCCESSFUL in 694ms4 actionable tasks: 2 executed, 2 up-to-date12:22:03: Execution finished ':test --tests "hello.login.web.session.SessionManagerTest.sessionTest"'. 이렇게 에러가 나와서 build에서 gradle → IntelliJ IDEA로 바꾸니깐 됐어요
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
save()메소드의 리턴값에 대해서
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요! 강의 정말 잘 듣고 있습니다.MemoryMemberRepository클래스의 save() 메소드에 대해서 궁금한게 있습니다. @Override public Member save(Member member) { member.setId(++sequence); store.put(member.getId(), member); return member; }여기서 리턴값에 멤버를 그대로 반환하는데요, 이러면 외부에서 member값을 변형할 수 있고 그 변형이 DB에 저장된 값에도 영향을 미치는 위험이 있지 않나 해서요.return new Member(member); 이런식으로 하는게 더 나은 방법이 아닌가 싶어서 여쭤봅니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HandlerAapter가 어떻게 각 메서드를 실행할 수 있는가?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요. 저와 비슷한 질문이 있어서https://www.inflearn.com/questions/1292736이 글을 보았는데요, 이 글을 읽고 핸들러 매핑하는 과정까지는 잘 이해했다고 생각하고 있습니다. package hello.servlet.web.springmvc.v3; import hello.servlet.domain.member.Member; import hello.servlet.domain.member.MemberRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @Controller @RequestMapping("/springmvc/v3/members") public class SpringMemberControllerV3 { private MemberRepository memberRepository = MemberRepository.getInstance(); @GetMapping("/new-form") public String newForm() { return "new-form"; } @PostMapping("/save") public String save(@RequestParam("username") String username, @RequestParam("age") int age, Model model) { Member member = new Member(username, age); memberRepository.save(member); model.addAttribute("member", member); return "save-result"; } @GetMapping public String members(Model model) { List<Member> members = memberRepository.findAll(); model.addAttribute("members", members); return "members"; } } <이해된 부분>SpringMemberControllerV3 클래스의 메서드들은 RequestMappingHandlerMapping에 의해 매핑되고, 이들을 실행하기 위해 RequestMappingHandlerAdapter가 사용됩니다.따라서, 핸들러(메서드, 컨트롤러)는 SpringMemberControllerV3 클래스이고, 이 클래스의 메서드가 핸들러 메서드입니다. 핸들러 어댑터는 RequestMappingHandlerAdapter가 됩니다.=============================<이해되지 않은 부분> 디스패처 서블릿은 요청이 들어올 때 이 매핑된 정보들을 활용하여 핸들러와 핸들러 어댑터를 찾고, 이를 통해 요청을 처리합니다.============================/springmvc/v3/members 요청이 들어왔을 때 RequestMappingHandlerMapping에 의해 매핑이 되고, 이들을 실행하기 위해서 RequestMappingHandlerAdapter가 실행이 되어야 하는데 프레임워크의 생명주기처럼 자동으로 실행이 되는건가요..? (눈에 보이지 않아서 잘 모르겠습니다 ㅠㅠ 이전 강의처럼 인터페이스를 구현한것도 아니기 때문입니다..!)예전 예시에서는 Controller 인터페이스를 구현하면 구현한 메서드를 호출하는 과정이 이해가 되었는데,지금은 보다시피 개발자가 원하는 대로 메서드명을 마음대로 지정할 수 있기 때문에, 이게 어떻게 스프링에서 가능한것인지 잘 이해하지 못하겠습니다..!예전 예시에서는 오버라이딩을 하기때문에, 당연히 오버라이딩이 된 것이 호출되겠구나! 했는데,save나 members와 같이 개발자가 마음대로 정한 메서드이름을 어떻게 알고 딱딱 실행을 하는지.. 잘 모르겠습니다 ㅠㅠ================정리핸들러 매핑을 하고, 어댑터 목록에서 RequestMappingHandlerAdapter를 호출하는 것까지는 이해완료.이 어뎁터가 어떻게 각 메서드를 호출하는지 이해하지 못하는 상황(메서드이름은 마음대로 바뀔 수 있기 때문에)스프링 MVC 전체 구조 그림으로 봤을 때, 사용자가 요청을 하게된다면 @RequestMapping(@Controoler)에 정한 URL에따라 핸들러 매핑, 핸들러 어댑터 목록을 가져오고 해당 메서드를 실행한다고 한다면, RequestMappingHandlerAdapter가 자동으로 어댑터로 지정이 되고 해당 메서드가 실행이 되면 이 메서드가 핸들러(컨드롤러)가 되는것이 맞는지 궁금합니다 !
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
spring initializr 시 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 강의와 똑같이 spring generate했는데 오류가 나네요
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@Validated 클래스레벨에 사용가능한지 궁금합니다.
안녕하세요. 강의에서 Item클래스에 @NotNull, @NotBlank등과 같은 유효성검사 어노테이션을 인스턴스필드레벨에 추가해줬습니다. 이 어노테이션이 제 역할을 하려면 위 그림과 같이 controller파라미터에 @Validated 어노테이션을 추가해줘야하는데요. 차라리 Item클래스측 클래스레벨에 @Validated어노테이션을 달아주는 것은 어떨까 생각이 들었습니다.controlller에서 @Validated를 까먹고 못넣어줄 수 도 있기 때문에 @NotNull, @NotBlank를 고려할 때 Item에서 @Validated도 함께 작성하면 좋을것 같거든요.제 생각이 올바른지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
서블릿필터-인증체크에서 catch구문 질문
안녕하세요. 강의 '서블릿필터-인증체크' 08:25 에서 질문있습니다.질문1)@Slf4j public class LoginCheckFilter implements Filter { private static final String[] whitelist = {"/", "/members/add", "/login", "/logout", "/css/*"}; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); HttpServletResponse httpResponse = (HttpServletResponse) response; try { log.info("인증 체크 필터 시작 {}", requestURI); if (isLoginCheckPath(requestURI)) { log.info("인증 체크 로직 실행 {}", requestURI); HttpSession session = httpRequest.getSession(false); if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) { log.info("미인증 사용자 요청 {}", requestURI); httpResponse.sendRedirect("/login?redirectURL=" + requestURI); return; //여기가 중요, 미인증 사용자는 다음으로 진행하지 않고 끝! } } chain.doFilter(request, response); } catch (Exception e) { throw e; //예외 로깅 가능 하지만, 톰캣까지 예외를 보내주어야 함 } finally { log.info("인증 체크 필터 종료 {}", requestURI); } } /** * 화이트 리스트의 경우 false 즉, 인증 체크X * true시 인증 체크O */ private boolean isLoginCheckPath(String requestURI) { return !PatternMatchUtils.simpleMatch(whitelist, requestURI); } }수업에 사용된 위 코드에서 try~catch를 해줘야 한다는 것을 어떻게 인지하고 사용할 수 있는지 궁금합니다.예외처리에 무감각하게 되면 try~catch없이 개발을 할 때가 많았는데요. 지금도 마찬가지로 왜 try~catch가 필요한지 알지 못합니다. 질문2)catch구문에서 throw e; 를 하여 서블릿단에서 톰캣으로 예외를 보내줘야하는 이유도 궁금합니다.(강사님께서 이유를 말씀해주시지 않았습니다.)보통 try~catch구문을 사용하지 않으면 에러가 발생했을 때 발생한 위치에서 요청이 종료되고 500에러를 응답하는 것으로 알고있습니다.try~catch를 쓰고 catch구문에서 로그만 남기면 200정상이 될 것이지만try~catch를 쓰고 catch구문에서 톰캣에게 throw를 하게된다면 여전히 500응답합니다.위 세 케이스 중에 로그를 남길 수 있고 동시에 500에러를 클라이언트에게 보낼 수 있는 방법으로 세 번째 방식이 채택된 것인지 궁금합니다.
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
reject 메소드 시그니처가 불분명한 경우 조치방법
안녕하세요. BindingResult의 reject 메소드시그니처를 확인하려고 합니다. ctrl + 클릭으로 정의된 곳으로 이동하니 Errors 인터페이스로 이동했습니다. 이때 시그니처가 아쉽게도void reject(String errorCode, @Nullable String defaultMessage); 아니라 위 그림처럼 var1, var2로 되있습니다. 강사님께서 강의하실 땐 전자처럼 파라미터변수명이 ctrl + p로 확인할 수 있었던것 같습니다.저도 동일한 환경을 만들고 싶은데요. 유용한 방법이 있는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
value의 값
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/)[질문 내용]여기에 질문 내용을 남겨주세요.판매 여부를 체크하지 않았는데, 크롬 '소스보기'에서 확인해보면<input type="checkbox" id="open" class="form-check" name="open" value="true"><input type="hidden" name="_open" value="on"/>과 같이 value="true"가 나옵니다. value의 값이 true이면 타임리프 속성(th:field를 사용하면, 값이 true인 경우 체크를 자동으로 처리)으로 체크가 되어야 하는 것과도 좀 충돌하는 것 같습니다. 체크를 하지 않았는데 value의 값은 true이고, 정작 타임리프는 true일 경우 자동으로 체크처리해야하는데 화면에는 체크처리가 되지 않아있고... 어디서 잘못 생각한 것일까요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
DTO 질문 있습니다.
안녕하세요컨트롤러마다 필요한 Request 값과 Response 값이 다를 거 같은데 그러면 컨트롤러 하나 마다 Reqeust, Response를 위한 DTO를 다 만들어서 사용하나요??
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
@Transactional이 어디에 적용되어 있는지 스프링은 매번 조사하는 건가요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]@Transactional 적용 우선순위가 1. 클래스의 메서드2. 클래스의 타입 3. 인터페이스의 메서드 4. 인터페이스의 타입 이 순서라고 하셨으니 클래스의 메서드에 @Transactional이 없으면 클래스의 타입을 확인하고, 그래도 없으면 인터페이스의 메서드를 확인하고, 그래도 없으면 인터페이스의 타입에 @Transactional이 있는지 없는지 확인하는 거로 이해했는데 스프링 프레임워크를 사용하면 이를 항상 적용하나요?이전에 스프링 핵심 원리 기본 편, MVC 1, 2 강의에서 작성한 코드들엔 @Transactional을 적용하지 않았었는데, @Transactional이 코드 어디에도 없더라도 매번 스프링이 이렇게 @Transactional이 어디에 있는지 조사하나요?
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
members.jsp 가 white error 뜹니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]jsp 를 사용하여 회원 가입까지는 했는데, 회원 목록 조회가 안 됩니다. 강의 내용 따라서 작성해보았는데 안 돼서 자료에 있는 코드도 복붙했는데 안 되네요ㅜㅜ순서대로 에러 페이지, members.jsp , 폴더 구조입니다.아래는 제 프젝 올려놓은 링크입니다.https://drive.google.com/file/d/1CusOmnzhU0t4lSSS2OhY4Cn1fn2uAqQF/view?usp=sharing
-
미해결스프링 프레임워크는 내 손에 [스프1탄]
lombok api 등록 후
lombok을 임포트시키고 나서 아웃라인에 변화가 일어나지 않습니다.이런 경고메시지도 떴는데 뭐가 잘못된 걸까요..?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
질문이 많은데.. th:object 마지막 질문입니다..
th:object=${item}th:field=*{itemName}이런식으로 사용하고, 만약 폼에서 itemName으로 test를 입력했다면item.setItemName(test) 이렇게 세팅되고 이 item객체가 Controller에 넘어가는 줄 알았는데이렇게 동작하는게 아니라일반적인 폼 데이터 전송처럼 쿼리 파라미터 형식으로 입력 데이터가 전달 되지만th:object, th:field를 사용하면 객체의 필드 이름들과 폼 데이터 전송 시 쿼리 파라미터의 이름을 쉽게 맞출 수 있기 때문에 사용한다고 생각했는데맞을까요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
테스트 코드를 위한 @Builder, 생성자
안녕하세요api 에서 request 를 받는 경우 getter 만 열어두고 사용하는 경우가 있는데요,이런 경우엔 request dto에 테스트 코드를 위한 생성자나 builder를 추가해주는게 맞을까요?테스트 코드를 짜기 위해 실제 코드를 수정하는 부분이 찝찝해 질문드립니다
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:object
폼 페이지에서<form th:object=${item} > <input th:field=*{itemName} >이런식으로 th:object, th:field를 사용하면item객체에 입력한 itemName이 세팅돼서 item 객체가 다시 컨트롤러로 전달되는 줄 알았는데그냥 일반 폼 데이터를 입력받을 때 처럼 쿼리 파라미터가 전달되는 것을 확인했습니다.굳이 th:object를 써서 객체를 전달받을 필요가 있나요??