묻고 답해요
144만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Practical Testing: 실용적인 테스트 가이드
builer 생성 방식 메서드 분리
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요. 강의를 보면 createProduct 를 통해서 builder 패턴 생성자 생성 방식을 공통메서드로 분리해주셨는데요. 이는 builder 패턴이 제공해주는 생성자 생성방식의 유연성을 함수로 분리함으로써 인해 제약을 주는 것이기도 한 거 같다는 생각이 들었습니다. 만약에 각 Product마다 필요한 컬럼이 다르다면 createProduct 함수로 분리하는게 아닌 반복이 되지만 어쩔 수 없이 각각 builder() + 체이닝 방식으로 코드를 기술하셨을지, 아니면 필요한 함수 시그니처마다 함수를 분리하셨을지 궁금합니다.
-
해결됨Spring framework 개발 환경 구축하기와 Dao 리팩토링하기
[해결 방법] Autowired가 적용이 안되는 문제 + context에서 NullPointerException
build.gradle 추가testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.3' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.3'
-
미해결스프링 시큐리티 OAuth2
인증을 세션이 아닌 jwt로 할 경우 질문입니다.
현재 oauth2Login api를 사용해서 사용자 로그인 인증에 성공하면 인증객체가 세션에 저장되고, 이후 인가서버에 code 요청시 OAuth2AuthorizationEndpointFilter 에서도 securityContext에 저장돼있는 인증객체로 인해 인증성공으로 판단후 code를 발급합니다. 근데 세션 기반이 아닌, jwt 토큰을 받아서 검증후 인증을 처리하는 로직이라면 jwt 토큰을 검증하는 필터인 resource Server api의 필터가 OAuth2AuthorizationEndpointFilter 보다 뒤에 있기 때문에 인증객체가 없어서 코드발급을 안해줄텐데 이럴땐 어떻게 해야하나요? jwt토큰을 검증하고 인증객체를 만드는 필터를 OAuth2AuthorizationEndpointFilter 앞에 만든다고 쳐도 그러면 resource Server api의 필터와 똑같이 동작하는 필터가 생기는건데 좋은 방법인것 같진 않습니다. 어떻게 해야 하나요?
-
미해결스프링 시큐리티 OAuth2
Resouce owner 인증 전 단계 질문입니다.
클라이언트가 인가서버에게 인가코드를 요청하기 전에 사용자인증을 받기 위해 사용자 id, 비밀번호를 입력하는 단계가 먼저 거치고, 인증이 되면 인가서버에게 /oauth2/authorize url로 response_type=code ~~ 이런식의 정보를 포함해서 요청하게 되는데 그러면 사용자가 인증받을때 입력한 사용자 id, 비밀번호를 통해 인증처리를 하는건 인가서버에서 하는게 아닌건가요? 인가서버에서 하는거라면 입력한 사용자 id, 비밀번호는 어떤 필터에서 처리하는건가요?
-
미해결Spring framework 개발 환경 구축하기와 Dao 리팩토링하기
[해결 방법] findOne 에러 / Inferred type 'S' for type parameter 'S' is not within its bound; should extend 'com. spring. www. domain. User'
@RunWith(SpringRunner.class) @SpringBootTest public class UserRepositoryTest { @Autowired UserRepository userRepository; @Test public void save() { //User user = new User("kms", "kms1234", "hongildong"); //userRepository.save(user); User user = new User(); user.setId("kms"); Example<User> userExample = Example.of(user); User selectedUser = userRepository.findOne(userExample).orElse(null); assertEquals("kms", selectedUser.getId()); } }
-
미해결Spring framework 개발 환경 구축하기와 Dao 리팩토링하기
[해결 방법] Java8 버전 사용하고 싶으신 분들은 아래와 같이 설정하시면 됩니다.
build.gradleplugins { id 'java' id 'org.springframework.boot' version '2.3.12.RELEASE' id 'io.spring.dependency-management' version '1.0.10.RELEASE' } group = 'com.spring.www' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'mysql:mysql-connector-java:8.0.32' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() }gradle-wrapper.propertiesdistributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
트랜잭션 전파 활용1,2 강의 내용 중 질문
강의록에 첨부해주신 그림을 보면 MemberRepository는 con1를 사용하고, LogRepository는 con2를 사용하는데 이게 각각 MemberRepository는 트랜잭션B를 사용하고 LogRepository는 트랜잭션C를 사용한다고 해서 다른 커넥션을 사용하게 되는거죠?? MemberRepository는 con1를 사용하고 커밋하고 난 후에 커넥션 풀에 con1이 반납되고 그 후에 LogRepository가 트랜잭션을 시작하게 되면 con1을 사용하게 되는건 아닌가요?? 이럴때는 서로가 다른 트랜잭션B,C로 구분이 안되어있을때만 이렇게 되는건가요..??
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
세션클러스터링 적용후 중복로그인 체크
안녕하세요. 스프링 시큐리티 완전 정복 6.x 버전 잘 들었습니다.궁금한 점 이 있는데요.세션 클러스터링을 통해서 redis를 적용하면 세션이 tomcat -> rediss로 변경되는 부분 확인하였고, 잘 동작되는 것도 확인하였습니다.궁금한 점은 단일 서버일 때 중복 로그인 설정을 하면 session 체크를 ConcurrentSessionFilter에서 하는 것으로 알고 있는데, 세션 클러스터링을 적용하면 동시 세션을 어떻게 체크하는지 궁금하고, 이것을 제어하기 위해 설정이 추가로 필요한지 궁금합니다.단일 서버일 경우 sessionManagement를 통해서 maximumSessions(1) 인 것을 체크를 하게 되는데, 세션 클러스터링을 적용할 경우 이 값을 어떻게 공유하면서 처리하는지 궁금합니다.감사합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ConversionService와 Formatter 역할
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용] 정리를 하자면 아래와 같은지 확인하고 싶습니다.ConversionServiceHTTP 요청 파라미터(문자) → 타입에 맞는 객체로 변환객체 → HTML 렌더링을 위한 문자로 변환Formatter숫자/날짜 → 지정된 형식의 문자열로 변환 (예: 10000 → "10,000")형식화된 문자열 → 객체로 변환 ("2024-10-19 14:05:57" → localDateTime 객체)
-
미해결Practical Testing: 실용적인 테스트 가이드
Classicist VS. Mockist
우빈님. 안녕하세요! 질문이 있어서 남겨드립니다.제가 테스트할때는 repository부분의 쿼리메서드나 jpql로 작성한 코드들은 따로 테스트를 하지 않고 QueryDSL같은 외부 라이브러리를 사용할때만 단위 테스트를 진행합니다. 그리고 비즈니스 레이어에 대해서는 위의 repository를 mocking하여 사용하고 컨트롤러 부분에서 통합테스트를 진행합니다.해당 부분에서 우빈님과 하는 방식이 다른것 같습니다. 우빈님은 비즈니스 레이어에서 통합테스트를 진행하고 Presentation 레이어에서 mocking을 이용한다고 하셨는데 혹시 제가 하는 방식에서 조언을 주실 수 있으실지 잘못된 방향성으로 가고 있는지에 대해 여쭤보고 싶습니다. 또한 우빈님께서 그렇게 진행하시는 이유에 대해 듣고 싶습니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
인증 컨텍스트 - SecurityContext / SecuriryContextHolder - 2
강의 13분 50초를 보면this.securityContextHolderStrateget.setContext(context);this.securityContextRepository.saveContext(context, request, response);두 메서드가 존재합니다.전자는 ThreadLocal에 인증객체를 저장한다라고 하셨고,후자는 세션에 저장한다라고 설명해주셨는데 개인적으로 잘 이해가 안갑니다. 차이가 무엇인지...
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Test에서 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 코드는 다음과 같이 작성했는데 다음과 같은 문제가 발생합니다. 코드를 여러번 수정하고 계속 확인하는데 고쳐지지가 않아서 질문드립니다![질문 내용]여기에 질문 내용을 남겨주세요.
-
미해결스프링 시큐리티 OAuth2
code 를 accessToken 으로 교환시 질문입니다.
인가서버로부터 code 발급받고 이 코드를 accessToken으로 교환하기 위해 서버에 요청할때 이 순간은 인증을 못받은 상태 아닌가요? accessToken을 발급받아야 클라이언트가 인증을 받은거고 그리고 이때도 클라이언트가 인증을 받아서 authorizedClient 객체가 생기는거지 인증객체가 생기는건 아닐텐데 강의 37분30초쯤에는 code를 accessToken으로 바꿔달라는 요청할때 왜 인증객체가 생성돼있나요? authorization server api를 사용했기때문에 마지막에 위치한 인가서버 필터에 도달하기 위해 다르게 처리되는건가요?
-
미해결스프링 시큐리티 OAuth2
resouce server 질문
인가서버 설정을 하면서 인가서버에서 accessToken을 받고 이를 검증해야하기 때문에 oauth2ResourceServer api를 jwt로 설정한다고 설명하셨는데 이게 무슨 말인지 잘 모르겠습니다. oauth2ResourceServer 는 말그대로 헤더에 jwt 토큰이 있는 요청이 들어오면 이 jwt 토큰을 인가서버와의 통신으로 검증해서 인증처리를 하는 구조인건데 인가서버 설정에서 이게 왜 필요한건지 잘 모르겠습니다. user info 요청할때 클라이언트가 인가서버로 accessToken을 주면서 유저정보 달라고할때 인가서버에서 이 accessToken을 검증하는데, 이때 리소스 서버를 사용해서 검증한다는건가요? 그럼 oauth2ResourceServer api를 등록안하면 인가서버는 자체적으로 accessToken을 검증할수가 없는건가요? 인가서버와 리소스서버는 서로 다른 개념인거 같은데 인가서버를 위해 리소스서버를 써야한다는게 잘 이해가 가지 않습니다.
-
미해결스프링 시큐리티 OAuth2
자체로그인 구현시 질문입니다.
카카오, 네이버같은 소셜로그인이 아닌, 자체 로그인을 통한 검증을 구현하려고 하는데 프론트가 react 이므로 jwt 토큰을 사용한 검증을 진행하려고 합니다. 그러면 이를 구현하기 위해서 jwt 토큰을 발급하는 oauth2 authorization server와 발급한 jwt토큰을 검증하는 oauth2 Resource Server와 자체적으로 만든 시큐리티 인가서버에 code와 토큰을 요청하는 oauth2 client api를 전부 사용해야하는건가요? 즉, jwt를 통한 자체로그인 검증기능을 구현하려면 지금까지 학습한 oauth2 client + oauth2 Resource Server + oauth2 Authorization Server 3개 api를 전부 사용해 구현해야 하는건가요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
테스트 코드에 대해 질문 있습니다.
private String createNextProductNumber() { String latestProductNumber = productRepository.findLatestProductNumber(); if (latestProductNumber == null) { return "001"; } int latestProductNumberInt = Integer.parseInt(latestProductNumber); int nextProductNumberInt = latestProductNumberInt + 1; return String.format("%03d", nextProductNumberInt); } Integer.parseInt(latestProductNumber); 이 부분 처럼 값을 숫자로 바꿀때 latestProductNumber가 숫자인지 아닌지에 대한 검증은 안해도 되는건지 궁금합니다. public OrderResponse createOrder(OrderCreateRequest request, LocalDateTime registeredDateTime) { List<String> productNumbers = request.getProductNumbers(); List<Product> products = findProductsBy(productNumbers); deductStockQuantities(products); Order order = Order.create(products, registeredDateTime); Order savedOrder = orderRepository.save(order); return OrderResponse.of(savedOrder); } ... private static List<String> extractStockProductNumbers(List<Product> products) { return products.stream() .filter(product -> ProductType.containsStockType(product.getType())) .map(Product::getProductNumber) .collect(Collectors.toList()); } private Map<String, Stock> createStockMapBy(List<String> stockProductNumbers) { List<Stock> stocks = stockRepository.findAllByProductNumberIn(stockProductNumbers); return stocks.stream() .collect(Collectors.toMap(Stock::getProductNumber, s -> s)); } private static Map<String, Long> createCountingMapBy(List<String> stockProductNumbers) { return stockProductNumbers.stream() .collect(Collectors.groupingBy(p -> p, Collectors.counting())); } 위 상황처럼 createOrder()메서드가 아래 private 메서드를 모두 호출 하므로 createOrder() 메서드만 테스트하고 나머지 메서드는 테스트를 안 해도 되는건가요?질문의 요지는 private이냐 아니야가 아니라 특정 메서드에서 다른 메서드를 모두 호출한다면 특정 메서드만 테스트를 해도 되는지 아니면 각각의 메서드도 테스트를 해야하는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
오류처리 흐름과 ExceptionResolver 관련 질문
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 질문 1. 오류 처리 흐름을 아래와 같이 이해하였는데 맞는지 여부BasicErrorController를 활용한 오류 처리 흐름WAS(여기까지 전파) ← 필터 ← 서블릿 ← 인터셉터 ← 컨트롤러(예외 발생)WAS(/error) → 서블릿 → BasicErrorController에서 오류 처리 → View or JSON 반환ExceptionResolver를 활용한 오류 처리 흐름ExceptionResolver(response.sendError() 처리) ← 필터 ← 서블릿 ← 인터셉터 ← 컨트롤러(예외 발생)WAS(/error) → 서블릿 → BasicErrorController에서 오류 처리 → View or JSON 반환질문 2. ExceptionResolver 관련 설명을 아래와 같이 이해하였는데 맞는지 여부예외 발생 시 서블릿 컨테이너까지 예외가 전달되지 않고, 스프링 MVC의 ExceptionResolver 에서 예외를 처리한다. -> response.sendError() 가 아닌 예외(Exception)이 WAS에 전달되지 않는다.WAS 입장에서는 정상 처리된 것이다. -> response.sendError() 는 WAS 입장에서 정상 처리 된 것으로 인지한다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
HandlerExceptionResolver의 sendError, ModelAndView
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요.아래의 흐름이 맞는지 확인해보고 싶어 질문드립니다.정리:일반적인 예외:Spring MVC가 처리되지 않은 예외를 감지합니다.Spring MVC는 이 예외를 WAS에게 전달합니다.WAS는 기본적으로 500 Internal Server Error를 설정합니다.Spring Boot 환경에서는 BasicErrorController가 호출되어 최종 에러 응답을 생성합니다.HandlerExceptionResolver에서 빈 ModelAndView 반환:Spring MVC는 예외가 처리되었다고 간주합니다.만약 resolver 내에서 response.sendError()를 호출했다면:WAS는 요청 처리 완료 후 에러 상태를 감지합니다.WAS는 에러 처리 메커니즘을 시작합니다.Spring Boot 환경에서는 BasicErrorController가 호출됩니다.sendError()를 호출하지 않았다면, 일반적인 응답으로 처리됩니다.HandlerExceptionResolver에서 null 반환:Spring MVC는 다음 resolver로 예외 처리를 계속 시도합니다.모든 resolver가 null을 반환하면, 예외는 처리되지 않은 것으로 간주됩니다.처리되지 않은 예외는 WAS에게 전달됩니다.WAS는 500 Internal Server Error를 설정합니다.Spring Boot 환경에서는 BasicErrorController가 호출됩니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
redirect vs. forward사용예
redirect 는 실제 클라이언트(웹 브라우저)에 응답이 나갔다가, 클라이언트가 redirect 경로로 다시 요청한다. 따라서 클라이언트가 인지할 수 있고, URL 경로도 실제로 변경된다. 반면에 forward는 서버 내부에서 일어나는 호출이기 때문에 클라이언트가 전혀 인지하지 못한다. 라고 설명해주셧는데 redirect 같은 경우는 HTTP강의에서 영구적인 경우는 흔히 웹 사이트 주소가 바뀔때 유저가 예전 URL로 접근할시 새로운 URL로 연결해주는 역할을 할대 ㅅ ㅏ용하고 일시적인 경우 주문 후에 새로 고침으로 인한 중복 주문 방지로 주로 쓰인다고 했는데 FORWARD는 언제 사용하는건가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]***************************APPLICATION FAILED TO START***************************Description:Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.Action:Check your application's dependencies for a supported servlet web server.Check the configured web application type.이런오류가 발생합니다