묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
V2 HandlerAdapter 적용하기
안녕하세요. 수업을 듣다가 V2 또한 Adapter 로 만들어 보려고 하였습니다. 김영한님이 V2 를 적용하려면 아마 FrontController 도 건드려야 할 거라고 하셨는데, ControllerV2HandlerAdapter도 MyHandlerAdapter 인터페이스를 구현하니 어떻게든 ModelView 를 리턴하게 만들 수밖에 없더라고요. (잠깐 디폴트 메소드 써볼까 했는데…어차피 추상메소드는 구현해야하니까 그것도 안되더라고요 ㅜㅜ) 그래서 차라리 ControllerV2HandlerAdapter로 ModelView 를 구현하게 만들었는데, public class ControllerV2HandlerAdapter implements MyHandlerAdapter { @Override public boolean supports(Object handler) { return (handler instanceof ControllerV2); } @Override public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { ControllerV2 controller = (ControllerV2) handler; MyView view = controller.process(request, response); String viewPath = view.getViewPath(); // 모델뷰 만들기 String viewName = parsingViewName(viewPath); ModelView mv = new ModelView(viewName); // 모델뷰에 모델 넣기 Map<String, Object> model = new HashMap<>(); request.getAttributeNames().asIterator() .forEachRemaining(attributeName -> model.put(attributeName, request.getAttribute(attributeName))); mv.setModel(model); return mv; } private String parsingViewName(String viewPath) { String[] splitList = viewPath.split("/"); int lastIndex = splitList.length - 1; String viewNameWithJSP = splitList[lastIndex]; String[] splitJSP = viewNameWithJSP.split("[.]"); String viewName = splitJSP[0]; return viewName;} 작동은 잘 되는데, 저 parsingViewName 메소드로 너무 억지로 ModelView로 반환하려는 느낌이 들어서… 조금 아쉽습니다. FrontController 에서 쉽게 바꿀 수 있는 아이디어가 있을까요? 아직 저는 구현 Adapter들이 MyHandlerAdapter 를 구현하는 것 때문에 FrontController 에서는 어떻게 바꿔야할지 모르겠습니다. 또 한편으로 Adapter의 역할이 말 그대로 110V 이나 50V 뭐든 220V 으로 맞춰주는 거라고 생각한다면, ControllerV2HandlerAdapter 에서 억지로라도 ModelView 로 반환해주는 것이 맞는 것 같다는 생각도 듭니다. 그래서, 만약 FrontController 와 구현 Adapter 중 하나를 수정해야한다면 무엇을 수정하는 것이 더 효율적인가요?(유지보수면에서요!)
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
세션 관련 질문이 있습니다.
기존에 직접 sessionManager를 만들어서 세션을 관리하는 것에 있어서는 sessionStore라는 맵에 key값으로 sessionId와 value값으로는 loginMember를 넣어서 사용을 하고 sessionId를 가지고 사용자를 식별하여 사용한 것으로 이해했습니다. 맞나요? 그런데 session.setAttribute함수를 찾아보니 attributes라는 map에 key값으로 상수값을 value값으로 loginMember를 넣는 거 같은데 (attributes.put(name, value)이렇게 있더라고요) 그럼 map에 키값이 동일하게 지정을 해주면 다른 사용자에 대해서는 어떻게 식별을 하나요? 관리자모드로 보면 sessionId가 생기긴 하는데 이건 spring에서 생성을 해주는 것이 아닌가요? 제가 못찾은 것인지 어느 코드가 id를 생성하는지를 모르겠어어요... 아 그리고 logout에서는 v2를 보면 expire를 통해서 해당 id값에 대한 member를 지우도록 했는데 session을 사용하면서 invalidate함수를 통해 session을 지우면 session전체가 다 지워지는 건가요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
사소한 오타를 발견하여 말씀드립니다!
강의 대시보드의 강의자료는 버전 수정이력이 v2021-12-01로 되어있지만 PDF파일 다운받을 시 v 2022-12-01로 오타가 있습니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
프로젝트 생성 후 build.gradle Open as Project 시 에러
환경 OS : Mac M1 Pro macOS Monterey Version 12.1 Intellij : Intellij IDEA 2021.3.1(Ultimate Edition) Build #IU-213.6461.79, built on December 29, 2021 Java Version : openjdk version "11.0.11" 2021-04-20 오류 메시지 Could not load wrapper properties from '{프로젝트 경로}/{프로젝트 명}/gradle/wrapper/gradle-wrapper.properties'. 현상 start.spring.io에서 [프로젝트 환경설정] - [프로젝트 생성] 후 Intellij에서 Open을 통해 프로젝트의 build.gradle Open - 오픈 -> 오픈시 Open as Project를 클릭 Window 10에서는 별다른 설정 없이 Gradle에서 라이브러리를 정상적으로 다운 하였으나, Mac에서는 Build 에러 발생(오류 메시지 참조) 해결을 위한 진행 사항 1. 'Could not load wrapper properties from Intellij' 키워드로 검색결과 gradle 버전 문제로 확인되었으나, 해당 프로젝트로 Window 10환경에서 정상적으로 gradle Build되어 해당 케이스 제외 2. Intellij에서 제공하는 New Project를 사용하여 Gradle 프로젝트 Build가 성공 ※ 정상적으로 build를 성공 하였으나, 원인 확인을 위한 분석 진행 분석 사항 1. start.spring.io에서 생성한 프로젝트(이하 spring)와 Intellij에서 생성한 프로젝트(이하 Intellij)의 gradle-wrapper.properties 비교 spring의 distributionUrl : https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip Intellij의 distributionUrl : https\://services.gradle.org/distributions/gradle-7.1-bin.zip 두 설정의 gradle 버전은 각 7.3.3-bin.zip과 7.1-bin.zip으로 버전차이가 있음 Case 1. Intellij 프로젝트의 설정파일을 spring 프로젝트의 설정파일로 덮어씌웠으나 동일한 에러 발생 Case 2. spring 프로젝트의 설정파일을 Intellij 프로젝트의 설정파일로 덮어씌웠으나 정상 결과 : 설정파일 또는 버전의 문제가 아님. 2. 구글링 중 Intellij와 Gradle sync에러 관련 글 확인결과 블로거가 Intellij의 log를 확인 한것을 따라 Intellij의 로그 체크결과 권한 관련 사항이 문제 에러로그 : java.nio.file.FileSystemException: '{프로젝트 경로}/{프로젝트 명}/gradle/wrapper: Operation not permitted' [결론 및 해결 방안] 권한의 문제로 시스템 환경설정 - 보안 및 개인 정보 보호 - 전체 디스크 접근 권한 - Intellij IDEA.app 권한 부여 [질문사항] 1. 권한 허용을 하지 않아도 Intellij에서 생성된 프로젝트는 Build성공한 이유가 궁금합니다. 2. 추가로 Mac에서는 '전체 디스크 접근 권한'을 허용하고 진행하는 것인지, 혹시 환경의 문제가 있는건지 궁금합니다. 긴 질문사항 읽어주셔서 감사합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
만들지 않은 url로 접근 할 떄 처리는 어떻게 하나요 ??
만약에 /itemsed 라는 만들지도 않은 url로 접근할 경우는 어떻게 처리를 하나요 ?? 1) 로그인을 한 경우 잘못된 경로 인입 -> 에러창이 뜸 (아마도 다음 예외처리에서 해결??) 2) 로그인을 하지 않은 경우 잘못된 경로 인입 -> 로그인체크 인터셉터에서 로그인창으로 리다이렉트 -> 이 경로도 1)과 마찬가지고 에러페이지로 예외처리 하려면 addPaterns 에 /** 가 아니라 더 세밀하게 조정을 해야할까요? 아니면 다른 방법이 있을까요 ?
-
해결됨스프링 핵심 원리 - 기본편
할인 정책을 동시에 적용하고 싶은 경우 AppConfig 설정 방법
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 안녕하세요 객체지향 개발에 관심이 생겨 공부중인 개발자 입니다. 좋은 강의 잘 듣고 있습니다. 한번에 하나의 할인 정책을 적용하는 경우는 AppConfig에서 지정을 해주면 되는데 만약 동시에 두 개 이상의 할인 정책을 적용하는 경우 어떤 방법으로 구현하면 좋을지 궁금해서 질문드립니다. 1. 현재 적용하고 있는 할인 정책이 하나인 경우 아래와 같이 AppConfig에서 제어흐름을 담당하면서 어떤 할인 정책을 적용할지 결정을 한다는 점은 이해했습니다. public DiscountPolicy discountPolicy() { // return new FixDiscountPolicy(); return new RateDiscountPolicy(); } 2. 할인 정책을 모두(정액, 정률) 사용하고 싶은 경우 예를 들어 할인 정책을 적용할 수 있는 쿠폰이 정액, 정률 두 개가 동시에 존재한다고 했을 때 클라이언트의 변경 없이(OCP) 할인정책을 적용하고 싶다면 AppConfig 에서 `discountPolicy()` 메소드를 호출할 때 정률 할인 쿠폰인 경우 `new RateDiscountPolicy()`를 리턴해야하고 정액 할인 쿠폰인 경우 `new FixDiscountPolicy()`를 리턴해줘야 합니다. 2-1. AppConfig 를 인터페이스로 변경하고 구현체를 별도로 생성 public class FixDiscountAppConfig implements AppConfig { … } public class RateDiscountAppConfig implements AppConfig { … } // OrderApp AppConfig appConfig; if (“정률할인 쿠폰”) { appConfig = new RateDiscountAppConfig(); } else If (“정액할인 쿠폰”) { appConfig = new FixDiscountAppConfig(); } AppConfig appConfig = new AppConfig(); MemberService memberService = appConfig.memberService(); OrderService orderService = appConfig.orderService(); 2.2 AppConfig 내 discountPolicy 메소드 호출 시 파라미터를 넘겨 구분 public DiscountPolicy discountPolicy(String 할인정책) { if (“정액”.equals(할인정책)) { return new FixDiscountPolicy(); } else { return new RateDiscountPolicy(); } } 한번에 하나의 정책을 적용하는 것보단 동시에 여러 정책을 적용하는 경우가 더 많을 것 같다고 생각이 들었습니다. 이 경우에는 어떤 방식으로 구현하는게 좋은 객체 지향원칙을 지키며 구현하는 것일지 조언을 구하고자 합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
실행을 두번 연달아서 했더니 NoClassDefFoundError가 떴습니다.
강의내용 6:00까지 진행중이였는데 제가 실수로 Run을 두번 해버렸습니다. 그림에 빨간동그라미 표시한대로 처음은 Run탭에 초록색 화살표를 눌렀다가 두번째로 Run을 진행했더니 NoClassDefFoundError 에러가 떴습니다. 런했을 때 나오는 콘솔내용들입니다. 2022-01-22 10:52:31.818 INFO 12244 --- [ main] hello.servlet.ServletApplication : No active profile set, falling back to default profiles: default2022-01-22 10:52:32.817 WARN 12244 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletComponentRegisteringPostProcessor': Unexpected exception during bean creation; nested exception is java.lang.NoClassDefFoundError: javax/servlet/annotation/WebServlet2022-01-22 10:52:32.834 INFO 12244 --- [ main] ConditionEvaluationReportLoggingListener : Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.2022-01-22 10:52:32.878 ERROR 12244 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'servletComponentRegisteringPostProcessor': Unexpected exception during bean creation; nested exception is java.lang.NoClassDefFoundError: javax/servlet/annotation/WebServletat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:196) ~[spring-context-5.3.15.jar:5.3.15]at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.15.jar:5.3.15]at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.15.jar:5.3.15]at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.6.3.jar:2.6.3]at hello.servlet.ServletApplication.main(ServletApplication.java:12) ~[classes/:na]Caused by: java.lang.NoClassDefFoundError: javax/servlet/annotation/WebServletat org.springframework.boot.web.servlet.WebServletHandler.<init>(WebServletHandler.java:39) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.web.servlet.ServletComponentRegisteringPostProcessor.<clinit>(ServletComponentRegisteringPostProcessor.java:49) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.boot.web.servlet.ServletComponentScanRegistrar$ServletComponentRegisteringPostProcessorBeanDefinition.lambda$getInstanceSupplier$0(ServletComponentScanRegistrar.java:94) ~[spring-boot-2.6.3.jar:2.6.3]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.15.jar:5.3.15]at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.15.jar:5.3.15]... 13 common frames omittedCaused by: java.lang.ClassNotFoundException: javax.servlet.annotation.WebServletat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[na:na]at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]... 20 common frames omitted Process finished with exit code 1 이러고 localhost로 들어가도 들어가지지 않는 상태입니다.. 제가 인텔리제이가 처음이여서 많이 어버버하네요 ㅜㅜ 어떻게 하면 될까요?
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@Login Member ➡ @Login Optional〈Member〉 파라미터 타입에 대한 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 안녕하세요 최고의 김영한 강사님.감탄하며 듣고 보고 있습니다. 고맙습니다. 새해 복많이 받으셔요! 저의 상황은 이렇습니다. HomeController 코드입니다. @GetMapping("/") public String loginHomeV4ArgumentResolver( @Login(LOGIN_MEMBER) Optional<Member> member, Model model) { if (member.isEmpty()) { return "home"; } model.addAttribute("member", member.get()); return "loginHome"; } 이 코드에서 의구심이 드는 부분은제가 커스텀 한 파라미터 부분입니다. Optional<Member> @Login(LOGIN_MEMBER) Optional<Member> member 아규먼트 리졸버에서 HomeController 로 요렇게 쏴주고 있어요 public Object resolveArgument(...) { ... ... /* 어노테이션 value 얻어오기 */ String sessionId = loginAnnotation.value(); return Optional.ofNullable(session.getAttribute(sessionId)); } 질문입니다. 메서드 파라미터로 Optional 을 쓰지 말라고 어디선가 들었는데, 그 룰이 이 상황에도 적용이 되는지 , 이렇게 Optional 를 파라미터로 넘겨도 괜찮을지 궁금합니다.잠제적인 문제를 알수 없어 질문하게 되었습니다. 읽어주셔서 감사해요!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
JdbcTemplate
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] build.gradle 파일에 jdbc 라이브러리를 추가하고, Load Gradle Changes도 해보고 File -> Open -> build.gradle을 선택해서 Open as Project도 해보았는데 JdbcTemplate을 import 못하고 있습니다. 어떤 부분에 문제가 있는 건가요?
-
미해결스프링 핵심 원리 - 기본편
IntelliJ 자동완성 관련
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네[질문 내용]스프링으로 전환하기 4:05 구간을 보시면 applicationContext.getBean(~)에 Bean 이름을 입력하십니다. 신기하게도 텍스트일 뿐인데 IntelliJ가 추정해서 Bean 이름을 제안해주네요. 제 IntelliJ는 자동완성이 안되는데 따로 설정법이 있나요? 구글링을 해봐도 해당 내용을 찾기 어렵군요. IntelliJ IDEA 최신 버전을 사용 중입니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
requestheaderservlet 실행 에러
3분경 코드 실행시 다음과같이 파싱은 제대로 되나, 밑에 에러들( IOExeption .. )이 많이 뜹니다 . 에러 내용이고, 최하단 코드업로드도했습니다. --- REQUEST-LINE - start --- request.getMethod() = GET request.getProtocal() = HTTP/1.1 request.getScheme() = http request.getRequestURL() = http://localhost:8080/request-header request.getRequestURI() = /request-header request.getQueryString() = null request.isSecure() = false --- REQUEST-LINE - end --- 2022-01-21 15:13:09.393 DEBUG 27180 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [780] 2022-01-21 15:13:09.393 DEBUG 27180 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer : Received [] 2022-01-21 15:13:09.394 DEBUG 27180 --- [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@d344380:org.apache.tomcat.util.net.NioChannel@91bedf8:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8080 remote=/[0:0:0:0:0:0:0:1]:51431]], Status in: [OPEN_READ], State out: [OPEN] 2022-01-21 15:13:11.105 DEBUG 27180 --- [nio-8080-exec-2] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [780] 2022-01-21 15:13:11.105 DEBUG 27180 --- [nio-8080-exec-3] o.a.coyote.http11.Http11InputBuffer : Before fill(): parsingHeader: [true], parsingRequestLine: [true], parsingRequestLinePhase: [0], parsingRequestLineStart: [0], byteBuffer.position(): [0], byteBuffer.limit(): [0], end: [0] 2022-01-21 15:13:11.113 DEBUG 27180 --- [nio-8080-exec-3] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header java.io.EOFException: null at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1328) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1215) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:805) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:360) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na] 2022-01-21 15:13:11.113 DEBUG 27180 --- [nio-8080-exec-2] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header java.io.EOFException: null at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1328) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1215) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:805) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:360) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na] 2022-01-21 15:13:11.114 DEBUG 27180 --- [nio-8080-exec-3] o.apache.coyote.http11.Http11Processor : Error state [CLOSE_CONNECTION_NOW] reported while processing request java.io.EOFException: null at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1328) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1215) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:805) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:360) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na] 2022-01-21 15:13:11.114 DEBUG 27180 --- [nio-8080-exec-2] o.apache.coyote.http11.Http11Processor : Error state [CLOSE_CONNECTION_NOW] reported while processing request java.io.EOFException: null at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1328) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1215) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:805) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:360) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:269) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.56.jar:9.0.56] at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na] 2022-01-21 15:13:11.115 DEBUG 27180 --- [nio-8080-exec-3] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@d344380:org.apache.tomcat.util.net.NioChannel@91bedf8:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8080 remote=/[0:0:0:0:0:0:0:1]:51431]], Status in: [OPEN_READ], State out: [CLOSED] 2022-01-21 15:13:11.115 DEBUG 27180 --- [nio-8080-exec-2] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@744cb7a8:org.apache.tomcat.util.net.NioChannel@639e0620:java.nio.channels.SocketChannel[connected local=/[0:0:0:0:0:0:0:1]:8080 remote=/[0:0:0:0:0:0:0:1]:51430]], Status in: [OPEN_READ], State out: [CLOSED] --- package hello.servlet.basic.request;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet(name = "requestHeaderServlet", urlPatterns = "/request-header")public class RequestHeaderServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { printStartLine(request); } private void printStartLine(HttpServletRequest request) { System.out.println("--- REQUEST-LINE - start ---"); System.out.println("request.getMethod() = " + request.getMethod()); //GET System.out.println("request.getProtocal() = " + request.getProtocol()); //HTTP/1.1 System.out.println("request.getScheme() = " + request.getScheme()); //http // http://localhost:8080/request-header System.out.println("request.getRequestURL() = " + request.getRequestURL()); // /request-test System.out.println("request.getRequestURI() = " + request.getRequestURI()); //username=hi System.out.println("request.getQueryString() = " + request.getQueryString()); System.out.println("request.isSecure() = " + request.isSecure()); //https사용 유무 System.out.println("--- REQUEST-LINE - end ---"); System.out.println(); }}
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
dependencies 에 sourceset 으로 분류되지 않아도 괜찮을까요?
안녕하세요, 강의 잘 듣고 있습니다 :) 다름이 아니라, Gradle 설정 후 sourceset 으로 되지 않고 ClassPath 로 뜨더라고요. 왠만한 설정들은 다 똑같은데 버전 차이인지 모양은 조금씩 다른 것 같습니다. 그대로 진행해도 괜찮을까요? 답변 미리 감사드립니다 :)
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
IDENTITY vs SEQUENCE 전략 중 든 의문
안녕하세요, 지금 강의랑 직접적으로 관련된 의문은 아니지만, 지금까지 이 강의를 진행하면 든 의문이 있어서 해소하고 싶어 질문드립니다. DB에 insert을 할 때 사용되는 IDENTITY 전략과 SEQUENCE 전략이 그것인데요. (우선 JPA 강의는 이게 처음이라서 검색을 통해 해소하고 싶었지만 제 검색 실력이 부족해 질문드립니다) 1. 제가 검색을 통해 알아본 결과, GenerationType.IDENTITY는 em.persist() 실행 시점에 DB에 INSERT를 날리고, PK값을 가지고 오고, Sequence는 DB로부터 sequence를 가지고 와서 em.persist()할 때 가지고 온 sequence를 영속성 컨텍스트에 주입한다고 알고 있습니다. 근데 그렇게 할 거면 차리리 그냥 IDENTITY 역시 다음 AUTO_INCREMENT 값이 뭔지만 가져와서 영속성 컨텍스트에 넣고 실제 ISNERT는 flush할 때 넣어주는 방법도 고려해볼 만한 거 같은데 왜 그런 전략은 취하지 않은 건지 의문이 들었습니다. 2. sequence 같은 경우는 allocation_size가 50일 때, 첫 번째 INSERT 쿼리 중 에러가 발생해서 해당 트랜젝션이 종료되면 해당 50개의 sequence는 날라가고 51번째부터 시작하는 건지도 궁금합니다 3. 마찬가지로 IDENTITY 전략에서 em.persist() insert 중 에러가 발생해서 rollback이 되기 전에 다른 insert 요청이 날라와서 insert를 해야하면 처음 에러가 발생했을 때 사용된 PK는 뛰어넘고 auto_increment가 진행되는 건지도 알고 싶습니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
aftereach 적용하지 않아도 테스트가 정상작동됩니다.
현재 복습중입니다. 12분 34초에 나오는데, 분명 예전에는 @AfterEach 를 넣지 않으면 repository에서 기존 값들이 지워지지 않아 테스트에 오류가 생겼었습니다. 그런데 지금은 @AfterEach에서 clear 해주지 않아도 알아서 다른 테스트들에서 저장한 값들이 저장되지 않는데, 기본 구조가 바뀐 걸까요? 예를 들면 findAll에서 repository에 멤버1, 멤버2를 저장했습니다. 그러면 레포지토리의 사이즈는 2가 되어야 하는데, 다음 테스트 맨 처음에 repository.size를 출력해주면 0이 나옵니다.
-
미해결스프링부트 시큐리티 & JWT 강의
BCryptPasswordEncoder 관련 Error
package com.junyharang.jwtstudy.config.jwt; import com.fasterxml.jackson.databind.ObjectMapper;import com.junyharang.jwtstudy.auth.PrincipalDetails;import com.junyharang.jwtstudy.model.Member;import lombok.RequiredArgsConstructor;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.Authentication;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;// 스프링 시큐리티에 UsernamePasswordAuthenticationFilter가 있다.// /login이 요청 오면 username, password를 전송하면 (Post로)// UsernamePasswordAuthenticationFilter가 동작한다.// 현재는 SecurityConfig에서 FormLogin을 disable을 시켜서 동작하지 않는다.@RequiredArgsConstructorpublic class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter { private final AuthenticationManager authenticationManager; @Override // /login 요청이 들어오면 로그인 시도를 위해 실행되는 Method public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { System.out.println("JwtAuthenticationFilter : 로그인 시도 중 입니다!"); // 1. username, password를 받는다. try {// BufferedReader reader = request.getReader();//// String input = null;//// while ((input = reader.readLine()) != null) {// System.out.println(input);// } // while 문 끝 // JSON으로 전달된 값을 Parsing 할수 있게 해주는 객체 생성 ObjectMapper om = new ObjectMapper(); Member member = om.readValue(request.getInputStream(), Member.class); System.out.println(member); // Token 생성(회원의 이름과 Password를 통해) UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(member.getUsername(), member.getPassword()); // PrincipalDetailsService의 loadUserByUsername()이 실행 된다. // authenticationManager에 Token을 넣어 호출한다. // authentication 변수에는 Login 정보가 담긴다. Authentication authentication = authenticationManager.authenticate(authenticationToken); // authentication 객체가 Session 영역에 저장된다. PrincipalDetails principal = (PrincipalDetails) authentication.getPrincipal(); // 출력이 된다면 Login이 되었다는 의미 System.out.println(principal.getMember().getUsername()); return authentication; } catch (IOException e) { e.printStackTrace(); } // try-cache 문 끝 System.out.println("==========================================="); // 2. authenticationManager로 정상 인지 로그인 시도하면 PrincipalDetailsService가 호출된다. // 해당 Class안에 loadUserByUsername()가 자동 호출 // 3. PrincipalDetails를 Session에 담는다. // Session에 해당 내용을 담는 이유는 담지 않으면 권한에 대한 처리를 할 수 없기 때문이다. // 4. JWT를 만들어서 응답해 준다. return null; } // attemptAuthentication(HttpServletRequest request, HttpServletResponse response) 끝 } // class 끝 안녕하세요? 25강에 해당 부분을 하다가 DB에 회원값이 들어가 있는 걸 보고, 회원가입 로직이 누락 되었다는 부분을 찾기 위해 Controller를 보고 아래 내용을 추가 하였습니다. @PostMapping("join") public String join(@RequestBody Member member) { member.setPassword(bCryptPasswordEncoder.encode(member.getPassword())); member.setRolse("ROLE_USER"); memberRepository.save(member); return "회원가입완료";} 그리고 나서 SecurityConfig에 아래 내용을 추가 하였구요. @Autowired private MemberRepository memberRepository;@Autowired private CorsConfig corsConfig;@Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder();} // passwordEncoder() 끝private final CorsFilter corsFilter; 근데 아래와 같은 Error가 발생 합니다. Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2022-01-19 00:25:02.184 ERROR 17752 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Parameter 1 of constructor in com.junyharang.jwtstudy.controller.RestAPIController required a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' that could not be found. Action: Consider defining a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' in your configuration.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
jpql 페치조인
안녕하세요 영한님 감사합니다 첫번째 : new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 반환하면 SELECT 절에서 원하는 데이터를 직접 선택하므로 네트워크 용량을 최적화 할수 있다고 해주셨는데 뒤로 돌아가서 JPQL 페치조인도 마찬가지로 원하는 데이터를 직접 선택해 보고싶어서 이런식으로는 못하나요 ? 테스틀 해봤는데 에러가 나서 질문드립니다. ======================================== 두번쨰 : 18:40 설명은 xToOne 관계에선 페치조인이 필요 없다고 이해 하면 되는거죠 ???
-
미해결스프링부트 시큐리티 & JWT 강의
Entity에 @Data에 대한 질문
안녕하세요? 강의를 듣다가 궁금한 점이 있어 질문 드립니다. Entity Class에 Setter를 사용하면 안된다고 배웠는데, @Data를 사용하시는 이유가 있으실까요??
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Java HotSpot(TM) 64-Bit Server VM warning
스프링부트 gradle 2.6.2 버전인데 설치하고 나서 기본 세팅된 프로그램 돌려봤는데 다음과 같은 워닝이 떠요 Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release. 어떻게 해결할 수 있을까요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
서블릿 생성 시점과 역할 관련 질문입니다!
안녕하세요. 좋은 강의 정말 감사드립니다^^! 서블릿에 관련하여 궁금한 것이 생겨서 질문 드리고 싶습니다. 1. 서블릿 객체는 언제 생성되나요? 처음 스프링 부트가 띄워질 때 만들어 지는 것인가요? 아니면 url mapping이 되어서 서블릿 객체가 필요해지면 생성되나요? 그리고 스프링에서 사용하는 dispatcherservlet은 언제 생성되나요? 2. HttpServelet reqest 객체에 HTTP 요청 메시지 파싱해서 넣고 처리해주는게 서블릿 객체라고 배웠습니다. 그렇다면 HttpServelet response의 내용을 바탕으로 HTTP 응답 메시지를 생성하는 것도 서블릿이 하나요? 3. 서블릿의 요청 메시지 처리 작업은 언제 이루어지나요? was가 url에 맞는 서블릿 객체의 service()를 수행하는데, 저희가 만든 service에는 요청 메시지 파싱 작업이 없어보입니다! service를 부르기 전에 다른 메소드가 먼저 불리는 것인가요? 감사합니다!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
실무에 대해 궁금한것이 있습니다.
그렇다면 실무에서는 REST API의 예외처리를 처리하는경우, 앞서 배운 ResponseStatusExceptionResolver, DefaultHandlerExceptionResolver 이거는 제쳐두고 궁극기인 ExceptionHandlerExceptionResolver 의 @ExceptionHandler와 이를 모아서 관리하는 @ControllerAdvice 이렇게 2개만 사용이 되는편인가요?