묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemberController 러닝 에러
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]4분 쯤에 강사님께서 @Autowired 설명하셨을 때 생성자의 파라미터인 memberService에 빨간 밑줄 에러표시가 떴는데 저는 그게 뜨지도 않았고, HelloSpringApplication을 실행하면 강사님과는 다르게 붉은 글씨들이 뜨네요.. 뭐가 잘못된 건지 모르겠습니다..
-
미해결실습으로 배우는 선착순 이벤트 시스템
MySql Lock을 사용하지 않는 이유
강의에서 설명해주시기로는 쿠폰 개수를 가져오는 것부터 쿠폰 생성까지 lock을 걸어야 한다고 설명 주셨는데 이전 강의인 재고 관리 이슈와는 다르게 row가 아닌 table에 lock을 걸기 때문에 성능 이슈가 발생한다고 보면 될까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
회원서비스테스트강의중 회원가입 테스트에 대한 궁금증이 생겨서 질문드립니다.
회원가입 테스트를 진행할때 밑에 검증하는 부분에서 궁금증이 생겼습니다. 강의상에서는 제가 작성한 부분에서는 findOneMember라는 회원의 이름을 이용하여 검증을 하고 있는걸로 알고 있습니다. 하지만 제가 추가로 작성한 마지막 줄에 있는 검증 코드처럼 findOneMember라는 회원의 이름으로 접근하지 않고 when부분에서 도출한 joinId와 given부분에서 생성한 기대하는 회원의 id를 이용하여 검증을 하면 혹시 안되는지 여쭈어보고 싶습니다. 추가로 이렇게 검증을 할 때 어떤 것을 검증하냐는 개발자의 마음인지도 궁금합니다. 감사합니다.
-
미해결스프링 시큐리티
스프링 시큐리티 멀티 로그인 관련 질문드립니다.
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain adminfilterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() .httpBasic() ; return http.build(); } @Bean static final public InMemoryUserDetailsManager kk() { //DB연동을 안할 경우, 테스트 용으로 하는 것이다. UserDetails user = User.withDefaultPasswordEncoder() .username("user") .password("1111") .roles("USER") .build(); UserDetails admin = User.withDefaultPasswordEncoder() .username("admin") .password("1111") .roles("ADMIN") .build(); return new InMemoryUserDetailsManager(user, admin); } } @Configuration class config2 { @Bean public SecurityFilterChain userfilterChain(HttpSecurity http) throws Exception { http.authorizeRequests() .requestMatchers("/user/**").hasRole("USER") .anyRequest().authenticated() .and() .formLogin() ; return http.build(); } } 스프링 시큐리티가 최근부터 Bean으로 설정을 해야하며, 강의에서 나온 antmatchers()와 같은 함수명이 바뀌어 구글링을 하며 만들어보고자 도전해보고 있습니다. 해당 강의 중 "다중 보안 설정"에 대한 내용과 유사하게 구현해보고자 하였으나, 마음처럼 되지 않아 질문을 남김니다.제가 구현하고 싶은 형태는 localhost:8080/user >> formLogin() 페이지로 이동하게 되고, 이와 다르게 localhost:8080/admin >> httpBasic() 페이지로 이동하도록 구현하고자 합니다. 하지만, 생각과는 다르게 admin 경로가 처리가 안되는 것을 확인하였습니다. 이에 대해 조언을 구하고자 합니다.
-
미해결스프링 시큐리티 OAuth2
소셜 로그인 후 JWT 발급과 요청 시 access token담아 보내기 에러
https://github.com/YuYoHan/project_study1 전체 링크입니다. 일단, 시큐리티 컨피그 중 Oauth2에 관련된 부분입니다. 방식은 REST 방식입니다. http // oauth2Login() 메서드는 OAuth 2.0 프로토콜을 사용하여 소셜 로그인을 처리하는 기능을 제공합니다. .oauth2Login() // .defaultSuccessUrl("/success-oauth") // OAuth2 로그인 성공 이후 사용자 정보를 가져올 때 설정 담당 .userInfoEndpoint() // OAuth2 로그인 성공 시, 후작업을 진행할 서비스 .userService(principalOauth2UserService) .and() .defaultSuccessUrl("/success-oauth"); 저는 현재 생각하는 방식이 소셜 로그인을 성공하면 PrincipalOauth2UserService 에서 Member 테이블에 넣어주고 save까지 해서 로직을 구현했습니다. 그리고 실행해본 결과 로그로 제대로 값이 등록되어 있는 것을 볼 수 있었습니다.package com.example.project1.config.oauth2; import com.example.project1.config.auth.PrincipalDetails; import com.example.project1.config.oauth2.provider.GoogleUserInfo; import com.example.project1.config.oauth2.provider.NaverUserInfo; import com.example.project1.config.oauth2.provider.OAuth2UserInfo; import com.example.project1.domain.member.UserType; import com.example.project1.entity.member.MemberEntity; import com.example.project1.repository.member.MemberRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import java.util.Map; @Service @Slf4j @RequiredArgsConstructor public class PrincipalOauth2UserService extends DefaultOAuth2UserService { private final BCryptPasswordEncoder bCryptPasswordEncoder; private final MemberRepository memberRepository; // 구글로부터 받은 userReuest 데이터에 대한 후처리되는 함수 @Override public PrincipalDetails loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { // registrationId로 어떤 OAuth로 로그인 했는지 확인가능 log.info("clientRegistration : " + userRequest.getClientRegistration() ); log.info("accessToken : " + userRequest.getAccessToken().getTokenValue() ); OAuth2User oAuth2User = super.loadUser(userRequest); // 구글 로그인 버튼 클릭 →구글 로그인 창 → 로그인 완료 → code 를 리턴(OAuth-Client 라이브러리) → AccessToken 요청 // userRequest 정보 → 회원 프로필 받아야함(loadUser 함수 호출) → 구글로부터 회원 프로필을 받아준다. log.info("getAttributes : " + oAuth2User.getAttributes()); // 회원가입을 강제로 진행 OAuth2UserInfo oAuth2UserInfo = null; if(userRequest.getClientRegistration().getRegistrationId().equals("google")) { log.info("구글 로그인 요청"); oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes()); } else if(userRequest.getClientRegistration().getRegistrationId().equals("naver")) { log.info("네이버 로그인 요청"); // 네이버는 response를 json으로 리턴을 해주는데 아래의 코드가 받아오는 코드다. // response={id=5SN-ML41CuX_iAUFH6-KWbuei8kRV9aTHdXOOXgL2K0, email=zxzz8014@naver.com, name=전혜영} // 위의 정보를 NaverUserInfo에 넘기면 oAuth2UserInfo = new NaverUserInfo((Map)oAuth2User.getAttributes().get("response")); } else { log.info("구글과 네이버만 지원합니다."); } // 사용자가 로그인한 소셜 서비스(provider)를 가져옵니다. // 예를 들어, "google" 또는 "naver"와 같은 값을 가질 수 있습니다. String provider = oAuth2UserInfo.getProvider(); // 사용자의 소셜 서비스(provider)에서 발급된 고유한 식별자를 가져옵니다. // 이 값은 해당 소셜 서비스에서 유니크한 사용자를 식별하는 용도로 사용됩니다. String providerId = oAuth2UserInfo.getProviderId(); // 예) google_109742856182916427686 String userName = provider + "_" + providerId; String password = bCryptPasswordEncoder.encode("get"); // 사용자의 이메일 주소를 가져옵니다. 소셜 서비스에서 제공하는 이메일 정보를 사용합니다. String email = oAuth2UserInfo.getEmail(); // 사용자의 권한 정보를 설정합니다. UserType. // 여기서는 소셜로그인으로 가입하면 무조건 User로 권한을 주는 방식으로 했습니다. UserType role = UserType.USER; // 이메일 주소를 사용하여 이미 해당 이메일로 가입된 사용자가 있는지 데이터베이스에서 조회합니다. MemberEntity member = memberRepository.findByUserEmail(email); if(member == null) { log.info("OAuth 로그인이 최초입니다."); log.info("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓"); log.info("OAuth 자동 회원가입을 진행합니다."); member = MemberEntity.builder() .userName(userName) .userPw(password) .userEmail(email) .userType(role) .provider(provider) .providerId(providerId) .build(); log.info("userEmail : " + member.getUserEmail()); log.info("userName : " + member.getUserName()); log.info("userPw : " + member.getUserPw()); log.info("userType : " + member.getUserType()); log.info("provider : " + member.getProvider()); log.info("providerId : " + member.getProviderId()); memberRepository.save(member); } else { log.info("로그인을 이미 한적이 있습니다. 당신은 자동회원가입이 되어 있습니다."); log.info("userEmail : " + member.getUserEmail()); log.info("userName : " + member.getUserName()); log.info("userPw : " + member.getUserPw()); log.info("userType : " + member.getUserType()); log.info("provider : " + member.getProvider()); log.info("providerId : " + member.getProviderId()); } // attributes가 있는 생성자를 사용하여 PrincipalDetails 객체 생성 // 소셜 로그인인 경우에는 attributes도 함께 가지고 있는 PrincipalDetails 객체를 생성하게 됩니다. return new PrincipalDetails(member, oAuth2User.getAttributes()); } } 이제 @AuthenticationPrincipal OAuth2User oAuth2User를 사용하면 소셜 로그인한 정보를 가져와서 JWT 발급하는데 사용할 수 있다고 들었는데 @GetMapping("/success-oauth") public ResponseEntity<?> createTokenForGoogle(@AuthenticationPrincipal OAuth2User oAuth2User) { if(oAuth2User == null) { log.info("받아올 정보가 없습니다 ㅠㅠ"); return ResponseEntity.status(HttpStatus.NOT_FOUND).body("정보가 없어...."); } else { log.info("oauth2User 정보를 받아오자 : " + oAuth2User); // OAuth2User에서 필요한 정보를 추출하여 UserDetails 객체를 생성합니다. ResponseEntity<TokenDTO> token = memberService.createToken(oAuth2User); log.info("token : " + token); return ResponseEntity.ok().body(token); } }@AuthenticationPrincipal OAuth2User oAuth2User를 사용해서 정보를 받아와서 null이 아닐 경우MemberService // 소셜 로그인 성공시 jwt 반환 // OAuth2User에서 필요한 정보를 추출하여 UserDetails 객체를 생성하는 메서드 public ResponseEntity<TokenDTO> createToken(OAuth2User oAuth2User) { String userEmail = oAuth2User.getAttribute("email"); log.info("userEmail in MemberService : " + userEmail); MemberEntity findMember = memberRepository.findByUserEmail(userEmail); // 권한 정보 추출 List<GrantedAuthority> authorities = getAuthoritiesForUser(findMember); // UserDetails 객체 생성 (사용자의 아이디 정보를 활용) // 첫 번째 인자 : username 사용자 아이디 // 두 번째 인자 : 사용자의 비밀번호 // 세 번째 인자 : 사용자의 권한 정보를 담은 컬렉션 UserDetails userDetails = new User(userEmail, null, authorities); log.info("userDetails in MemberService : " + userDetails); TokenDTO token = jwtProvider.createToken2(userDetails); log.info("token in MemberService : " + token); return ResponseEntity.ok().body(token); } private List<GrantedAuthority> getAuthoritiesForUser(MemberEntity member) { // 예시: 데이터베이스에서 사용자의 권한 정보를 조회하는 로직을 구현 // member 객체를 이용하여 데이터베이스에서 사용자의 권한 정보를 조회하는 예시로 대체합니다. UserType role = member.getUserType(); // 사용자의 권한 정보를 가져오는 로직 (예시) List<GrantedAuthority> authorities = new ArrayList<>(); authorities.add(new SimpleGrantedAuthority("ROLE_" +role.name())); log.info("role in MemberService : " + role.name()); log.info("authorities in MemberService : " + authorities); return authorities; }JwtProvider public TokenDTO createToken2(UserDetails userDetails) { long now = (new Date()).getTime(); Date now2 = new Date(); // userDetails.getAuthorities()는 사용자의 권한(authorities) 정보를 가져오는 메서드입니다. // claims.put("roles", userDetails.getAuthorities()) 코드는 사용자의 권한 정보를 클레임에 추가하는 것입니다. // 클레임에는 "roles"라는 키로 사용자의 권한 정보가 저장되며, 해당 권한 정보는 JWT의 페이로드 부분에 포함됩니다. Claims claims = Jwts.claims().setSubject(userDetails.getUsername()); claims.put("auth", userDetails.getAuthorities()); log.info("claims : " + claims); // access token Date accessTokenExpire = new Date(now + this.accessTokenTime); String accessToken = Jwts.builder() .setSubject(userDetails.getUsername()) .setClaims(claims) .setIssuedAt(now2) .setExpiration(accessTokenExpire) .signWith(key,SignatureAlgorithm.HS256) .compact(); // RefreshToken 생성 Date refreshTokenExpire = new Date(now + this.refreshTokenTime); String refreshToken = Jwts.builder() .setIssuedAt(now2) .setClaims(claims) .setExpiration(refreshTokenExpire) .signWith(key, SignatureAlgorithm.HS256) .compact(); return TokenDTO.builder() .grantType("Bearer ") .accessToken(accessToken) .refreshToken(refreshToken) .userEmail(userDetails.getUsername()) .build(); }이런식으로 로직을 짰는데 지금 생각하는 방식이 소셜 로그인이 성공했을 경우 주소, 권한(USER or ADMIN) 를 추가적으로 넣고 싶은데 소셜 로그인으로 어떻게 해야할지 감이 안잡힙니다 ㅠㅠ 그리고 컨트롤러에서 제대로 정보를 못가지고 오는거 같습니다.PrincipalOauth2UserService에서 return new PrincipalDetails(member, oAuth2User.getAttributes());이렇게 보내줬는데 PrincipalDetails에서package com.example.project1.config.auth; import com.example.project1.entity.member.MemberEntity; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.oauth2.core.user.OAuth2User; import java.util.ArrayList; import java.util.Collection; import java.util.Map; @Setter @Getter @ToString @NoArgsConstructor @Slf4j public class PrincipalDetails implements UserDetails, OAuth2User { // 일반 로그인 정보를 저장하기 위한 필드 private MemberEntity member; // OAuth2 로그인 정보를 저장하기 위한 필드 // attributes는 Spring Security에서 OAuth2 인증을 수행한 후에 사용자에 대한 추가 정보를 저장하는 데 사용되는 맵(Map)입니다. // OAuth2 인증은 사용자 인증 후에 액세스 토큰(Access Token)을 발급받게 되는데, // 이 토큰을 사용하여 OAuth2 서비스(provider)로부터 사용자의 프로필 정보를 요청할 수 있습니다. // 예를 들어, 소셜 로그인을 사용한 경우에는 attributes에는 사용자의 소셜 서비스(provider)에서 제공하는 프로필 정보가 담겨 있습니다. // 소셜 로그인 서비스(provider)마다 제공하는 프로필 정보가 다를 수 있습니다. // 일반적으로 attributes에는 사용자의 아이디(ID), 이름, 이메일 주소, 프로필 사진 URL 등의 정보가 포함됩니다. /* * 구글의 경우 * { "sub": "100882758450498962866", // 구글에서 발급하는 고유 사용자 ID "name": "John Doe", // 사용자 이름 "given_name": "John", // 이름(이름 부분) "family_name": "Doe", // 성(성(성) 부분) "picture": "https://lh3.googleusercontent.com/a/AAcHTtdzQomNwZCruCcM0Eurcf8hAgBHcgwvbXEBQdw3olPkSg=s96-c", // 프로필 사진 URL "email": "johndoe@example.com", // 이메일 주소 "email_verified": true, // 이메일 주소 인증 여부 "locale": "en" // 지역 설정 } * */ private Map<String, Object> attributes; // 일반 로그인 public PrincipalDetails(MemberEntity member) { this.member = member; } // OAuth2 로그인 public PrincipalDetails(MemberEntity member, Map<String, Object> attributes) { this.member = member; this.attributes = attributes; } // 해당 유저의 권한을 리턴하는 곳 @Override public Collection<? extends GrantedAuthority> getAuthorities() { Collection<GrantedAuthority> collection = new ArrayList<>(); collection.add(new SimpleGrantedAuthority("ROLE_" + member.getUserType().toString())); log.info("collection : " + collection); return collection; } // 사용자 패스워드를 반환 @Override public String getPassword() { return member.getUserPw(); } // 사용자 이름 반환 @Override public String getUsername() { return member.getUserEmail(); } // 계정 만료 여부 반환 @Override public boolean isAccountNonExpired() { // 만료되었는지 확인하는 로직 // true = 만료되지 않음 return true; } // 계정 잠금 여부 반환 @Override public boolean isAccountNonLocked() { // true = 잠금되지 않음 return true; } // 패스워드의 만료 여부 반환 @Override public boolean isCredentialsNonExpired() { // 패스워드가 만료되었는지 확인하는 로직 // true = 만료되지 않음 return true; } // 계정 사용 가능 여부 반환 @Override public boolean isEnabled() { // 계정이 사용 가능한지 확인하는 로직 // true = 사용 가능 return true; } @Override public Map<String, Object> getAttributes() { return attributes; } @Override // OAuth2 인증에서는 사용되지 않는 메서드이므로 null 반환 public String getName() { return null; } }생성자를 구현했지만 컨트롤러에서 못받고 있습니다. 추가 질문)postman에서 소셜로그인 테스트를 해서 성공해서 accesstoken을 받았는데 거기서 뭘 어떻게 진행해야 하나요? 거기서 소셜 로그인을 성공하면 바로 토큰을 발급해줘서 요청시 header에 담아서 보내주것을 어떤식으로 해야하나요??추가 질문2)소셜 로그인은 아니지만 발급 받은 access token을 header에 담아서 보내주는 것을 하는 도중java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor at org.springframework.util.Assert.isTrue(Assert.java:121) ~[spring-core-5.3.28.jar:5.3.28] at org.springframework.security.core.userdetails.User.<init>(User.java:110) ~[spring-security-core-5.7.9.jar:5.7.9] at org.springframework.security.core.userdetails.User.<init>(User.java:87) ~[spring-security-core-5.7.9.jar:5.7.9] at com.example.project1.config.jwt.JwtProvider.getAuthentication(JwtProvider.java:231) ~[classes/:na] at com.example.project1.config.jwt.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:62) ~[classes/:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:661) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:427) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:357) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:294) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:373) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:237) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:319) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] 2023-07-22 18:49:55.024 ERROR 11616 --- [nio-8080-exec-6] o.a.c.c.C.[Tomcat].[localhost] : Exception Processing ErrorPage[errorCode=0, location=/error] java.lang.IllegalArgumentException: Cannot pass null or empty values to constructor at org.springframework.util.Assert.isTrue(Assert.java:121) ~[spring-core-5.3.28.jar:5.3.28] at org.springframework.security.core.userdetails.User.<init>(User.java:110) ~[spring-security-core-5.7.9.jar:5.7.9] at org.springframework.security.core.userdetails.User.<init>(User.java:87) ~[spring-security-core-5.7.9.jar:5.7.9] at com.example.project1.config.jwt.JwtProvider.getAuthentication(JwtProvider.java:231) ~[classes/:na] at com.example.project1.config.jwt.JwtAuthenticationFilter.doFilter(JwtAuthenticationFilter.java:62) ~[classes/:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:217) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:112) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:82) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) ~[spring-security-web-5.7.9.jar:5.7.9] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.28.jar:5.3.28] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) ~[spring-web-5.3.28.jar:5.3.28] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:661) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:427) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:357) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:294) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:373) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:237) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:319) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.76.jar:9.0.76] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] 이런 에러가 발생합니다....보니까 public Authentication getAuthentication(String token) { // 토큰 복호화 메소드 Claims claims = parseClaims(token); log.info("claims in JwtProvider : " + claims); if(claims.get("auth") == null) { throw new RuntimeException("권한 정보가 없는 토큰입니다."); } Object auth = claims.get("auth"); log.info("auth in JwtProvider : " + auth); // 클레임 권한 정보 가져오기 List<String> authorityStrings = (List<String>) claims.get(AUTHORITIES_KEY); Collection<? extends GrantedAuthority> authorities = authorityStrings.stream() .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); // UserDetails 객체를 만들어서 Authentication 리턴 UserDetails principal = new User(claims.getSubject(), "", authorities); return new UsernamePasswordAuthenticationToken(principal, token, authorities); } 여기서 오류가 생기는거 같습니다. log.info("auth in JwtProvider : " + auth); 찍으면 auth in JwtProvider : [ROLE_USER] 이렇게 나옵니다
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
default_batch_fetch_size 크기 질문
강의에서default_batch_fetch_size가 100이고,OrderItem의 크기는 2개,Item의 크기는 4개 입니다default_batch_fetch_size를 정할때 OrderItem의 크기와 Item의 크기를 더한 값인가요? 아니면 OrderItem의 크기만 인건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
메인 오류
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.실행시키면 실행이 되다가 갑자기 이런 오류가 뜹니다... 설정이나 설치 등은 그대로 따라했습니다.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
질문있습니다
강사님이 올려주신 파일이 아니라 Spring Initializr여기서 직접 생성한 다음에 프로젝트를 진행하려고 하는데 이노테이션 ?에노테이션이 안먹습니다.. 아마 그래들 파일 문제인것 같은데 강사님 올려주신 동영상에는 그래들파일 수정하라는 말은 없었거든요 ;; 빠른답변 부탁드립니다 그리고 MYSQL 설치할떄도 디폴트디벨로퍼 항목이 없습니다;; 강좌 왜이런지 ;;
-
미해결생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현
안녕하세요 강사님 active profiles 관련해서 궁금한게 있습니다
보통 아래와같이yml 파일에 이 yml의 profiles가 dev야 라고 명시 해주고 spring: profiles: dev인텔리제이 active profiles에서 dev를 넣어주면매칭이 되는걸로 알고있는데,별도로 안적어주면application-과 .yml 사이에 있는 파일명을 profiles로 인식을 하는건가요?yml 설정 (3) 강의 보고 질문드립니다!
-
해결됨[개념은 호옹~, 실습 빡] 스프링 부트, 입문!
17강 Unique index or primary key violation
안녕하세요 홍팍님17강 듣는 중 에러 발생으로 질문있습니다강의 6분대 정도의 위 사진까지 진도를 나가고 http://localhost:8080/articles/에서 새 아티클을 생성하면 위 페이지가 나옵니다에러문구는 아래와 같습니다2023-07-21 16:32:25.979 INFO 18712 --- [nio-8080-exec-2] c.e.f.controller.ArticleController : ArticleForm(id=null, title=DDDD, content=4444) 2023-07-21 16:32:25.980 INFO 18712 --- [nio-8080-exec-2] c.e.f.controller.ArticleController : Article(id=null, title=DDDD, content=4444) 2023-07-21 16:32:26.032 DEBUG 18712 --- [nio-8080-exec-2] org.hibernate.SQL : insert into article (id, content, title) values (default, ?, ?) 2023-07-21 16:32:26.034 TRACE 18712 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [VARCHAR] - [4444] 2023-07-21 16:32:26.034 TRACE 18712 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [VARCHAR] - [DDDD] 2023-07-21 16:32:26.037 WARN 18712 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23505, SQLState: 23505 2023-07-21 16:32:26.038 ERROR 18712 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.ARTICLE(ID) ( /* key:1 */ CAST(1 AS BIGINT), '1111', 'dummy1')"; SQL statement: insert into article (id, content, title) values (default, ?, ?) [23505-214] 2023-07-21 16:32:26.056 ERROR 18712 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["PRIMARY KEY ON PUBLIC.ARTICLE(ID) ( /* key:1 */ CAST(1 AS BIGINT), '1111', 'dummy1')"; SQL statement: insert into article (id, content, title) values (default, ?, ?) [23505-214]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Unique index or primary key violation: "PRIMARY KEY ON PUBLIC.ARTICLE(ID) ( /* key:1 */ CAST(1 AS BIGINT), '1111', 'dummy1')"; SQL statement: insert into article (id, content, title) values (default, ?, ?) [23505-214]아티클을 전부 다 지우고 몇개를 새로 생성하면 id값이 2번부터 생성돼요.1, 2번 아티클을 지우고 새 아티클을 만들면 4번이 생성됩니다.도와주십셔 스프링부트 버전 data.sqlbuild.gradleplugins { id 'java' id 'org.springframework.boot' version '2.7.13' id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.example' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '11.0.19.7' } repositories { mavenCentral() } dependencies { // add lombok compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-mustache' implementation 'org.springframework.boot:spring-boot-starter-web' runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation fileTree(dir: 'lib', include: ['*.jar']) } tasks.named('test') { useJUnitPlatform() } application.property
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
mysql 설치 중 질문
mysql 설치 중 developer default라는게 안떠서 custom을 눌러서 connector들을 직접 추가해주려고 하는데 현재 8.0.34 버전은 안뜨네요 혹시 connector는 다른 버전을 설치해도 될까요? 그리고 만약 설치한다면 x86으로 돼있던데 제 컴퓨터는 64비트인데 설치해도 되는건가요??아 그리고 제가 예전에 mysql을 설치했었다가 오류가 떠서 완전히 지우고 이번에 다시 설치하는겁니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
H2에 member테이블이 생성안됨
섹션1의 h2데이터베이스 설치에서 설명한대로 하고 있는데접속은 되는데 계속 member 테이블 생성이 안되네요ㅠㅠ.yml 파일도 바꿔보고 dependencies도 비슷한 질문들 찾아가면서 다 바꿨는데 왜 이러는건지 모르겠네요jpahsop.mv.db도 제대로 생성된 상황입니다. 이게 제 yml파일이고spring: config: import: device.yml datasource: url: jdbc:h2:tcp://localhost/~/jpashop username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: # 알아서 table을 생성해줌 ddl-auto: create properties: hibernate: format_sql: true logging.level: org.hibernate.SQL: debug org.hibernate.type: trace 이건 gradle.build의 dependencies입니다dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-jdbc' testImplementation 'junit:junit:4.13.1' testImplementation 'junit:junit:4.13.1' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' }강사님께서는 run하면 console창에 create Member가 뜨는데 저는 안뜨는게 주원인인거 같습니다...어딜 손봐야하는 걸까요??
-
미해결스프링 부트 - 핵심 원리와 활용
서블릿
@WebServlet가 잘 이해가 가지 않아서 질문드립니다. 1) @WebServlet 애노테이션은 web.xml과 연동? 된다고 생각하면 될까요? 2) @WebServlet을 사용한 클래스 내에 서블릿 초기화 처럼 디스패처 서블릿을 등록하여도 될까요? 3) @WebServlet은 web.xml 사용시 사용하는 애노테이션이고, 나머지 서블릿 초기화들은 web.xml 대신 사용하는 프로그래밍 초기화라고 생각하면 될까요?
-
미해결스프링 부트 - 핵심 원리와 활용
빈등록
@RestController 에노테이션 사용후 HelloConfig내 @ComponentScan을 사용하면 자동으로 빈이 등록되는걸로 알고있는데, 굳이 수동 빈 등록을 한 이유를 알 수 있을까요?명시적으로 보여주기 위함일까요?
-
미해결스프링 시큐리티 OAuth2
boot 3.0 이상에서의 질문입니다.
boot 3.0 이상에서는 2.7과 다르게 spring security 의 변경된 부분이 많던데 혹시 해당 수업의 3.0 이상이 적용된 예제 소스나 수업 내용을 3.0에서 구현하려면 2.7 과 어떤 부분을 변경 해야하는것이 있는지 알 수 있을까요 ㅠㅠ? 수업을 듣다가 3.0이상으로 구현해 보려고 했는데 안되서 질문드립니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
안녕하세요 질문있습니다~!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요!강의 듣다가 궁금한 점이 생겨서요!섹션6 스프링 DB 접근 기술 - 스프링 통합테스트 후반부를 듣다가 생긴 궁금증입니다~! MemberServiceTest 와 MemberServiceIntegrationTest 설명을 해주시면서 자바 코드로만 돌아갈 수 있는 순수한 단위 테스트가 좋을 확률이 높다고 하셨는데요자바 코드로만 돌아가는 MemberServiceTest는 실제 DB를 연결하지 않았잖아요그럼 보통 실무에서도 순수한 단위 테스트는 이렇게 MemoryMemberRepository의 형식으로 만들어서 단위 테스트를 진행 하는 건가요? MemberServiceTest와 MemberServiceIntegrationTest의 차이점은 DB를 연결하고/안하고의 차이, 그로인해 스프링컨테이너 연결 유무의 차이.. 맞죠..?
-
해결됨스프링 부트 - 핵심 원리와 활용
test 실행시 DB 저장 에러
위에 SPRING 은 표기됐니다. 서버 실행에는 문제가 없는데 DB에 문제가 있네요 PreparedStatementCallback; SQL [insert into member(member_id, name) values(?,?)]; NULL not allowed for column "MEMBER_ID"; SQL statement: insert into member(member_id, name) values(?,?) [23502-214] org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [insert into member(member_id, name) values(?,?)]; NULL not allowed for column "MEMBER_ID"; SQL statement: insert into member(member_id, name) values(?,?) [23502-214] at app//org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:95) at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) at app//org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1538) at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:667) at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:960) at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1015) at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1025) at app//hello.member.MemberRepository.save(MemberRepository.java:23) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at app//org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) at app//org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at app//org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:752) at app//org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at app//org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at app//org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:752) at app//org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703) at app//hello.member.MemberRepository$$SpringCGLIB$$0.save(<generated>) at app//hello.member.MemberRepositoryTest.memberTest(MemberRepositoryTest.java:21) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "MEMBER_ID"; SQL statement: insert into member(member_id, name) values(?,?) [23502-214] at app//org.h2.message.DbException.getJdbcSQLException(DbException.java:508) at app//org.h2.message.DbException.getJdbcSQLException(DbException.java:477) at app//org.h2.message.DbException.get(DbException.java:223) at app//org.h2.message.DbException.get(DbException.java:199) at app//org.h2.table.Column.validateConvertUpdateSequence(Column.java:365) at app//org.h2.table.Table.convertInsertRow(Table.java:926) at app//org.h2.command.dml.Insert.insertRows(Insert.java:167) at app//org.h2.command.dml.Insert.update(Insert.java:135) at app//org.h2.command.dml.DataChangeStatement.update(DataChangeStatement.java:74) at app//org.h2.command.CommandContainer.update(CommandContainer.java:169) at app//org.h2.command.Command.executeUpdate(Command.java:252) at app//org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:209) at app//org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:169) at app//com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) at app//com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) at app//org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:965) at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651) ... 103 more MemberRepositoryTest > memberTest() FAILED org.springframework.dao.DataIntegrityViolationException at MemberRepositoryTest.java:21 Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException at MemberRepositoryTest.java:21 2023-07-21T02:27:25.304+09:00 INFO 12264 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2023-07-21T02:27:25.306+09:00 INFO 12264 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 1 test completed, 1 failed > Task :test FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':test'. > There were failing tests. See the report at: file:///C:/Users/seongmun/spring/start/autoconfig/build/reports/tests/test/index.html * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 5s 4 actionable tasks: 2 executed, 2 up-to-date 테스트 코드입니다. 에러를 찾으려고아래부터 주석처리했는데, save에서 에러가 뜨더라구요! save도 영상처럼 그대로 작성했는데,어디서 에러가 뜬걸까요?
-
미해결[개념은 호옹~, 실습 빡] 스프링 부트, 입문!
8강 에러 질문있습니다.
전부 정상적으로 입력했는데 논리적이지않다고 에러가뜨네요 ㅜㅜ repository 입니다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
Filter우선순위 질문
안녕하세요! MSA강의 섹션2 Logging Filter관련 부분 듣다가 필터 우선순위와 관련된 궁금증이 생겨서 질문 남깁니다! GatewayFilter filter = new OrderedGatewayFilter((exchange, chain) -> { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); log.info("Logging Filter base message: {}",config.getBaseMessage()); if(config.isPreLogger()){ log.info("Logging Filter Start: request uri -> {}",request.getURI()); } //Custom Post Filter return chain.filter(exchange).then(Mono.fromRunnable(()->{ if(config.isPostLogger()){ log.info("Logging Filter End: response Code -> {}",response.getStatusCode()); } })); }, Ordered.HIGHEST_PRECEDENCE); return filter;위와 같은 방식으로 OrderedGatewayFilter를 사용해 filter를 생성했는데 이때 두번째 인자로 Ordered.HIGHEST_PRECEDENCE를 사용할 때와 Ordered.LOWEST_PRECEDENCE를 사용할 때 등장하는 filter 우선순위와 관련된 궁금증이 생겼습니다.HIGHEST를 사용할때는 우선순위가 높은 필터가 먼저 나와서 강의에서도 그렇고 코드 실행결과LoggingFIlter -> GlobalFilter -> CustomFilter의 순서로 Filter 가 등장했는데 그렇다면, 반대로 우선순위가 낮은 경우인 LOWEST를 사용할 때는 CustomFilter -> GlobalFilter -> LoggingFIlter의 순서로 filter가 등장해야한다고 생각하는데 결과가 그렇지 않아서 우선순위에 어떠한 개념이 있는지, 제가 어떤 개념을 놓치고 있는지 의문이 들어 질문글 남깁니다!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MappingJackson2HttpMessageConverter가 JsonConverter인가요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]MappingJackson2HttpMessageConverter가 JsonConverter인가요?