묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 기본편
MyLogger 를 Interceptor 로 구현 시 질문
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요? 강의를 듣다가 requesURL 같은 경우 Interceptor 에서 멤버 변수로 저장하는 것이 좋다고 해서 구현을 해보려고 했는데 문제가 생겨서 질문 드립니다.## 앞으로 강좌를 계속 듣긴 할 거라서 혹시 뒤의 강좌를 듣고 나면 해결될 수 있는 문제라면 어느 강좌인지 알려주셔도 될 것 같습니다. MyLogger.javapackage hello.core.common; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.util.UUID; @Component @Scope(value = "request") public class MyLogger { private String uuid; private String requestURL; public void setRequestURL(String requestURL) { this.requestURL = requestURL; } public void log(String message) { System.out.println("[" + uuid + "]" + "[" + requestURL + "] " + message); } @PostConstruct public void init() { uuid = UUID.randomUUID().toString(); System.out.println("[" + uuid + "] request scope bean create: " + this); } @PreDestroy public void close() { System.out.println("[" + uuid + "] request scope bean close: " + this); } } CoreInterceptor.javapackage hello.core.common; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component @RequiredArgsConstructor public class CoreInterceptor implements HandlerInterceptor { private final ObjectProvider<MyLogger> myLoggerProvider; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("CoreInterceptor.preHandle"); String requestURL = request.getRequestURL().toString(); MyLogger myLogger = myLoggerProvider.getObject(); myLogger.setRequestURL(requestURL); return HandlerInterceptor.super.preHandle(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } } WebMvcConfig.javapackage hello.core.common; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @RequiredArgsConstructor public class WebMvcConfig implements WebMvcConfigurer { private final ObjectProvider<MyLogger> myLoggerProvider; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new CoreInterceptor(myLoggerProvider)).excludePathPatterns("/css/**", "/images/**", "/js/**"); } } LogDemoController.javapackage hello.core.web; import hello.core.common.MyLogger; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; @Controller @RequiredArgsConstructor public class LogDemoController { private final LogDemoService logDemoService; private final ObjectProvider<MyLogger> myLoggerProvider; @RequestMapping("log-demo") @ResponseBody public String logDemo(HttpServletRequest request) { String requestURL = request.getRequestURL().toString(); MyLogger myLogger = myLoggerProvider.getObject(); myLogger.log("controller test"); logDemoService.logic("testId"); return "OK"; } } LogDemoService.javapackage hello.core.web; import hello.core.common.MyLogger; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class LogDemoService { private final ObjectProvider<MyLogger> myLoggerProvider; public void logic(String id) { MyLogger myLogger = myLoggerProvider.getObject(); myLogger.log("service id = " + id); } } 위와 같이 이렇게 구현을 해보니 문제가 생기는데...일단, 인터셉터를 스프링 빈으로 등록하면서 MyLogger 를 활용하려면 알려주신 ObjectProvider 를 사용해야 할 것 같은데... WebMvcConfig 에서 인터셉터를 등록하는 경우, 위의 경우처럼 처음 서버 구동 시에 처리되어야 하는데 이 때는 reqeust 를 사용할 수 없는 문제입니다. 앞서 이 문제를 ObjectProvider 로 해결했는데 Interceptor 의 경우, 나중에 등록이 안 될 것 같은데 이런 경우 어떻게 해결해야 될까요?저렇게 인터셉터를 null 로 호출하니 실행해 보면 WebMvcConfig.java -> registry.addInterceptor(new CoreInterceptor(null))...java.lang.NullPointerException: Cannot invoke "org.springframework.beans.factory.ObjectProvider.getObject()" because "this.myLoggerProvider" is null위와 같은 에러가 발생합니다.관련된 소스 첨부하였습니다.도움 부탁 드립니다. 위의 소스는 제대로 된 걸로 다시 첨부하였습니다.registry.addInterceptor(new CoreInterceptor(null))...->private final ObjectProvider<MyLogger> myLoggerProvider; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new CoreInterceptor(myLoggerProvider)).excludePathPatterns("/css/**", "/images/**", "/js/**"); } 위와 같이 수정하였습니다. 이런 저런 버그들과 강의에서 가르쳐 주신 ObjectProvider 를 사용해서 설정파일에서 request 가 들어오는 시점에 로그를 주입해서 처리되도록 수정하였습니다.Interceptor 에서는 왜 ObjectProvider 를 사용하지 못할 거라고 생각했는지 모르겠네요. 답변 글 보고 질문을 수정하다가 생각이 나서 소스를 수정해 보니 잘 되는 것 같네요.감사합니다.
-
미해결스프링 시큐리티 OAuth2
Resources Server 질문
안녕하세요 수원님 ! 강의를 수강하다가 헷갈리는 내용이 생겨 질문드립니다 ! 위와 같은 그림을 설명하실때, 스프링 서버는 Client 의 역할을 하신다고 하셨습니다. 이후 Resource Server 를 강의하시는 파트에서는 스프링 서버가 리소스 서버가 된다고 하셨는데, 이 부분에서 혼동이 발생하여 질문드립니다. 카카오와 같은 소셜 로그인 기능을 구현한다고 가정하겠습니다.스프링 서버가 JWT 의 의존성을 갖고, 프론트에게 토큰을 발행해주는 서비스를 구현한다면, 이때 스프링 서버는 Client 와 Resourse Server 의 역할을 동시에 하는 것일까요??위와 같은 구조에서 토큰을 프론트에 발행할 때, 스프링은 카카오 인가 서버로 부터 토큰을 받고 해당 토큰을 그대로 내려주는 것일까요?? 보안상 문제가 발생하니 발급 받은 토큰을 기반으로 새로운 JWT 생성해서 내려주는 것일까요??소셜 로그인을 연동했다면, issuer-uri 에는 카카오의 인가 서버 Url 을 입력 하면 될까요??
-
미해결스프링 시큐리티 OAuth2
intellij 에서 스프링부트2.7.1 이 없어요
인텔리제이에서 하려고 합니다. 그런데 2.7.1도 없고 2.x.x중에 하나를 골랐는데 에러가 뜹니다. >=3.0.0-M1 이라고 처음부터 뜨고, 그냥 무시하고 만들어서 실행해보면 아예 빨간글이 쫙쫙 그어지면서 에러가 뜹니다. 이거를 어떻게 해결해야할지 모르겠습니다... 도와주세요...ㅠㅠㅠㅠ
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
@PostConstruct 애노테이션이 정확히 뭔가요?
@PostConstruct 이 애노테이션이 좀 생소해서요 뭔가 생성자에 관한것 같은데요 정확히 어떤 역할을 하는건가요?
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
ServiceException: Unable to create requested service 뜨는 분들 보세요
ServiceException: Unable to create requested serviceHibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set프로젝트 시작했는데 이런 에러 뜨시는 분들 해결책 공유 드립니다.우선 첫번째로 Mysql 서버가 켜져있는지를 확인해봅니다. Workbench를 켜서 Mysql connect를 해주세요.그래도 안 된다면, 두번째로 application.yaml에 아래처럼 코드를 추가해줍니다.이처럼 database:mysql을 추가해줍니다.이렇게 하면 대부분 해결되실겁니다. ps. 추가적으로 이후에 unknown database라는 주의 문구가 뜨는 분들은 해당 이름으로 database를 아직 만들지 않아서 그렇습니다. url에 들어가는 이름으로 mysql workbench에서 database를 만들어서 진행하세요.
-
해결됨스프링 핵심 원리 - 기본편
애플리케이션 빈 출력하기
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]이렇게 위에 다 뜨는데 맞게 뜬건가요??
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
java.lang.NullPointerException: Cannot invoke because is null 이 떠요
강의를 보며 따라하면서 기존 클래스들을 변형하여 진행할 때 test 코드 작성 시 다음과 같이 에러가 뜹니다처음에는 이런 문구가 뜨고 스프링부트 3.x 를 쓰고있어서 @ExtendWith(SpringExtension.class) //junit 5 로 변경하고 나서야 다음과 같은 문구가 뜹니다.강의에서 @RequiredArgsConstructor 를 쓰면 final을 선언해줘야한다고 해서 강의와 동일하게 진행했으나 service의 join에서 null값이 생기는 것 같은데 어디가 문제인지 모르겠습니다.java.lang.NullPointerException: Cannot invoke because "this." is nullbuild.grable 은 다음과 같습니다.plugins { id 'java' id 'org.springframework.boot' version '3.0.7' id 'io.spring.dependency-management' version '1.1.0' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies {implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' //유효성 검증 implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' //web view implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' // runtimeOnly 'com.mysql:mysql-connector-j' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' // testImplementation 'org.springframework.security:spring-security-test' //JUnit4 추가 testImplementation("org.junit.vintage:junit-vintage-engine") { exclude group: "org.hamcrest", module: "hamcrest-core" } } test { useJUnitPlatform() } tasks.named('test') { useJUnitPlatform() }Userpackage domain; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter //@NotNull public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false) private Long id; //auto increment @Column(name = "email", nullable = false) private String email; //id @Column(length = 200 ,name ="password") private String password; @Column(name = "name", nullable = false) private String name; @Column(name= "phone" ,nullable = false ) private String phone; @Builder public User(){ this.email =email; // this.name=name; } } UserRepositorypackage domain; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import org.springframework.stereotype.Repository; import java.util.List; @Repository public class UserRepository { @PersistenceContext private EntityManager em; public void save(User user){ em.persist(user); } public User findOne(String email) { //email 값으로 멤버값 반환 return em.find(User.class, email); } //리스트조회 public List<User> findAll(){ return em.createQuery("select u from User u", User.class) .getResultList(); } //특정값으로 조회 public List<User> findByName(String name) { return em.createQuery("select u fromUser u where u.name = :name", User.class) .setParameter("name", name) .getResultList(); } } UserServicepackage domain; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional(readOnly = true) @RequiredArgsConstructor //final있는 field 로 생성자 public class UserService { private final UserRepository userRepository; // @Transactional public String join(User user){ validateDuplicateMember(user); // 중복 회원 검증 userRepository.save(user); //error : line 13 선언변수 그대로 가져와야함 return user.getEmail(); } private void validateDuplicateMember(User user){ List<User> findUsers = userRepository.findByName(user.getName()); if(!findUsers.isEmpty()) { throw new IllegalStateException("이미 존재하는 회원입니다."); } } } UserServiceTestpackage domain; import org.junit.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.transaction.annotation.Transactional; import static org.junit.Assert.assertEquals; //메모리 모드 DB 연계 테스트 //@RunWith(SpringRunner.class) //junit 4 @ExtendWith(SpringExtension.class) //junit 5 @SpringBootTest @Transactional //rollback public class UserServiceTest { @Autowired UserService userService; @Autowired UserRepository userRepository; @Test public void 회원가입() throws Exception { //Given User user = new User(); user.setEmail("fitplace@naver.com"); //email 로 검증 -> name은 중복 존재 가능성 o //When String saveEmail = userService.join(user); //Then assertEquals(user, userRepository.findOne(saveEmail)); } // @Test(expected = IllegalStateException.class) // public void 중복_회원_제외() throws Exception { // //Given // // //When // // //Then // // } // }
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
회사에서는 Spring Data JPA를 사용하지 않고 , Query DSL 만 사용합니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 영한님.얼마전에 스타트업에 신입 백엔드 개발자로 입사하였고, 작년부터 영한님 강의를 꾸준히 들어오던 수강생 입니다!저희 회사는 데이터 접근 기술로써 Query DSL로 통일되어 있었는데요, 왜 Spring Data JPA를 사용하지 않냐고 대표님께 문의드리자, Query DSL로 모든 기능을 다 수행할 수 있기에,코드의 일관성과 학습 기술을 줄이기 위해서 라고 답변 받았습니다. 그러나 저는 애초에 JPA를 사용하는 근본적인 이유중 하나가 바로 직접 SQL을 작성하지 않기 때문이라고 생각하고 있기 때문에 , Spring Data JPA를 사용하는게 어떻겠냐고 다시 한번 문의드리고 싶은 상황입니다. 영한님 께서 신입으로 입사한 저의 입장이셨다면, 문의를 드렸을지 생각을 여쭙고 싶습니다. 항상 좋은 강의 및 답변 감사합니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
강의 내용중에 궁금한게 있습니다.
Presentation Layer 테스트 (2)0:59:00 부터 말씀해주신 내용이 대략 이렇습니다.서비스 로직이 커지게 되어 분리를 하거나 모듈화하여 사용한다면controller dto를 하위 레이어인 service에서 알고있으면필요없는 Bean Valid의 의존성을 추가해야하고, 하위레이어가 상위 레이어에 의존성이 생기게 되어 해당 서비스 로직을 다른 컨트롤러에서 사용하고 싶을때 발목을 잡는다.라고 말씀해주셨습니다. 전제 : 확장할 일도 없고, 이 서비스는 해당 컨트롤러에서만 사용하게 되는 구조일 경우Service용 Dto를 만들지 않고 Controller Dto에서 Entity로 변환해서 Service에 넣어주시나요 ?아니면 코드의 일관성을 생각해서 몇분 안걸리니까 만들어서 사용하시나요? 그리고 추가로 궁금한게 있습니다.service 패키지가 api 패키지 내에 존재하는데서비스가 확장되고 모듈화가 되어 사용한다거나 ,다른 컨트롤러에서도 그 서비스를 사용하게 된다면서비스 패키지는 도메인 패키지쪽으로 넣어서api (controller,advice,advice dto),domain( entity(entity,repository), service(service,dto)) 같은 구조로 변경을 하시는지 궁금합니다.그리고 현재 프로젝트에서 api 패키지 안에 service 패키지를 넣으신 이유도 궁금합니다. !! 질문의 영역을 벗어났다는 것을 알지만, 답변을 해주실 수 있으실까요 감사합니다(__)신뢰할만한 답변을 받을 곳이 없어서 질문을 남겨봅니다..답변하시기 어려우시다면 키워드라도 알려주시면 감사합니다!!
-
해결됨스프링 부트 웹 개발 입문 - 따라하며 배우기
가격수정...404오류
404 오류 입니다...소스는 구글로 공유했습니다..
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
양방향 괸계에서 관계 설정 위치에 대한 질문이 있습니다.
회원 - 주문 관계에서 관계를 설정할 때는 주문 엔티티에서 public void setMember(Member member) { this.member = member; member.getOrders().add(this); }이렇게 관계를 설점함과 동시에 주문- 주문상품 -상품 관계를 설정할 때도 주문 엔티티에서 관계를 설정하더라구요public void addOrderItem(OrderItem orderitem){orderItems.add(orderitem);orderitem.setOrder(this);}이 과정은 어느 엔티티에 하던 상관 없는건가요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
테스트코드에서만 적용되는 yml 설정을 하고 싶습니다.
안녕하세요! 실무에서 겪었던 문제에 대한 조언을 구하고 싶습니다.test 하위에 application.yml을 만들면 테스트코드 돌릴 때 해당 yml 설정을 따른다고 배워서 적용했습니다. application-local.ymlapplication-prod.yml이런 식으로 뒤에 - 프로필이 붙은 형태이고테스트 폴더 하위에도application-local.yml파일을 만들었습니다. DB 연결이 안되길래 prod.yml 쪽으로 연결 시도를 하는거 같아테스트 코드에@ActiveProfiles("local")을 붙여주었고 테스트 서버 DB에 잘 붙어서 테스트코드를 작성했습니다.(main/applicatino-local.yml 역시 테스트 서버 DB에 연결되어 있는 상태)테스트코드를 작성하다보니 이게 불편하더라구요그래서 h2 인메모리 DB를 사용하고자 테스트 코드용 yml에 설정을 해주었습니다.jpa ddl auto 설정도 create 였구요..ㅎㅎㅎ 동료 개발자분이 테스트 서비스 로그인이 안된다길래 보니 테스트 디비 데이터가 다 날아갔습니다,,,하하하하정말 식은땀이 주륵..... 다행히 얼마 전에 다른 작업으로 백업을 해둔게 있어서 그걸로 복구했습니다만 정말 아찔했습니다 ㅠㅠ main/appication-local.yml 의 datasource url로 연결하고test/appication-local.yml 의 ddl-auto: create 설정을 따른 것으로 보여지는데왜 이런걸까요?저는 test/appication-local.yml 설정만 따를 거라고 생각했는데.. 제가 원하는 것은 local에서 서버를 직접 띄워서 사용할 때는 test 서버 db에 연결하고 싶고테스트 코드 돌릴 때는 인메모리 h2를 사용하고 싶습니다.이런 경우에 어떻게 사용하면 좋을까요? main/applilcation-local.ymldatssource: 테스트 서버 DB test/applilcation-local.ymldatssource: 인메모리 h2 DBjpa ddlauto: create -> 테스트 서버 디비 데이터 다 날아감내가 원하는 것 : 테스트 코드는 test/applilcation-local.yml 설정만을 따라 인메모리 DB 사용
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
main/application.yml, test/application.yml
안녕하세요! 실무에서 겪었던 문제에 대한 조언을 구하고 싶습니다.강의를 들으며 test 하위에 application.yml을 만들면 테스트코드 돌릴 때 해당 yml 설정을 따른다고 배워서 적용했습니다. application-local.ymlapplication-prod.yml이런 식으로 뒤에 - 프로필이 붙은 형태이고테스트 폴더 하위에도application-local.yml파일을 만들었습니다. DB 연결이 안되길래 prod.yml 쪽으로 연결 시도를 하는거 같아테스트 코드에@ActiveProfiles("local")을 붙여주었고 테스트 서버 DB에 잘 붙어서 테스트코드를 작성했습니다.(main/applicatino-local.yml 역시 테스트 서버 DB에 연결되어 있는 상태)테스트코드를 작성하다보니 이게 불편하더라구요그래서 h2 인메모리 DB를 사용하고자 테스트 코드용 yml에 설정을 해주었습니다.jpa ddl auto 설정도 create 였구요..ㅎㅎㅎ 동료 개발자분이 테스트 서비스 로그인이 안된다길래 보니 테스트 디비 데이터가 다 날아갔습니다,,,하하하하정말 식은땀이 주륵..... 다행히 얼마 전에 다른 작업으로 백업을 해둔게 있어서 그걸로 복구했습니다만 정말 아찔했습니다 ㅠㅠ main/appication-local.yml 의 datasource url로 연결하고test/appication-local.yml 의 ddl-auto: create 설정을 따른 것으로 보여지는데왜 이런걸까요?저는 test/appication-local.yml 설정만 따를 거라고 생각했는데.. 제가 원하는 것은 local에서 서버를 직접 띄워서 사용할 때는 test 서버 db에 연결하고 싶고테스트 코드 돌릴 때는 인메모리 h2를 사용하고 싶습니다.이런 경우에 어떻게 사용하면 좋을까요? main/applilcation-local.ymldatssource: 테스트 서버 DB test/applilcation-local.ymldatssource: 인메모리 h2 DBjpa ddlauto: create -> 테스트 서버 디비 데이터 다 날아감내가 원하는 것 : 테스트 코드는 test/applilcation-local.yml 설정만을 따라 인메모리 DB 사용
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
postman 500 오류
안녕하세요!! 강의 내용에 따라 진행했는데 자꾸 검사결과 다음과 같이 오류가 뜹니다... 원인이 궁금해서 질문올립니다. 감사합니다.
-
미해결스프링부트 시큐리티 & JWT 강의
findByUsername(username)을 사용하는 이유가 궁금합니다.
안녕하세요 강사님 궁금한 점이 해결되지 않아서 질문 남깁니다.강사님 git에 있는 소스를 그대로 갖고 왔습니다.토큰이 정상적인 상황일 때, 즉 username 값이 존재할 때 findByUsername을 사용해서 user객체를 얻는 장면인데 토큰 안에 User객체 자체를 저장해서 불필요한 DB연동을 안 하는 방식은 잘못된 방식인가요?제 생각에는 이렇게 사용하면 토큰에 User 정보가 노출되기 때문에 보안이 취약하다 라고 생각하는데 이 생각이 맞는지 궁금합니다.username은 충분히 겹칠 수 있는 값이라고 생각이 드는데 토큰을 저장할 때 Id값을 저장해서 꺼내오는 방식은 잘못된 방식일까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
intellij 한글깨짐
1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니오3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]인텔리제이 한글꺠짐 해결하려고 아래의 블로그 보고 하라는대로 따라했는데 해결이 안됩니다 ..https://knoow.tistory.com/195인텔리제이 설치 경로의 bin폴더로 가서 idea64.exe.vmotions 파일을 처음에 인텔리제이로 열어서 수정했다가 저장이 안되는 것 같길래 메모장으로 열어서다음과 같이 코드 넣고 저장 눌렀습니다 근데 아이콘도 메모장으로 바뀌고 파일명도 idea64.exe 로 변해서(근데 파일 속성 보면 vmotions 파일은 맞았어요) 다시 idea64.exe.vmotions으로 파일 이름을 변경했어요인텔리제이로 hello spring 프로젝트 열어서 help> edit custom VM options -Dfile.encoding=UTF-8 추가했구요build.gradle 가서 아래처럼 코드도 추가했습니다file > settings > File encodings모든 설정을 다 UTF - 8 로 다 바꿨구요 EUC-KR로도 바꿔서 실행도 해봤습니다 근데도 자꾸 꺠져서 출력됩니다 어떻게 해야하나요 .. 흑흑
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
테스트 트랜잭션
테스트 클래스에서 주로 @Transactional 을 클래스 계층에 선언하고 테스트를 전체 롤백시키는 코드를 자주 사용했었는데 권장되지 않는 방식인가여?? 비즈니스 로직의 트랜잭션에 영향을 끼친다고 하셔서 다른 방법이 어떤 게 있을까 궁금해요.
-
미해결스프링부트 시큐리티 & JWT 강의
key 보관 방법
수업 듣다가 궁금증이 생겨서 남깁니다.key 생성 시에 현재 실습에서는 "cos" 를 사용했는데, 실제로 사용할때는 key를 어떻게 생성하고, 보관해야하는지 궁금합니다.
-
미해결스프링 핵심 원리 - 기본편
Mac OS 기반 인텔리제이 Spring boot 프로젝트 생성 시 발생한 오류
Mac OS 기반 인텔리제이를 설치하고 처음 Spring boot(gradle) 프로젝트 생성 시인텔리제이에서 build하는 과정에서 다음과 같은 오류가 발생합니다.구글링을 해봐도 어떤게 원인인지 해결 방안을 모르겠어서 질문 남겨요! * Exception is: org.gradle.api.UncheckedIOException: java.io.StreamCorruptedException: invalid type code: 00 at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:62) at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:41) at org.gradle.tooling.internal.provider.serialization.PayloadSerializer.deserialize(PayloadSerializer.java:78) at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:51) at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35) at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:49) at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:65) at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:140) at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41) at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:40) at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:122) at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:40) at org.gradle.internal.buildtree.InitDeprecationLoggingActionExecutor.execute(InitDeprecationLoggingActionExecutor.java:58) at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40) at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:65) at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53) at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:65) at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:61) at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:57) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204) at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66) at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157) at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59) at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53) at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73) at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:57) at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36) at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249) at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109) at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36) at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110) at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64) at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46) at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:100) at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:88) at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:69) at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62) at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41) at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:64) at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32) at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:50) at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:38) at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47) at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31) at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78) at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75) at org.gradle.util.internal.Swapper.swap(Swapper.java:38) at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37) at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104) at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52) at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
-
미해결실전! 스프링 데이터 JPA
단방향 연관관계 적용시 질문 있습니다.
일반적으로 양방향 연관관계는 지양하는 것이 좋다고 해서, 단방향 연관관계로 생각을 해보고 있는데요. Member (N) 쪽에만 Team 쪽으로 단방향 연관관계를 설정한 상태인데요. 특정 팀의 멤버들을 알고 싶은 경우가 있을거 같아요. Member 중, team id 가 X 인 것을 찾고 싶은 경우에는 어떻게 해야하나요? fetch join 시에는 별칭을 줄 수 없기 때문에 안될거 같습니다. 이럴때는 그냥 일반 조인문으로 풀어내고, team 정보가 필요하다면 다시 조회하는 것이 맞나요?