apigateway의 application.yml을 보면 get요청에는 authorizationHeaderFilter를 적용시키고 있습니다. authenticFilter는 그저 로그인 요청시 attempthAuthentication메소드와 successfulAthentication메소드를 통해 인증을 처리하고 response헤더에 토큰을 추가하는 역할입니다. 따라서 로그인 요청에만 적용하면 될 것 같은데, 깃허브의 최신코드 버전을 보면 거의 모든 요청에 authenticationFilter를 적용하고 있습니다. 왜 로그인요청이 아닌 다른 요청에다가 AthenticFilter를 적용할까요? apiGateway-service에서 GET요청만 AuthoriztionFilter를 적용하면 되지않나요?? http.authorizeHttpRequests((authz) -> authz .requestMatchers(new AntPathRequestMatcher("/actuator/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/h2-console/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/users", "POST")).permitAll() .requestMatchers(new AntPathRequestMatcher("/h2-console/**")).permitAll() // .requestMatchers(new AntPathRequestMatcher("/welcome/**")).permitAll() // .requestMatchers("/**").access(this::hasIpAddress) .requestMatchers("/**").access( new WebExpressionAuthorizationManager("hasIpAddress('127.0.0.1') or hasIpAddress('172.30.1.48')")) .anyRequest().authenticated() )
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 뒷 내용이 어려워서 다시 복습하는중인데 파라미터에 Model model을 사용하는 이유가 궁금합니다. 파라미터로 받지 않고 메서드 내부에서 Model model; model.addAttribute(모델데이타, value); 이렇게 사용할 수 는 없는건가요? 그리고 api통신에서 어노테이션에 @ResponseBody를 확인하면 html로 반환하지 않는다고 인식 후 return이 스트링인지 객체인지 확인 후 어떤 형식으로 반환할지 정해지는것인가요? 객체를 반환할 때 서버에 반환하던 웹 브라우저에 반환하던 스프링은 누구에게 반환을 하는건지 몰라도 되는것인가요? 예를 들면 현 강의에서는 웹 브라우저에 반환을 하였지만 리액트를 이용할 때는 노드환경(노드환경을 서버로 이해하였습니다.)에 반환을 하는 방식인데 스프링은 요청한 주체와 반환되는 값이 어디로 가는지는 알 필요가 없는건가요?
안녕하세요. 깃허브에서 spring boot 3.2 브랜치통해 코드를 작성했습니다. 그런데 회원가입, 로그인까지 해서 jwt토큰까지는 잘 받아오는데, 그 이후에 /welcome으로 헤더에 토큰으로 추가해서 요청을 보내도 403 forbidden에러가 뜹니다. 코드는 spring boot 3.2 브랜치와 동일합니다.
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
국비 수료 후 선생님 강의 듣고 있습니다. 저는 오라클을 db로 사용했었고 그 땐 sql디벨로퍼를 주로 사용했었는데요 전 인텔리제이 무료버전이라 mysql command line client를 사용해야 할텐데 제가 궁금한건 오라클에서 sql디벨로퍼를 사용했더라면 그에 대응되는게 인텔리제이의 mysql command line client라 보면 될까요? sql디벨로퍼에선 테이블도 가시적으로 보이고 셀렉트 해서 조회하는 결과도 보였는데 mysql command line client 같은 경우 리눅스형식같고 뭔가 좀 어색해서용
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 접속까지는 되는데 test.db.mv 파일이 만들어지지가 않아서 jdbc:h2:tcp:// localhost/~./test 접속이 안됩니다 이걸로
최신버전에서 apply가 deprecated되어서 자료를 좀 찾아봤습니다만, 확신이 없어서 질문드립니다. @EnableWebSecurity @Configuration public class SecurityConfig { @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated() ) .formLogin(withDefaults()) .with(new CustomSecurityConfigurer().setFlag(true), withDefaults()); return http.build(); } } 대체로 with을 사용한다고 하는데, Customizer.withDefaults를 두번째 인자로 주었습니다. 이렇게 사용하는 것이 맞나요? Customizer의 역할도 조금만 알려주시면 감사하겠습니다. 기존 프로젝트에 대입하려니 최신 관련 자료가 너무나 없네요... ㅠㅠ
[질문 내용] 안녕하세요! ArrayList 에 대해 이것저것 찾아보던 중 이런 내용이 있었습니다. ArrayList,Map 은 동시성 이슈가 있어 ArrayList 대신 CopyOnWriteArrayList를 Map 대신 ConCurrentHashMap 을 쓰라는 내용이었습니다. 이에 대해 실제 스프링으로 개발할 때 위 내용이 어떻게 응용되는지 이해가 안되고 찾지 못해서 질문드립니다. 뭐 단순히 ArrayList 에 정수 넣고 실험해서 동시성 이슈가 있다라고 파악을 한다고 치더라도 뭐 어느 경우에 적용해야 하는지 이해가 안갑니다. 질문 요약 1) ArrayList 대신 CopyOnWriteArrayList 를 써야 하는 실무적인 실제 예를 들어주세요! 지금까지 영한님한테 배웠던 대로 양방향 관계에서 List = new ArrayList<>로 초기화 해줬는데 그러면 이는 유저가 많은 멀티스레드 환경에서 위험한 것 아닌가요?? public PostResponseDto showDetailsPost(final Long postId){ //Post + PostImage + Post 게시글 작성자 함께 영속화 Post post = findPostWithFetchMemberAndImage(postId); //첫 댓글 Reply (대댓글 X) + 부모댓글 작성자 함께 영속화 List<Reply> parentReply = replyRepository.findParentReplyByPostIdWithFetchMember(postId); List<ReplyResponseDto> replyResponseDtoList = new ArrayList<>(); //부모-> 자식 순으로 DTO 순서 저장. for(Reply parent: parentReply){ replyResponseDtoList.add(ReplyResponseDto.of(parent,makeNickNameForReply(parent),makeContentsForReply(parent))); 위 코드는 List<ReplyResponseDto> 를 new ArrayList<>() 로 초기화 해서 add 로 넣어주는 부분이 있습니다. 이런 부분도 다 CopyOnWriteArrayList를 써야 하는 것인가요? 2) Map 도 마찬가지입니다. 실제 Map 대신 ConcurrentHashMap 을 써야 했던 실무적인 예를 들어주시면 감사하겠습니다.
안녕하세요 질문이 있습니다 API 강의 듣다가 궁금증이 생겨서 질문을 남기게 되었습니다. @RequestParam 은 매개변수의 값을 반환하는건가요? @RequestMapping("/save") public ModelAndView save(HttpServletRequest request, HttpServletResponse response) { String username = request.getParameter("username"); int age = Integer.parseInt(request.getParameter("age")); ... } 이 코드를 @PostMapping("/save") public String save(@RequestParam("username") String username, @RequestParam("age") int age, Model model) { ... } 요렇게 바꿔줄 수 있는 역할이 @RequestParam 인 건가요? 그리고 RequestParam 을 쓸때 달아주는 어노테이션이 @ResponseBody 인건가요??
안녕하세요 mvc강의를 2편까지 모두 듣고 야생형코스를 따라가려고 jpa1 편을 수강중입니다. 현재 섹션2까지 들었는데 도메인 분석과 엔티티설계시 강사님께서 설명해주신 다대다관계, 연관관계 메서드 등 확실히 이해는 안가지만 이런게 있구나 하며 넘어가도 되는걸까요? 이 강의에서는 jpa를 알아가보는 것보다 스프링에서 jpa를 어떻게 쓰는지만 알고 이 강의 듣고 기본편으로 넘어가도 되는걸까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] pdf에 @Transactional 설명하는 부분에서 테스트 시작 전에 트랜잭션을 시작하고~ 라는 말이 있는데, 여기서 말하는 트랜잭션이 시작한다는게 무엇을 시작한다는 건가요?
Hibernate는 @Version 을 사용하고, Lock 옵션을 @Lock(LockModeType.OPTIMISTIC) 을 사용할 경우에 NONE 모드와 다르게 엔티티를 수정하지 않고 단순히 조회만 해도 버전을 확인한다고 강사님 JPA 책에 작성되어있습니다. 실제 코드로 구현해보니 버전만 확인하는거 같더라구요 그 사이에 다른 트랜잭션이 해당 엔티티를 수정하여 버전이 변경되어도 ObjectOptimisticLockingFailureException 예외가 발생하지 않습니다. 간단하게 로직을 설명드리면 트랜잭션 A가 옵티미스틱 락 모드로 회원을 조회합니다. version = 0 트랜잭션 A를 5초 대기합니다. 트랜잭션 B가 회원을 수정하여 버전이 변경됩니다. version = 1 트랜잭션 B가 종료됩니다. 5초가 지나 트랜잭션 A가 종료됩니다. 트랜잭션 A가 종료될 때 옵티미스틱 락 모드라서 마지막에 버전을 확인합니다. select version as version_ from member where id=? 그런데 트랜잭션 A가 종료될때에 회원 버전이 다르지만 예외가 발생하지 않습니다. 이러면 OPTIMISTIC의 용도가 트랜잭션을 커밋할 때 버전 정보를 조회해서 현재 엔티티의 버전과 같은지 검증한다. 만약 같지 않으면 예외가 발생한다고 작성되어있는데 예외가 발생하지 않는다면 강사님께서 설명해주신 조회한 엔티티는 트랜잭션이 끝날 때까지 다른 트랜잭션에 의해 변경되지 않아야한다. 조회 시점부터 트랜잭션이 끝날때까지 조회한 엔티티가 변경되지 않음을 보장한다. 이 말의 다른 의미가 어떤건지 궁금합니다 ! 아니면 제가 테스트를 잘못하고 있는 걸까요..? 아래는 로직에 대한 간단한 코드입니다. 도메인 package org.example.stock_rt_1.domain; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; @Entity @Getter @NoArgsConstructor public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; private long personId; private int age; @Version private Long version; public Member(long personId, int age) { this.personId = personId; this.age = age; } public void addAge() { ++this.age; } } 리포지토리 package org.example.stock_rt_1.repository; import jakarta.persistence.LockModeType; import org.example.stock_rt_1.domain.Member; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Lock; import java.util.Optional; public interface MemberRepository extends JpaRepository<Member, Long> { @Lock(LockModeType.OPTIMISTIC) Optional<Member> findByPersonId(Long id); } 서비스 package org.example.stock_rt_1.service; import lombok.RequiredArgsConstructor; import org.example.stock_rt_1.domain.Member; import org.example.stock_rt_1.repository.MemberRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Optional; @Service @RequiredArgsConstructor public class MemberService { public final MemberRepository memberRepository; @Transactional public void addAge(long personId) { sleep(500); //findMember가 먼저 실행되야하기 때문에 넣었습니다. Member member = memberRepository.findByPersonId(personId).orElseThrow(); member.addAge(); } @Transactional public void findMember(long personId) { memberRepository.findByPersonId(personId); sleep(5000); } private void sleep(long mills) { try { Thread.sleep(mills); } catch (InterruptedException e) { System.out.println("e = " + e.getMessage()); } } } 테스트코드 package org.example.stock_rt_1.service; import org.example.stock_rt_1.domain.Member; import org.example.stock_rt_1.repository.MemberRepository; 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; @SpringBootTest class MemberServiceTest { @Autowired private MemberService memberService; @Autowired private MemberRepository memberRepository; @Test @DisplayName("회원 정보를 조회중 다른 트랜잭션에서 정보를 변경했다.") void addAge() throws InterruptedException { // given int personId = 5555; memberRepository.save(new Member(personId,15)); // when Thread selectThread = new Thread(() -> memberService.findMember(personId),"트랜잭션-A"); selectThread.start(); Thread updateThread = new Thread(() -> memberService.addAge(personId),"트랜잭션-B"); updateThread.start(); selectThread.join(); updateThread.join(); } } 로그 [트랜잭션-A] : select m1_0.id,m1_0.age,m1_0.person_id,m1_0.version from member m1_0 where m1_0.person_id=? Hibernate: select m1_0.id,m1_0.age,m1_0.person_id,m1_0.version from member m1_0 where m1_0.person_id=? [트랜잭션-B] : select m1_0.id,m1_0.age,m1_0.person_id,m1_0.version from member m1_0 where m1_0.person_id=? Hibernate: select m1_0.id,m1_0.age,m1_0.person_id,m1_0.version from member m1_0 where m1_0.person_id=? [트랜잭션-B] : update member set age=?,person_id=?,version=? where id=? and version=? [트랜잭션-B] : select version as version_ from member where id=? [트랜잭션-A] : select version as version_ from member where id=?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 이전 강의에서는 PageRequest.of(pagenum, pagesize, sort.by ()) 를 사용해서 직접 설정해줘서 리포지토리 매서드에 인자로 넘겼는데 mvc의 @PageableDefault를 사용하면 이런 부분을 자동으로 처리해준다라고 이해해도 괜찮을까요?
안녕하세요 로그인시에는 인증이 필요하지가 않는데 자꾸 인증 해주는 AuthorizationHeaderFilter 클래스에서 apply 메소드에서 header 값이 없다고 걸립니다. 그래서 아래와 같이 401 오류로 로그인이 안됩니다. application.yml 파일은 문제없는거 같은데 뭘 더 확인해봐야 할까요,,,? 아래는 Users application.yml 파일입니다.
[질문 내용] 코드를 어제 새벽부터 계속 확인해보았는데 DB 생성이 되지 않습니다. 강사님과 스프링, DB 버전이 달라서 생기는 오류인가요? 해결 방법을 모르겠습니다.. JPA와 DB 설정, 동작 확인에서 Member 테이블은 생성이 되었습니다. 그러나 도메인 분석 설계 섹션 강의에서 진행한 Orders, category, delivery, item과 같은 테이블이 생성이 되지 않습니다. spring-boot는 3.2.4 버전을, H2의 경우 2.2.224 버전을 사용했으며, JUnit4는 현재 사용중인 springboot와 호환이 되지 않아 JUnit5를 사용하였습니다. 아래 드라이브 링크는 코드 전체 압축파일 입니다! https://drive.google.com/file/d/1_Xithr3ZMw4MzcHRz1E2TDypWM0c-_Ry/view?usp=sharing
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. 13:51초에서 실행 오류가 나며, H2 db에서 Member가 생성되지 않습니다. 하루정도 구글링을 진행하였지만 해결되지 않아 질문드립니다. 아래는 작성한 코드입니다! https://drive.google.com/file/d/1vASQI42Acv8UbdcQ_MDLIkDe0W0pcUba/view?usp=sharing