묻고 답해요
130만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결토비의 스프링 부트 - 이해와 원리
ProxyBeanMethods = false에 대해 궁금합니다.
MyAutoConfiguration에서 ProxyMethods를 false를 줬으니 Tomcat과 DisPatcherServlet이 호출될떄마다 새로 생성되는건가요??
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
왜 commit할 때 status를 넣어줘야 하나요.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]status는 트랜잭션 설정, 상태에 관한 정보인데, 이미 transactionManager는 생성할 때 dataSource를 넣어줬고, 또 트랜잭션 동기화 매니저가 있기 때문에 어떤 커넥션을 닫아야 할 지 알고 있을 것 같습니다.그럼 commit()할 때난 rollback()할 때 그냥 닫거나 롤백하면 될텐데, 왜 status가 필요한가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
Controller에서 BindingResult값을 유지한채로 @ExceptionHandler를 활용한 사용자 정의 예외를 처리하는법이 궁금합니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Spring data jpa 를 활용하여 지금까지 배운 내용들을 총 합한 프로젝트를 만들어 보고 있는데 한가지 궁금증이 생겨 질문 드립니다. @ExceptionHandler을 사용하여 사용자정의 예외를 만들어 아이디 중복 예외를 처리하고싶은데 예외를 처리하는 과정에서 아이디가 중복일시 Controller의 BindingResult를 활용하여 아이디가 중복이면 View에 아이디가 중복이라는 정보를 표현하고싶어서 프로젝트를 코딩중에 Controller 부분에서 service단에서 throw한 사용자 정의 예외를 처리하려 하는데 try catch로 예외를 처리하는 순간 @ExceptionHandler를 사용하지 못하고 그렇다고 다시 예외를 던지자니 @ExceptionHandler에서 View에 관련된 Binding result의 값이나 ModelAttribute의 값을 보존해지 못하여 처리가 불가합니다. 이럴때 제일 좋은 방법이 무엇인지 알고싶습니다. Controller 코드입니다.@Controller @RequiredArgsConstructor @RequestMapping("/users") public class UserController { private final LoginService loginService; @GetMapping("/add") public String addForm(@ModelAttribute("userDto") UserDto userDto) { return "user/addUserForm"; } @PostMapping("/add") public String save(@Valid @ModelAttribute UserDto userDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "user/addUserForm"; } // if (loginService.signUpIdExists(userDto.getLoginId()) == false){ // bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); // return "user/addUserForm"; // } try { loginService.signUp(userDto); return "redirect:/"; } catch (UserIdExistsException e) { bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); return "user/addUserForm"; } } } Service 코드입니다.@Slf4j @Service @RequiredArgsConstructor public class LoginService { private final UserRepository userRepository; public User login(String loginId, String password) { return userRepository.findByLoginId(loginId).filter(m -> m.getPassword().equals(password)) .orElse(null); } public void signUp(UserDto userDto) { // if(signUpIdExists(userDto.getLoginId()) == false){ // throw new UserIdExistsException("이미 존재하는 아이디입니다."); // } try { Address address = new Address(userDto.getAddressDto().getZipcode(), userDto.getAddressDto().getStreetAdr(), userDto.getAddressDto().getDetailAdr()); User regisUser = new User(userDto.getLoginId(), userDto.getLoginName(), userDto.getPassword(), address); userRepository.save(regisUser); } catch (DataIntegrityViolationException e) { throw new UserIdExistsException("이미 존재하는 아이디입니다."); } } private boolean signUpIdExists(String loginId) { return userRepository.findByLoginId(loginId).isEmpty(); } } @ControllerAdvice 코드입니다.@Slf4j @ControllerAdvice public class ExceptionAdvice { @ExceptionHandler(UserIdExistsException.class) public ModelAndView userIdExHandler(UserIdExistsException e) { log.error("[userIdExistsException] ex", e); return new ModelAndView(); } } UserIdExistsException 코드입니다.public class UserIdExistsException extends RuntimeException{ public UserIdExistsException() { } public UserIdExistsException(String message) { super(message); } } 위 코드는 동작은 확인했지만 사실상 try catch 로 예외를 잡아버려서 @ExceptionHandler가 동작하지 않는 상태입니다. Entity의 아이디값에 unique 옵션을 걸어두어 아이디 중복이 일어날시 DataIntegrityViolationException에러가 일어납니다.추가로 궁금한것예외가 사실상 repository에서 터지는데 인터페이스에는 try catch가 권장되지 않는것으로 알고 통상 Service에서 에러를 처리하는것으로 알아 이렇게 코딩하였는데 이게 올바른건지 모르겠습니다. 예외를 발생시키는 지점을 repository로 옮기는것이 맞나요? Spring data jpa 는 알아서 Spring에 종속된 에러를 출력하는것으로 알고있는데 DataIntegrityViolationException에 속한 예외 두가지를 다른방법으로 처리하고싶으면 ErrorCode를 분석해 If문 으로 사용자 정의 예외를 만들어서 처리해야하나요? bindingresult를 사용하기 위해 어쩔수없이 예외를 throw하였더니 controller까지 예외가 전파되서 코드가 지저분해졌습니다. 이렇게 View에 특정한 값을 보내주어야할때 Controller에 예외를 throw 하지 않고 해결할수있는 좋은 방법이 있나요? 질문이 길고 지저분해서 죄송합니다. 나름 열심히 알아보고 코딩해보아도 잘 모르겠어서 질문남깁니다. 감사합니다.
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
리소스 정리
트랜잭션 매니저의 전체 동작 흐름에서 마지막에 '전체 리소스를 정리한다.' 라고 나와있는데 코드상으로 어디 부분에서 리소스 정리가 일어나는 건가요? 커밋이나 롤백을 하고 리소스 정리를 하는 코드가 내부에 존재하는 건가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
Test 오류 발생 원인이 무엇인지 잘 모르겠습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; import java.sql.SQLException; /** * 트랙잭션 - @Transactional AOP */ @Slf4j //final이 붙거나 @NotNull 이 붙은 필드의 생성자를 자동 생성해주는 롬복 어노테이션 public class MemberServiceV3_3 { private final MemberRepositoryV3 memberRepository; public MemberServiceV3_3( MemberRepositoryV3 memberRepository) { this.memberRepository = memberRepository; } @Transactional //이 메소드를 호출할 때, 트랙잭션을 걸고 시작하겠다는 의미. // 성공하면 커밋 실패하면 롤백을 한다. public void accountTransfer(String fromId, String toId, int money) throws SQLException { bizLogic(fromId, toId, money); } private void bizLogic(String fromId, String toId, int money) throws SQLException { Member fromMember = memberRepository.findById(fromId); Member toMember = memberRepository.findById(toId); memberRepository.update(fromId,fromMember.getMoney()- money); validation(toMember); memberRepository.update(toId,toMember.getMoney()+ money); } private static void validation(Member toMember) { if(toMember.getMemberId().equals("ex")){ throw new IllegalStateException("이제 중 예외 발생. 테스트 위해 만듦"); } } }이것이 원본 코드이고 package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import static hello.jdbc.connection.ConnectionConst.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @SpringBootTest //스프링테스트 어노테이션이 있으면 이 테스트에서 //스프링부트가 이 테스트에서 스프링 컨테이너를 만들고 필요한 스프링 빈을 전부 등록하고 스프링 빈에 대한 의존관계 주입도 받을 수 있게 된다 class MemberServiceV3_3Test { public static final String MEMBER_A = "memberA"; public static final String MEMBER_B = "memberB"; public static final String MEMBER_EX = "ex"; @Autowired // 의존관계 주입을 받아서 사용한다. private MemberRepositoryV3 memberRepository; @Autowired private MemberServiceV3_3 memberService; @TestConfiguration static class TestConfig{ @Bean DataSource dataSource(){ return new DriverManagerDataSource(URL,USERNAME,PASSWORD); } @Bean PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3(){ return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3(){ return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberB = new Member(MEMBER_B, 10000); memberRepository.save(memberA); memberRepository.save(memberB); //when memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberB = memberRepository.findById(memberB.getMemberId()); assertThat(findMemberA.getMoney()).isEqualTo(8000); assertThat(findMemberB.getMoney()).isEqualTo(12000); } @Test @DisplayName("이체중 예외 발생") void accountTransferEx() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberEx = new Member(MEMBER_EX, 10000); memberRepository.save(memberA); memberRepository.save(memberEx); //when assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000)) .isInstanceOf(IllegalStateException.class); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberEx = memberRepository.findById(memberEx.getMemberId()); //memberA의 돈이 롤백 되어야함 assertThat(findMemberA.getMoney()).isEqualTo(10000); assertThat(findMemberEx.getMoney()).isEqualTo(10000); } }이것이 테스트 코드입니다.원본 코드는 따로 수정하지 않았고 테스트 코드만 가져와서 사용했는데 왜 오류가 발생하는지 잘 이해가 안됩니다 설명 부탁드립니다. 오류는 다음과 같이 나옵니다Execution failed for task ':test'.> No tests found for given includes: [hello.jdbc.service.MemberServiceV3_3Test.AopCheck](--tests filter)* 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.Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.For more on this, please refer to https://docs.gradle.org/8.2.1/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.BUILD FAILED in 577ms4 actionable tasks: 1 executed, 3 up-to-date 설명 부탁드립니다
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
MemberServiceV3_3 테스트 코드 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]위는 MemberServiceV3_3 코드의 @Transactional를 사용하는 메소드 부분이고 아래는 MemberServiceV3_3Test 코드입니다.package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import static hello.jdbc.connection.ConnectionConst.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @SpringBootTest //스프링테스트 어노테이션이 있으면 이 테스트에서 //스프링부트가 이 테스트에서 스프링 컨테이너를 만들고 필요한 스프링 빈을 전부 등록하고 스프링 빈에 대한 의존관계 주입도 받을 수 있게 된다 class MemberServiceV3_3Test { public static final String MEMBER_A = "memberA"; public static final String MEMBER_B = "memberB"; public static final String MEMBER_EX = "ex"; @Autowired // 의존관계 주입을 받아서 사용한다. private MemberRepositoryV3 memberRepository; @Autowired private MemberServiceV3_3 memberService; @TestConfiguration static class TestConfig{ @Bean DataSource dataSource(){ return new DriverManagerDataSource(URL,USERNAME,PASSWORD); } @Bean PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3(){ return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3(){ return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberB = new Member(MEMBER_B, 10000); memberRepository.save(memberA); memberRepository.save(memberB); //when memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberB = memberRepository.findById(memberB.getMemberId()); assertThat(findMemberA.getMoney()).isEqualTo(8000); assertThat(findMemberB.getMoney()).isEqualTo(12000); } @Test @DisplayName("이체중 예외 발생") void accountTransferEx() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberEx = new Member(MEMBER_EX, 10000); memberRepository.save(memberA); memberRepository.save(memberEx); //when assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000)) .isInstanceOf(IllegalStateException.class); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberEx = memberRepository.findById(memberEx.getMemberId()); //memberA의 돈이 롤백 되어야함 assertThat(findMemberA.getMoney()).isEqualTo(10000); assertThat(findMemberEx.getMoney()).isEqualTo(10000); } }저는 지금까지는 원본 코드와 테스트 코드가 따로 따로라고 생각했습니다. 근데 강의에서 원본 코드의 @Transactional을 사용 했을 때와, @Transactional을 주석 처리해 원본 코드를 수정했을 때. 테스트 코드의 결과가 다르게 변하더라구요. 이런 결과가 왜 발생하는건가요?테스트 코드는 원본 코드에 영향을 받는건가요?만약, 영향을 받는다면 어떤 범위까지 영향을 받는건가요? 설명 부탁드립니다!
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
커넥션과 세션의 관계, 세션과 트랜잭션의 관계가 궁금합니다.
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]스프링 DB 1편 트랜잭션 이해 파트에서 질문입니다."애플리케이션에서 DB 트랜잭션을 사용하려면 트랜잭션을 사용하는 동안 같은 커넥션을 유지해야한다. 그래야 같은 세션을 사용할 수 있다" 여기서 세션의 개념이 정확히 이해가 가지 않아 질문드립니다.찾아본 결과 하나의 커넥션에는 여러 개 세션이 존재할 수도, 아예 없을 수도 있다고 하고, 세션은 전달된 SQL이 실행되는 하나의 논리적 단위라고 합니다. 강의 설명에 따르면 같은 세션을 유지해야만 트랜잭션이 하나의 단위로 처리되기 때문에 이를 위해 같은 커넥션을 사용해야 한다고 이해했습니다. 그렇다면 같은 커넥션을 사용하는 것을 보장했을 때 항상 같은 세션을 사용하는 것도 보장되는 것인가요? 한 커넥션이 여러 세션을 사용하는 경우는 어떤 경우인가요? 여러 세션을 사용하게 되면 여러 세션에서 여러 개의 트랜잭션이 실행될 수 있는 것인가요?
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
@Transaction 적용 시 수동 빈 등록 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]@Transaction을 사용 시, 스프링 AOP가 적용되어야 하기 때문에 테스트 코드에서는 @SpringBootTest와 함께 트랜잭션 적용에 필요한 다양한 객체를 수동으로 등록하고 적용하는 법을 배웠습니다. (PlatforTransactionManager, DataSource 등) 그러면 테스트 환경이 아닌 서비스 로직에서 @Transaction을 사용할 경우에는 강의에서 진행한 수동 빈 등록 절차를 거치지 않아도 되는 건가요? @Transcation을 썼을 때 트랜잭션에 필요한 빈들을 자동으로 등록한다는 내용이 이 뜻인건지 궁금합니다.
-
미해결토비의 스프링 부트 - 이해와 원리
스프링 사용 관련 궁금한 사항이 생겨 질문드립니다
스프링 사용 관련 궁금한 사항이 생겨 질문드립니다 토비님 안녕하세요~ 오늘 아침에 웹프로그램 개발하다 갑자기 궁금한 사항이 생겼습니다 1. MVC 컨트롤러 를 이용 할 때 보안상 문제로 get을 사용하지 않고 post 만 작성 하는게 맞는것인지 웹프로그램을 개발 할 때 브라우저 url 에는 파라미터가 전혀 안보이는것이 보안상 최선인지 궁금합니다 토비님도, 스프링 mvc 를 이용해서 개발 하실때 모두 post 방식으로 request 를 하시는지 궁금합니다 (간혹 금융권 사이트에서는 url 부분에 파라미터가 안보였던거 같아서요.. ) 2. 네이버/카카오/유튜브 open API 등을 누가나 사용 할 수 있는데요 나쁜 사용자가 악의적인 의도를 갖고 마구 request 호출 을 할 경우 서버 트랙픽을 방어 하려고 하면 스프링의 어느 기술을 이용해서 막을 수 있을 까요? 3. 스프링 프레임웍 안에서 뷰(프론트) 부분에 JSP / 타임리프 / php / react / vue 동시에 여러가지를 함께 쓸 수가 있나요? 감사합니다. 수고하세요
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
동시성 이슈 처리 질문있습니다!
DB 동시성 문제를 해결하기 위해낙관적 잠금, 유니크 제약조건, 비관적 잠금이 있는 것으로 알고있습니다.비관적 잠금은 성능상의 이유로 잘 사용하지 않는다고 알고있어서낙관적 잠금 또는 유니크 제약조건으로 동시성을 해결하고 있는데, 낙관적 잠금을 사용해야 할지, 유니크 제약 조건을 사용해야 할지 의문이 들어 질문 드립니다. 감사합니다!
-
해결됨토비의 스프링 부트 - 이해와 원리
커스톰 @Conditional 강의에서 질문입니다.
<해결됨>같은 질문 링크입니다. https://www.inflearn.com/chats/757401/x27-conditional%EA%B3%BC-condition-x27-%EA%B0%95%EC%9D%98-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B83-0-%EC%9D%B4%EC%83%81%EC%9C%BC%EB%A1%9C-%EC%95%88%EB%90%98%EB%8A%94%EB%B6%84%EB%93%A4 https://github.com/tobyspringboot/helloboot/commit/9db7fbb4b665ad0a21e18fa580d378179b44fa92spring boot 3에서 적용해보고 있습니다.제목의 강의에 해당하는 커밋은 위 링크일 것 같습니다. 해당 커밋에서 checkout 한 후, dependencies { implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat' } implementation 'org.springframework.boot:spring-boot-starter-jetty' testImplementation 'org.springframework.boot:spring-boot-starter-test' } 위와 같이 jetty를 사용하게 해두고 어플리케이션을 실행하면 Unable to start web server, java.lang.NoClassDefFoundError: jakarta/servlet/http/HttpSessionContext 오류는 jakarta.servlet.http 패키지의 HttpSessionContext 자바 클래스를 찾을 수 없음이렇게 나오는 것 같습니다.어떻게 해결할 수 있을까요..?
-
해결됨토비의 스프링 부트 - 이해와 원리
TestRestTemplate ResourceAccessException 문제
TestRestTemplate 테스트를 하려고 했으나, 해당 문제가 계속 발생하더라구요.구글링을 해봐도 포트나 @SpringBootTest 어노테이션을 사용해서 해결해라 이런 얘기 들만 보여서아래 결과 처럼 해결 했습니다만, 왜 영상에서 나오는 것처럼 해서 는 안되는 것인지 모르겠습니다.1.2. (LocalServerPort를 없애보았으나 잘됨)
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
트랜잭션 템플릿과 AOP의 프록시객체
안녕하세요.앞에서 템플릿 콜백 패턴으로 트랜잭션 템플릿(스프링이 제공한 것이긴 하지만)을 구현했던 것처럼 AOP의 프록시 객체 클래스를 직접 구현할 수도 있을까요??구현할 수 있다면 어떤 방식으로 구현하는지,구현이 어렵다면 어떤 부분 때문에 어려운지 궁금합니다...!
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
dataSource에 관한 질문
앞선 강의들에서 driverManager는 라이브러리에 등록된 DB 드라이버들을 관리하고 커넥션을 획득하는 기능을 제공한다고 배웠습니다.하지만 여러 요청이 동시에 왔을 때 DriverManager는 커넥션이 하나 뿐이라 여러 요청을 병렬처리를 할 수 없다는 단점이 있어 커넥션 풀 이라는 개념을 도입하여 여러 요청을 풀 내의 여러개의 커넥션을 통해 병렬 처리가 가능하도록 하는 것이고, 이러한 커넥션을 획득하는 방법이 DriverManager, Hikari, DBCP2 등 여러 커넥션 획득 방법이 존재하기 때문에 이들을 추상화해둔 것이 DataSource interface이고, DataSource 구현체로 DriverManager를 통한 커넥션 획득 방법은 DriverManagerDataSource, Hikari를 통한 커넥션 획득 방법은 HikariDataSource이다.제가 이해한 것은 이정도 인데 맞는지 모르겠습니다..
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
SQLExceptionTranslator translate의 파라미터로 무엇을 넘기는 건가요?
SQLExceptionTranslator translate의 파라미터가 (String task, @Nullable String sql, SQLException ex) 이런식으로 되어있던데 첫번째 task에 무엇을 넣어야하는지 궁금합니다. 맥락상 실행한 메서드명을 넣는 것 같은데 이것저것 변경해보다가 전혀 관련없는 글을 써넣어도 정상작동하던데 task에 무엇을 넣는지, 어떤 역할을 하는지 궁금합니다.
-
미해결토비의 스프링 부트 - 이해와 원리
spring mapping 여러개 문의 드립니다
안녕하세요 토비님제가 자주 질문 드려서 싫어 하실거 같네요..https://www.url01.urlcom/충청도 or 제주도 or 인제군 or ...(지자체 정보 170개 )이런식으로 ~Controller.java170개의 경우를 겟매핑이나 포스트매핑(보안문제로)해야 합니다@GetMapping({ '/충청도', '/제주도', or '/인제군' or ......이런식으로 170 개의 지자체 })아래 부분을 위해서 수기 타이핑 문자열이 아닌db에서 불러와서 배열로 넣을려고 하니 되지 않아서제가 잘못 생각하고 있는지 여쭤봅니다변수 = 서비스.지자체리스트; //170개 db에서 꺼내옴@GetMapping({ value = 변수 }) ==> 이거 원래 안되는 것일 까요? 계속 스택오버플로우나 구글링 찾아봐도 제가답을 못 찾았습니다 혹시 원래 되는 기능 이라면 , 제가 어디 문서를 찾아 봤었어야 할까요?( 예를 들면 토비님 같은 경우스프링 공식 문서 샘플 설명 사이트 나, 자주 방문하는 이 사이트 찾아 보면 금방 답이 나왔을 것이다이런 부분 알려 주시면 감사합니다.. )
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
트랜잭션 추상화 관려해서 궁금한 점이 있습니다.
트랜잭션 추상화시키는데, 이것도 일관성 있는 서비스 추상화로 볼 수 있는건가요?공통 인터페이스를 만들어서 구현체만 바꿔주는 방법이 일관성 있는 서비스 추상화를 활용하는 것으로 볼 수 있는건가요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
PlatformTransactionManager 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.1.위의 코드에서txTemplate의 타입은 TransactionTemplate인데생성자를 만들 때는 왜PlatformTransactionManager의 타입으로 받는건가요?2. TracsactionTemplate 타입인 txTemplate에 어떻게 PlatformTransactionManager의 타입으로도 주입해줄 수 있는건가요?tracsactionTemplate와 PlatformTransactionManager는 어떤 관계가 있는건가요? 위와 같은 설명과 연관이 있는거 같은데 잘 이해가 안됩니다 설명 부탁드립니다!
-
미해결토비의 스프링 부트 - 이해와 원리
spring url 리다이렉트/포워딩 기술적 문의 드립니다
spring url 리다이렉트/포워딩 기술적 문의 드립니다안녕하세요 김동희입니다제가 공공기관 프로젝트에 개발자로 참여중입니다이쪽프로젝트 환경은jsp + 전자정부프레임웍(Spring) + html + postgre(db) 입니다이쪽 pm 이 알아봐달라고 부탁하는 사항이 있고,제가 생각하기에도 궁굼해서혹시 이런부분이 될런지 문의 드립니다메인 정부기관 홈페이지는 아래입니다 ex)https://www.url01.urlcom각 전국 지역별(강원,인천,제주..) 지자체관 별로 별도로 지역별 블로그 형식으로 지자체관 형식을 뛰웁니다ex) 강원특별자치도 인제군 지자체관https://www.url01.urlcom/xxx/xxx/xxxx/xxxxx/infoMain.do?ctpv=6420000&sgg=4330000하지만, 고객(공무원)측에서 url 하위로 깔리는 url 변수를 보여주지 말라지자체관별로 단축 url 을 사용 할 수 있게 해달라고 합니다 as-is https://www.url01.urlcom/xxx/xxx/xxxx/xxxxx/infoMain.do?ctpv=6420000&sgg=4330000to-be https://www.url01.urlcom/injegun 혹시 요청이 현재 spring(전자정부프레임웍) + jsp + tiels 환경에서 이 환경에서 고객(공무원) 들의 요청을 수렴해서반영 할 수 있을지 모르겠습니다 AA,TA 적인 기술적인 측면에서스프링의 config 또는 다른설정값 변경, 인터셉터변경, ~Controller~.java 변경~tiles.xml 변경 등을 통해서 가능 할까요?염치 불구하고 저도 이런부분이 궁금하기도 해서 문의 드립니다김동희 드림
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
트랙잭션 종료 후에 setAuotoCommit(true)로 변경하는 이유가 무엇인가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.커넥션 풀을 고려하여 setAutoCommit(true)로 되돌린다고 하셨는데 그 이유가 무엇인가요?설명 부탁드립니다 !