묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
마이그레이션 오류입니다.
강의에서 강사님께서 11에서 17로 바꾸라는 모든 설정 확실하게 수정 완료했고 gradle 코드 수정하여 실행하니 A problem occurred configuring root project 'library-app'.> java.util.concurrent.ExecutionException: org.gradle.api.GradleException: Failed to create Jar file C:\Users\seong\.gradle\caches\jars-9\3baa90cc2341a9ffd1656b87b2a3526e\spring-core-6.2.11.jar.아래와 같은 jar 파일 오류가 떴습니다. 구글링과 GPT를 써보니 캐시 파일 버전 충돌 오류라고 하여 캐시 파일을 삭제 하려고 해도 디렉터리가 비어있지 않다는 오류가 뜨며 삭제되지 않고, 또 .\gradlew wrapper 버전이 현재 7.5인데 스프링 부트 3.5.6은 최소 8.x를 사용한다고 하여 이것 또한 업그레이드 하려고 하였으나 PS C:\Project\Study-SpringBoot\library-app> .\gradlew wrapper --gradle-version 8.3 --distribution-type allStarting a Gradle Daemon, 5 stopped Daemons could not be reused, use --status for detailsFAILURE: Build failed with an exception.* What went wrong:A problem occurred configuring root project 'library-app'.> java.util.concurrent.ExecutionException: org.gradle.api.GradleException: Failed to create Jar file C:\Users\seong\.gradle\caches\jars-9\3baa90cc2341a9ffd1656b87b2a3526e\spring-core-6.2.11.jar.동일한 이런 jar 파일 오류가 떴습니다.이 오류를 어떻게 해결해야 할까요 .... 도와주세요 ㅜㅜ
-
해결됨(2026) 일주일만에 합격하는 정보처리기사 실기
제본
제본을하려고 합니다!총 매수가 어느정도 나오나요??
-
미해결스프링 시큐리티 OAuth2
JWT 조회 에 대한 질문
안녕하십니까. 스프링 시큐리티 강의를 듣고 있는 대학생입니다. 현재 강의를 들으면서 팀 프로젝트에 소셜 로그인을 적용하던 중 궁금증이 생겨 글을 작성하게 되었습니다. 현재 사용자가 로그인 후 토큰을 발급받고 MySQL에 리프레시 토큰을 저장한 뒤에, 사용자가 API에 접근할 때마다 매번 사용자 정보를 조회하는 것이 좋은 방법인지 궁금합니다. 현재 매번 조회하는 이유는 토큰의 사용자 정보가 서버 데이터베이스에 올바르게 저장된 사용자인지 검증하기 위해서 이 방식을 채택했습니다 package backend_lingua.linguas.infrastructure.security.filter; import backend_lingua.linguas.infrastructure.security.token.enumerated.TokenType; import io.jsonwebtoken.ExpiredJwtException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @Slf4j @Component @RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider jwtTokenProvider; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String token = getBearerToken(request); // 토큰이 있는 경우에만 검증 if (StringUtils.hasText(token)) { try { if (jwtTokenProvider.validateAccessToken(token)) { Authentication authentication = jwtTokenProvider.getAuthentication(token, TokenType.ACCESS_TOKEN); SecurityContextHolder.getContext().setAuthentication(authentication); log.debug("Security Context에 '{}' 인증 정보를 저장했습니다.", authentication.getName()); } } catch (ExpiredJwtException e) { log.error("토큰 인증 실패: {}", e.getMessage()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed"); return; } } filterChain.doFilter(request, response); } private String getBearerToken(HttpServletRequest request) { String bearerToken = request.getHeader("Authorization"); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; } } public TokenInfo generateToken(Authentication authentication) { String accessToken = createAccessToken(authentication); String refreshToken = createRefreshToken(authentication); Date accessTokenExpiryDate = createExpiryDate(accessTokenExpiration); return TokenInfo.from(accessToken, refreshToken, accessTokenExpiryDate.getTime(), refreshTokenExpiration); } public String createAccessToken(Authentication authentication) { return createToken(authentication, accessTokenExpiration, accessTokenSecret); } public String createRefreshToken(Authentication authentication) { String token = createToken(authentication, refreshTokenExpiration, refreshTokenSecret); Date expiryDate = createExpiryDate(refreshTokenExpiration); // DB에 리프레시 토큰 저장 tokenService.createRefreshToken(token, expiryDate, authentication); return token; } private String createToken(Authentication authentication, long expirationTime, String secretKey) { String authorities = authentication.getAuthorities() .stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); return Jwts.builder() .setSubject(authentication.getName()) // email .claim("auth", authorities) .setIssuedAt(new Date()) .setExpiration(createExpiryDate(expirationTime)) .signWith(createKey(secretKey)) .compact(); } public String getUsernameFromToken(String token, TokenType tokenType) { String secretKey = (tokenType == TokenType.ACCESS_TOKEN) ? accessTokenSecret : refreshTokenSecret; return Jwts.parserBuilder() .setSigningKey(createKey(secretKey)) .build() .parseClaimsJws(token) .getBody() .getSubject(); } public Authentication getAuthentication(String token, TokenType tokenType) { String username = getUsernameFromToken(token, tokenType); UserPrincipal userPrincipal = (UserPrincipal) userDetailsService.loadUserByUsername(username); return new UsernamePasswordAuthenticationToken( userPrincipal, token, userPrincipal.getAuthorities() ); } public boolean validateAccessToken(String token) { return validateToken(token, accessTokenSecret); } public boolean validateRefreshToken(String token) { return validateToken(token, refreshTokenSecret); } private boolean validateToken(String token, String secretKey) { try { Jwts.parserBuilder() .setSigningKey(createKey(secretKey)) .build() .parseClaimsJws(token); return true; } catch (ExpiredJwtException e) { log.error("만료된 JWT 토큰입니다."); throw e; // Filter에서 401 처리하도록 } catch (SecurityException | MalformedJwtException e) { log.error("잘못된 JWT 서명입니다."); } catch (UnsupportedJwtException e) { log.error("지원되지 않는 JWT 토큰입니다."); } catch (IllegalArgumentException e) { log.error("JWT 토큰이 잘못되었습니다."); } return false; } private Date createExpiryDate(long expirationTime) { return new Date(System.currentTimeMillis() + expirationTime); } private SecretKey createKey(String secret) { byte[] keyBytes = Decoders.BASE64.decode(secret); return Keys.hmacShaKeyFor(keyBytes); } @Service @RequiredArgsConstructor public class UserDetailsServiceImpl implements UserDetailsService { private final MemberRepository memberRepository; @Override @Transactional(readOnly = true) public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { Member member = memberRepository.findByEmail(email) .orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다: " + email)); return UserPrincipal.create(member); } }public class TokenServiceImpl implements TokenService { private final RefreshTokenRepository refreshTokenRepository; private final MemberRepository memberRepository; @Override @Transactional public RefreshToken createRefreshToken(String token, Date expiryDate, Authentication authentication) { String email = authentication.getName(); Member member = memberRepository.findByEmail(email) .orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다: " + email)); // 새 토큰 생성 RefreshToken refreshToken = RefreshToken.builder() .token(token) .member(member) .expiryDate(convertToLocalDateTime(expiryDate)) .build(); return refreshTokenRepository.save(refreshToken); } @Override @Transactional public void deleteRefreshToken(String email) { Member member = memberRepository.findByEmail(email) .orElseThrow(() -> new RuntimeException("사용자를 찾을 수 없습니다: " + email)); deleteRefreshTokenByUser(member); } @Override @Transactional public void deleteRefreshTokenByUser(Member member) { refreshTokenRepository.findByMemberId(member.getId()) .ifPresent(refreshTokenRepository::delete); } private LocalDateTime convertToLocalDateTime(Date date) { return Instant.ofEpochMilli(date.getTime()) .atZone(ZoneId.systemDefault()) .toLocalDateTime(); } }
-
해결됨6주 완성! 백엔드 이력서 차별화 전략 4가지 - 똑같은 이력서 속에서 돋보이는 법
이력서 첨삭
안녕하세요 딩코님 제가 완강을 하여 이력서를 작성해봤는데보완·추가 할만한 부분을 알려주실수 있을까요https://earthy-chalk-721.notion.site/Lee-Jeongwon-1aa176858bf380cca9cce9625a5ad1e4?pvs=73강의중 살짝 봤는데 포공 졸업하셨나요,,, 역시 너무 잘배웠습니다
-
해결됨(2026) 일주일만에 합격하는 정보처리기사 실기
1:03:00 node
func 매서드에서 while문 마지막 실행문인node = node -> next -> next; 가 이해가 잘 안되었는데요.해당 실행문 위에 있는 다른 실행문은 node->value 또는 node->next를 통해서 n1메모리에 참조해서 그 값을 가르키기 때문에 =을 통해 값변화가 일어난다.하지만 node = node -> next -> next; 의 경우에 node는 func메서드가 가지고 있는 지역변수이기 때문에 main에서부터 참조받은 n1 변수를 변경하지 않는다. 이게 맞을까요?저말고도 다른분들도 여럿 같은 질문을 했는데 정확한 답변이 없어서 제가 이해한게 맞는지 올려봅니다.. 그럼에도 확실하게 개념이 잡히지 않네요. node -> value 또는 node -> next조차도 func메서드 안에 있는 지역변수의 요소들인 건 매한가지 아닌가요...ㅠㅠ node도 메모리주소.. node->next->next도 메모리주소인데.. 왜 지역변수로 얕은복사(?)가 되는 것인지..ㅠㅠ
-
해결됨백엔드 6주 실전 미션과 1:1 피드백으로 완성하는 합격 포트폴리오
오타 발견 제보
3주차 수업 자료(notion) category 안에 Training 이 없습니다. 글 내용 흐름에 따라 Training 대신 Fiction 으로 수정하면 될 것 같습니다 🙂 아래 GROUP BY 를 통해서도 없다는 것을 다시 한 번 확인할 수 있습니다. GROUP BY 조회 결과
-
해결됨(2026) 일주일만에 합격하는 정보처리기사 실기
35q분
comp 메서드에 매개변수가 들어갈 때, str.length-1로 들어가면 뒤에서부터 재귀함수가 시작해서 d부터 들어가고 c b a가 순서대로 들어가야하는 것 처럼 보이는데요.이때, if문 안에서 result = c + result 로 되어 있는데요. result에 이미 d가 들어가있다고 가정했을 때 식이 진행되면 result = "cd"가 되는 것인지 result = "dc"가 되는 것인지 궁금합니다. 만약 전자라면 정답이 abcd가 되어야 하는 것이 아닌가요? index 마지막부터 시작되니까요.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
단건 주문만 가능하게 한건 의도한 부분이신가요?
1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]단순 궁금증입니다.도메인 설계에서 여러 OrderItem을 만들 수 있도록 설계했으면서 정작 Service에선 한 개의 ItemId, count를 받게 하신건 의도하신건가요? 의도하신거였네요.뒷 내용을 확인하지 않고 질문을 달았었네요..
-
해결됨(2026) 일주일만에 합격하는 정보처리기사 실기
정보처리기사 30일 플랜을 짜고 싶습니다.
안녕하세요 주말코딩님. 선생님의 강의를 듣고있는 정보처리기사 실기를 수강하고 있는 학생입니다.1회차는 떨어졌고, 2회차는 사정 상 접수를 못하게 되어 3회차에 접수하여 응시를 할 생각입니다. 1회차는 아마 40점정도로 맞은 것 같습니다. 이론은 대부분 맞혔지만 코드에서 대부분 정답을 맞히지 못해 불합격을 하고 말았습니다. 선생님의 강의를 30일플랜에 맞춰서 활용하려고 하는데 몇 가지 여쭙고 싶은 게 있어 질문을 드리고자 합니다. 3회차 시험 날까지 30일정도 시간이 있으며, 낮에는 회사에 근무하고 있어서 공부 시간은 저녁 7시부터 가능한 상황입니다. 주말에는 가정사가 있어 1-2시간정도만 학습이 가능한 상황입니다. 시험을 대비하기에 충분한 시간이 될 수 있을까요? 이론은 최근 나온 기출문제에 나온 문제들로 이미 틈틈이 학습 중입니다. 하지만 문제가 코드를 푸는 문제에 있어서 걱정이 됩니다. 일단 코드 문제를 풀 때 main부터 차근차근 풀어나갈 때, 어딘가 반드시 막히게 되더라구요.. 기초는 있지만 응용이 잘 안되는 것 같습니다. 혹시, 정보처리기사 실기문제를 ide상에서 복사해서 붙여 넣지 않고 직접 코딩을 해보는 것이 이해에 도움이 될까요?30일 플랜을 짤 때 어떻게 짜면 좋을까요? "1주차에는 몇 강을 듣고 몇 강을 들어라"이런 식으로 조언 부탁 드립니다.바쁘시더라도 답변 부탁 드리겠습니다.감사합니다..
-
미해결김영한의 실전 자바 - 중급 1편
12:30 의 newClassGrade 질문이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]16.타입 안전 열거형 패턴 12:30 쯤 new ClassGrade();로 새로운 객체를 만들어서 discountServies.discount의 파라미터로 사용 하셨는데 newClassGrade.BASIC 으로 파라미터를 입력하면 BASIC은 ClassGrade의 스태틱 필드이기 때문에 정상적으로 비교 가능한게 아닌지 궁금합니다. 만약 정상적으로 비교하다면 new를 기능에 크게 문제가 없는데 왜 private로 변경해야 하는지도 궁금해요!
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
26강 임시반장 정하기에서 질문이 있습니다
선생님은for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) {에서 값이 같으면 cnt++ 을 하는데 여기서 자기 자신도 갯수를 새어서 cnt를 하나 더하지만여기서는 어차피 모두 한다 cnt 를 똑같은 개수만큼 각 학년당 하나씩 ++ 해서 5가 더해질거고 각 학생마다 cnt 값이 아닌 cnt 가 가장 큰 학생을 고르는 문제이므로선생님께서는 이 부분을 고려하지 않은것인지 여쭙고 싶습니다
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
[질문 내용]묵시적 조인인select t.members from Team t이것과명시적 조인인select m from Team t join t.members m이 둘의 SQL 결과는 같았습니다.JPQL은 객체지향 쿼리니까 객체로 생각해보아도t.members는 List<Member> 컬렉션 자체이고t.members m으로 별칭을 주면 이 m은 Member 단위라는 게혼자 생각도 해보고 질문 글도 보고 검색도 계속 했는데 그 어디에도 납득가는 설명이 없어서요.그냥 외워야 하는 부분일까요?ㅠ
-
미해결스프링 시큐리티 OAuth2
password grant 방식 에러 응답
강의보고 실습하고 있는데요, password grant 타입은 아래와 같이 에러가 발생합니다. 유저 consent도 등록이 되어있는데, 진행이 안됩니다.
-
미해결실습으로 배우는 선착순 이벤트 시스템
흐름정리 제가 이해한게 맞나요?
쿠폰 100개를 발급해야하고 이 개수는 100을 넘어가면 안됨-> java synchronized락의 경우 쿠폰 발급을 담당하는 서버가 여러개라면 db에 쿠폰 저장(개수 업데이트) 요청이 동시에 올수 있으므로 race condition 발생-> redis의 경우 여러 서버가 쿠폰 발급 요청을 보내도 싱글 스레드이므로 쿠폰 발급 수를 정확히 100개로 맞출 수 있음. 하지만 예제의 경우 threadpool을 사용하여 각 스레드별로 쿠폰 발급이 가능하면 바로 db에 쿠폰 저장하는 로직이라서 db 부하가 심함-> kafka를 도입하여 스레드들이 쿠폰 발급 메세지만 카프카로 보내고 카프카 컨슈머가 이 메세지를 처리하여 db에 쿠폰을 저장함. 컨슈머 그룹에 속한 컨슈머는 현재 하나이므로 메세지 1개씩을 처리함 따라서 db에 부하가 심하지 않음.
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
이번달말에 완강 후 공부 방향
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 선생님. 제공해주신 강의 잘 듣고 있습니다.다름이 아니라, 이번달 말에 강의를 완강할 수 있을 것 같은데제가 준비하는 기업의 코딩테스트가 10월말쯤으로 약 한달 남았습니다.이러한 경우, 강의를 한번 더 복습하는 게 나을까요아니면 프로그래머스에서 문제를 골라서 푸는 게 나을까요? (기업 코딩테스트가 프로그래머스 환경에서 진행됩니다.) 답변 주시면 감사하겠습니다.
-
미해결RabbitMQ를 이용한 비동기 아키텍처 한방에 해결하기
강의 자료 관련
강의자료가 PDF로 변환하다보니, 문자 길이 때문인지 끊어지는 경우가 있는거 같은데 혹시 Notion 페이지로 제공해주실 수 잇나요?
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
dto 필드 속 엔티티 여부
1. 강의 내용과 관련된 질문인가요?예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요, dto에 대해서 질문드리고 싶어 남깁니다. order 테이블에는 연관관계 필드가 있는데 orderDto에서는 연관관계 필드를 제외한 데이터들이 필드로 들어가있습니다.보통 Dto를 작성할 때는 엔티티 연관관계 필드들은 양방향 편의 메서드같은것으로 수정하고 dto에서는 int, String같은 기본 필드들만 받는것이 일반적일까요 ? 스프링부트 1 버전에서 가급적 단방향 연관관계로 설계하라 하셨는데, 단방향으로 설계하게 되면 연관관계 편의 메서드를 작성하지 않을텐데 이때는 dto필드에 엔티티까지 작성하는지 궁금합니다.좋은 강의 제공해주셔서 감사드립니다 !
-
미해결죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.
이너 클래스로 구현하는 이유
킬구형 안녕!지금 실무에서 Spring Batch를 사용해서 배치 기능 구현하고 있는데 궁금한 점이 있어.강의의 예제 코드들을 보다보면 Job에 필요한 항목들을 따로 클래스 파일로 빼서 구현하지 않고 JobConfig 클래스 내에서 이너 클래스로 구현하던데 특별한 이유가 있을까!?@Slf4j public static class BrainwashProcessor implements ItemProcessor<InFearLearnStudents, BrainwashedVictim> {강의가 너무 재밌어서 점심시간에도 공부 중이야 ㅎㅎ
-
미해결토비의 클린 스프링 - 도메인 모델 패턴과 헥사고날 아키텍처 Part 1
멀티모듈
안녕하세요 토비님배운 내용을 바탕으로 기존 프로젝트 구조를 변경하는 연습하고 있습니다.기존 프로젝트가 멀티 모듈로 되어있어 멀티모듈 구조는 그대로 가져가고 싶은데 분리한다면어떻게 나누어야 할까요?모듈을 두개로 나누어 api와 core로 구성했는데 adapter, application, domain를api 모듈에 adapter core 모듈에 application, domain 이렇게 구성하였는데 이렇게 구분해도 괜찮은지 잘 모르겠습니다
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
제가 이런 코테가 처음인데 공부방법을..ㅠ
일단 인강을 보기전에 혼자 스스로 풀어보고 제출을해서 정답을 여러번 맞췄는데 선생님하고 코드가 좀 많이 다릅니다.(제 코드는 채점사이트에서는 정답은 나옴) 그래서 정답으로 나오긴하지만 선생님코드랑은 다르니..이게 올바는 코드인지..제가 푼게 잘푼건지..잘모르겠습니다..ㅠ 선생님코드로 공부를해야하는지..