묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결
웹개발 진로에 대해서 질문드리고싶습니다.
안녕하세요? 저는 현재 웹개발 백엔드공부중인 컴공 졸업생입니다.인프런에서 스프링 강의를 수강하고 있습니다.제가 나이도 좀 있고 공백기도 있어서 고민이 있습니다.현재 제가 공부중인, 웹개발 스프링을 공부하면, 웹 개발 직종뿐만 아니라 다른 유사한 직종으로도 들어갈 수 있을까요?개발자 아무나 하는 것이 아니라는 말도 많이 들었고, 처음부터 웹 개발 회사 진입도 어렵다는 말을 많이 들었어서 고민이 됩니다.스프링 웹개발 분야를 공부했을 때, 개발직종말고 이와 유사한 직종 들어갈 수 있는 곳들도 있을까요?예를들면, 금융회사라든지 이런 부차적으로 개발을 하는 곳들로요.빨리 취업하는 것이 목표라서 질문드립니다. 감사합니다.
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
LoginForm클래스가 web영역인 이유가 궁금합니다.
멤버 클래스, 멤버 리포지토리 클래스와 비교하였을 때 멤버 클래스는 도메인 영역에 존재하고 멤버 리포지토리에 의해서 멤버 클래스의 객체가 만들어지는것 같은데로그인기능에서 로그인폼 클래스가 멤버 클래스와 같은 기능인것 같은데 서로 다른 영역에 존재하고 로그인 사용자가 생성될려면 로그인서비스의 loginService.login()기능이 호출되어서 로그인 객체가 생성이 되는것을 알겠는데 멤버클래스와 다르게 web영역에 존재하는 이유가 궁금합니다.
-
해결됨
dto에서 toEntity VS entity 안에 정적 팩토리 메서드
@Service public class MemberService { private final MemberRepository memberRepository; public void save(MemberDto memberDto) { Member member = memberDto.toEntity(); memberRepository.save(member); } }@Service public class MemberService { private final MemberRepository memberRepository; public void save(MemberDto memberDto) { Member member = member.createMember(memberDto); memberRepository.save(member); } }dto에서 toEntity 와 entity 안에 정적 팩토리 메서드 중 어떤 코드를 쓰는게 좋을가요?의존성으로 보면 첫번째 코드가 맞는걸까요?
-
미해결Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부
Backpressure Example 코드 질문드립니다
기존 예제 (sleep 시간이 5L인 경우)에선 Exception이 발생하는 것을 확인했습니다. 하지만 sleep 시간을 더 늘리니까 Erorr가 발생하지않았습니다. 제 예상대로라면 버퍼가 더 빨리 차기 때문에 에러가 발생해야하는데, 동작이 이해가 되지 않습니다. public class BackpressureStrategyErrorExample { public static void main(String[] args) { Flux .interval(Duration.ofMillis(1L)) .onBackpressureError() .doOnNext(Logger::doOnNext) .publishOn(Schedulers.parallel()) .subscribe(data -> { // 왜 50L, 500L로 하면 에러가 발생하지 않을까? TimeUtils.sleep(500L); Logger.onNext(data); }, error -> Logger.onError(error)); TimeUtils.sleep(5000L); } }
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
컨트롤러에서 리다이렉트를 해주는건 ssr을 이용할때만 고려하면 되는 건가요?
Ssr을 이용할때는 직접 뷰를 이동하는 거니 백엔드 개발자가 리다이렉트도 처리를 해주어야 하는데 csr을 이용하여 json으로 통신할때는 백엔드 개발자는 데이터만 잘 넘겨주는것이 끝이기 떄문에 리다이렉트 관련 내용은 프론트 개발자가 해결하는 부분 인가요?그리고 @ModelAttribute와 파라미터에 사용되는 Model 객체에서 @ModelAttribute 는 Item 클래스의 멤버 변수를 세팅해주는것이기 때문에 csr을 이용하여 웹 개발을 할 때 return item 을 하여 객체가 json으로 변환되어 클라이언트에게 전달되니 @ModelAttribute 는 csr을 이용할때도 사용되는 어노테이션이고 Model객체의 model.addAttribute()는 ssr의 뷰 영역에서 사용될 데이터를 넘겨주는 기능이라서 csr을 이용할때는 사용을 안하나요?
-
미해결스프링 핵심 원리 - 기본편
싱글톤 컨테이너 - @Configuration과 싱글톤 강의 관련
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.싱글톤 컨테이너 - @Configuration과 싱글톤 강의에서 System.out.println("memberService -> memberRepository = " + memberRepository1); System.out.println("orderservice -> memberRepository = " + memberRepository2); System.out.println("memberRepository = " + memberRepository)이렇게 출력하면 전부 같은 memberRepository가 출력되야되는데 저는 전부 다른 memberRepository가 출력 됩니다. 이유를 모르겠습니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
N + 1 쿼리 횟수
안녕하세요 강의 너무 잘 듣고 있습니다."간단한 주문 조회 V2: 엔티티를 DTO로 변환" 강의를 듣던 중 궁금한 점이 생겨 질문 드립니다.Order 엔티티를 SimpleOrderDto로 변환하는 과정에서 아래 조건으로 인해 샘플 데이터 2개 기준 총 5(1 + 2 + 2)번의 쿼리가 날아간다고 이해했습니다.order -> member 지연 로딩 조회 N번order -> delivery 지연 로딩 조회 N번근데 저는 order -> delivery 쿼리 이후에 order를 찾는 쿼리가 한번 더 날아가는 것처럼 보입니다. 총 7번의 쿼리가 발생하는 것 같은데 무엇 때문인지 설명해주실 수 있을까요?코드와 콘솔 로그는 아래 첨부했습니다. 감사합니다.// Order 엔티티 @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "delivery_id") private Delivery delivery; private LocalDateTime orderDate; @Enumerated(EnumType.STRING) private OrderStatus status; // 주문상태 // Delivery 엔티티 @Id @GeneratedValue @Column(name = "delivery_id") private Long id; @JsonIgnore @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) private Order order; @Embedded private Address address; @Enumerated(EnumType.STRING) private DeliveryStatus status; // READY, COMP // OrderSimpleApiController @GetMapping("/api/v2/simple-orders") public List<SimpleOrderDTO> ordersV2() { List<Order> orders = orderRepository.findAll(new OrderSearch()); return orders.stream() .map(SimpleOrderDTO::new) .toList(); } @Data static class SimpleOrderDTO { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; public SimpleOrderDTO(Order order) { this.orderId = order.getId(); this.name = order.getMember().getName(); // Lazy 초기화 this.orderDate = order.getOrderDate(); this.orderStatus = order.getStatus(); this.address = order.getDelivery().getAddress(); // Lazy 초기화 } }2024-04-09T13:27:53.982+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id 2024-04-09T13:27:53.984+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636873984|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 join member m1_0 on m1_0.member_id=o1_0.member_id 2024-04-09T13:27:54.005+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2024-04-09T13:27:54.007+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874007|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=1 2024-04-09T13:27:54.012+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2024-04-09T13:27:54.013+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874013|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=1 2024-04-09T13:27:54.016+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2024-04-09T13:27:54.016+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874016|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=?|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=1 2024-04-09T13:27:54.018+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2024-04-09T13:27:54.019+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874019|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=?|select m1_0.member_id,m1_0.city,m1_0.street,m1_0.zipcode,m1_0.name from member m1_0 where m1_0.member_id=2 2024-04-09T13:27:54.020+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2024-04-09T13:27:54.020+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874020|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=?|select d1_0.delivery_id,d1_0.city,d1_0.street,d1_0.zipcode,d1_0.status from delivery d1_0 where d1_0.delivery_id=2 2024-04-09T13:27:54.021+09:00 DEBUG 12424 --- [nio-8080-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2024-04-09T13:27:54.021+09:00 INFO 12424 --- [nio-8080-exec-2] p6spy : 1712636874021|0|statement|connection 7|url jdbc:h2:tcp://localhost/~/jpashop_v2|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=?|select o1_0.order_id,o1_0.delivery_id,o1_0.member_id,o1_0.order_date,o1_0.status from orders o1_0 where o1_0.delivery_id=2
-
미해결
spring Security 구현중 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception 에러 발생
https://github.com/myungkeun02/spring_blog_3공부하고있는 코드입니다.제목 그대로 포스트맨으로 테스트중에Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception라는 에러가 발생합니다.구글링해서 문제가 발생할만한 부분을 모두 찾아 보았지만 해결이 안되어 글 올려봅니다.해결해주시는분께 아메리카노 쏩니다
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
필드 오류 메세지를 골라 쓸수는 없나요?
메세지를 관리하는 공통 관리팀에서필드에 대한 required 메세지 4가지를 정의해 놨다고 가정할 때required.item.itemName=상품 이름은 필수입니다. required.itemName=이름은 필수입니다. required.java.lang.String = 필수 문자입니다. required = 필수 값 입니다.아래 명령어는bindingResult.rejectValue("itemName","required");required.item.itemName으로 정의된 에러 메세지(상품 이름은 필수입니다.)만 불러 올 수 있는거죠?개발자가 네가지 오류 메세지 중에서 선택해서 사용할 수 있는 방법은 없나요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
protected 사용 이유
안녕하세요! 해당 강의에서 기본 생성자를 추가해주실 때, public이 아니라 protected를 사용하셨는데, 그 이유가 무엇인가요?혹시라도 다른 곳에서 기본생성자를 사용하지 못하도록 하게 하기 위함인가요? 제가 자바가 안익숙해서 그런지, 이러한 접근 제어자를 쓰는 것이나, static, final 키워드를 언제 쓰거나 안써야 하는지에 대한 감이 별로 없어서 구분을 잘 못하는데, 이러한 실력은 어떤 경험을 더 쌓아야 할지.. 아니면 어떤 키워드를 어떻게 공부해야 더이상 안 헷갈리고 확실하게 알 수 있을지 궁금합니다...! 항상 친절한 강의 감사드립니다.
-
미해결스프링 핵심 원리 - 기본편
setter 주입 시의 생성자
클래스에 생성자가 단 1개 존재하는 경우 @Autowired를 생략할 수 있다고 하셨는데, 이는 생성자 주입을 하는 경우에만 해당하는걸까요? setter 주입을 하기 위해 OrderServiceImpl에 setter를 정의하고 각 setter에 @Autowired를 붙였다면, 이때는 생성자 주입이 아닌 setter 주입이 이뤄지는 걸까요? 제가 추가적으로 OrderServiceImpl의 생성자에 출력문을 두었더니 memberRepository에 스프링 컨테이너에 존재하는 MemoryMemberRepository 객체의 주소값이 들어왔습니다... 생성자 주입도 이뤄지고 setter 주입도 이뤄지는 건가요...?public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { System.out.println("OrderServiceImpl.OrderServiceImpl"); System.out.println("memberRepository = " + memberRepository); this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
-
미해결스프링 핵심 원리 - 고급편
쓰레드로컬이 제공하는 별도의 저장소와 싱글톤의 관계
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요, 쓰레드 로컬이 가지는 별도의 보관소 개념이 정확하게 이해가 되지 않아 질문을 남깁니다. 1. 쓰레드 로컬이 만드는 별도의 전용 보관소라는 것은 하나의 객체를 생성하여 그곳에 정보값을 저장해 두었다가 해당 쓰레드가 싱글톤으로된 객체의 정보값을 호출할 때마다 참고하게 되는 것인지, 아니면 다른 방식으로 설계된 것인지 궁금합니다. 2. 결국 특정 쓰레드마다 별도의 저장소를 통해 정보값을 보관하게 한다면, 그리고 그 보관하는 것이 객체를 생성하는 방식이라면, 동시성 문제를 발생시키는 싱글톤 대신 프로토타입을 사용하면 되는 것이 아닌가 생각이 드는데 프로토타입이 아닌 쓰레드 로컬로 해결해야하는 이유가 무엇인지 궁금합니다.
-
해결됨스프링 핵심 원리 - 기본편
5분대부터 말씀하신 테스트에 대한 질문
안녕하세요 영한님. 강의 너무 잘 듣고 있습니다.다름이 아니라 강의 듣다가 테스트 코드의 중요성을 말씀해주셨는데, 궁금한 점이 있어서요 단위 테스트를 작성하는 것이 좋다단위 테스트는 스프링이나 DB를 활용하는 것이 아니다이렇다면, 단위 테스트할 때는 Fake 객체를 사용해서 단위테스트를 작성해야 하는 걸까요? 인터페이스로 역할과 구현이 분리된 상태에서 MemberRepository의 구현체를 프로덕션에서 사용하는 MemoryMemberRepository, 테스트 환경에서 사용할 FakeMemberRepository로 분리해서 사용하는 걸까? 하는 궁금함이 있어 여쭈어봅니다 항상 좋은 강의 감사합니다!!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
18:06 로그인을 하려도 리다이렉트가 안되는데 이유가 있나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]체크필터 코드 입니다.package hello.login.web.filter; import hello.login.web.session.SessionConst; import lombok.extern.slf4j.Slf4j; import org.springframework.util.PatternMatchUtils; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @Slf4j public class LoginCheckFilter implements Filter { private static final String[] whitelist = {"/", "/members/add", "/login", "/logout", "/css/*"}; @Override public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String requestURI = httpRequest.getRequestURI(); HttpServletResponse httpResponse = (HttpServletResponse) response; try{ log.info("인증체크 필터 시작 {}", requestURI); if(isLoginCheckPath(requestURI)){ log.info("인증 체크 로직 실행 {}", requestURI); HttpSession session = httpRequest.getSession(false); if(session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null){ log.info("미인증 사용자 요청 {}", requestURI); // 로그인 페이지로 리다이렉트 httpResponse.sendRedirect("/login?RedirectURL=" +requestURI); return; } } chain.doFilter(request, response); }catch (Exception e){ throw e; // 예외를 로길 가능 하지만, 톰캣까지 예외를 보내주어야 한다. }finally { log.info("인증 체크 필터 종료"); } } /** * 화이트 리스트의 경우 인증체크 필요 없음 */ // private boolean isLoginCheckPath(String requestURI){ // for (String s : whitelist) { // if (requestURI.equals(s)){ // return false; // } // } // return true; // return !PatternMatchUtils.simpleMatch(whitelist, requestURI); // } /** * 화이트 리스트의 경우 인증 체크X */ private boolean isLoginCheckPath(String requestURI) { return !PatternMatchUtils.simpleMatch(whitelist, requestURI); } } 컨트롤러 코드 입니다.package hello.login.web.login; import hello.login.domain.login.LoginService; import hello.login.domain.member.Member; import hello.login.web.session.SessionConst; import hello.login.web.session.SessionManager; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.servlet.server.Session; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @Slf4j @Controller @RequiredArgsConstructor public class LoginController { private final LoginService loginService; private final SessionManager sessionManager; @GetMapping("/login") public String loginForm(@ModelAttribute LoginForm form){ return "login/loginForm"; } // @PostMapping("/login") /*public String login(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){ if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 성공 처리 //쿠키에 시간 정보를 주지 않으면 세션 쿠키임(브라우저 종료시 모두 종료됨) Cookie idCookie = new Cookie("memberId", String.valueOf(loginMember.getId())); response.addCookie(idCookie); return "redirect:/"; // 홈으로 보냄 } // @PostMapping("/login") public String loginV2(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletResponse response){ if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 성공 처리 // 세션 관리자 통해 세션 보관 ㅏ고 회원 데이터 보관 sessionManager.createSession(loginMember, response); return "redirect:/"; // 홈으로 보냄 } // @PostMapping("/login") public String loginV3(@Validated @ModelAttribute LoginForm form, BindingResult bindingResult, HttpServletRequest request){ if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 성공 처리 // 세션이 있으면 있는 세션을 반환, 없으면 생셩해서 반환 HttpSession session = request.getSession(true); // 기본이 true라 생략 가능, 세션을 생성(있으면)하려면 true false일때는 세션 없으면 널일뿐 //세션에 로그인 회원 정보 보관 session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); // 세션 관리자 통해 세션 보관 ㅏ고 회원 데이터 보관 return "redirect:/"; // 홈으로 보냄 }*/ @PostMapping("/login") public String loginV4( @Validated @ModelAttribute LoginForm form, BindingResult bindingResult, @RequestParam(defaultValue = "/") String redirectURL, HttpServletRequest request){ if(bindingResult.hasErrors()){ return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); log.info("login? {}", loginMember); if(loginMember == null){ bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 성공 처리 // 세션이 있으면 있는 세션을 반환, 없으면 생셩해서 반환 HttpSession session = request.getSession(true); // 기본이 true라 생략 가능, 세션을 생성(있으면)하려면 true false일때는 세션 없으면 널일뿐 //세션에 로그인 회원 정보 보관 session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); // 세션 관리자 통해 세션 보관 ㅏ고 회원 데이터 보관 return "redirect:" + redirectURL; } //로그아웃 // @PostMapping("/logout") // public String logout(HttpServletResponse response){ // expireCookie(response, "memberId"); // return "redirect:/"; // } // @PostMapping("/logout") public String logoutV2(HttpServletRequest request){ sessionManager.expire(request); return "redirect:/"; } @PostMapping("/logout") public String logoutV3(HttpServletRequest request){ HttpSession session = request.getSession(false); if(session != null){ session.invalidate(); } return "redirect:/"; } private static void expireCookie(HttpServletResponse response, String cookieName) { Cookie idCookie = new Cookie(cookieName, null); idCookie.setMaxAge(0); response.addCookie(idCookie); } } 오타는 딱히 없는것 같은데 리다이렉트가 이루어지지 않습니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
mvc 1편 상품상세 실행 오류입니다.
상품상세 실행 중java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.오류 메세지가 나옵니다.https://drive.google.com/file/d/1Uqz3Fdgnh66wMES8vdChuriSCb3zXb_S/view?usp=sharing
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
H2 초반 연결문제
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.연견을 누르면 아래와같은 오류가 나옵니다
-
미해결
스프링 빈 등록
public class AllBeanTest { @Test void findAllBean() { ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class, DiscountService.class); DiscountService discountService = ac.getBean(DiscountService.class); Member member = new Member(1L, "userA", Grade.VIP); int discountPrice = discountService.discount(member, 10000, "fixDiscountPolicy"); assertThat(discountService).isInstanceOf(DiscountService.class); assertThat(discountPrice).isEqualTo(1000); } static class DiscountService { private final Map<String, DiscountPolicy> policyMap; private final List<DiscountPolicy> policies; public DiscountService(Map<String, DiscountPolicy> policyMap, List<DiscountPolicy> policies) { this.policyMap = policyMap; this.policies = policies; System.out.println("policyMap = " + policyMap); System.out.println("policies = " + policies); } public int discount(Member member, int price, String discountCode) { DiscountPolicy discountPolicy = policyMap.get(discountCode); System.out.println("discountCode = " + discountCode); System.out.println("discountPolicy = " + discountPolicy); return discountPolicy.discount(member, price); } } } 이것들을 스프링빈으로 등록하면, 정확히 어떤 것들이 스프링 빈으로 등록되는건가요? 모든 필드, 메소드들이 다 등록되는건가요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
서버 실행 실패
> Task :LibraryAppApplication.main() FAILED . ____ _ /\\ / ___'_ __ (_)_ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.6)2024-04-04 17:09:40.815 INFO 12468 --- [ main] c.g.libraryapp.LibraryAppApplication : Starting LibraryAppApplication using Java 17.0.9 on KONG with PID 12468 (C:\Project\project\library-app\build\classes\java\main started by jinju in C:\Project\project\library-app)2024-04-04 17:09:40.819 INFO 12468 --- [ main] c.g.libraryapp.LibraryAppApplication : No active profile set, falling back to 1 default profile: "default"2024-04-04 17:09:41.422 INFO 12468 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.2024-04-04 17:09:41.474 WARN 12468 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'userRepository' defined in com.group.libraryapp.domain.user.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot register bean definition [Root bean: class [org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in com.group.libraryapp.domain.user.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration] for bean 'userRepository': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=userConfiguration; factoryMethodName=userRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/group/libraryapp/config/UserConfiguration.class]] bound.2024-04-04 17:09:41.505 INFO 12468 --- [ main] ConditionEvaluationReportLoggingListener : Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.2024-04-04 17:09:41.521 ERROR 12468 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : ***************************APPLICATION FAILED TO START***************************Description:The bean 'userRepository', defined in com.group.libraryapp.domain.user.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration, could not be registered. A bean with that name has already been defined in class path resource [com/group/libraryapp/config/UserConfiguration.class] and overriding is disabled.Action:Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=trueExecution failed for task ':LibraryAppApplication.main()'.> Process 'command 'C:/Program Files/Java/jdk-17/bin/java.exe'' finished with non-zero exit value 1 찾아본 결과이 문제는 Spring 애플리케이션의 빈(bean) 정의 중에 중복이 발생하여 발생한 것으로 보입니다. 에러 메시지에 따르면 userRepository 빈이 이미 UserConfiguration 클래스에서 정의되어 있으며, 또한 Spring Data JPA가 자체적으로 해당 빈을 생성하려고 시도하고 있는 것으로 보인다고 합니다.혹시 UserConfiguration 부분에 변경이 적용 안된게 있어서 그런걸까요?저 bean 부분을 지워도 .UserServiceV1 때문에 컴파일 에러가 발생하더라구요,.,..
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
git에서 커밋을 했는데, 계속 진행해도 되는지의 여부
40강. git 기초사용법을 듣고 있습니다. 코드를 github에 올리는 과정에서 처음에는 git add . 작성 시 아래와 같이 에러가 나타났습니다위와 같은 과정을 거쳤고, 커밋이 반영된듯 싶으면서도 fatal: unknown write failure on standard output이라는 문구가 떠 다음 과정을 진행하기 찝찝합니다. 이전에 git add .시 실행은 된 것 같지만 warning이 난것도 나중에 문제가 될것 같습니다..감사합니다.
-
해결됨
김영한 강사님 강의에 대한 오류 질문입니다.
김영한 강사님의 스프링 핵심원리 기본편을 수강하다가 나온 오류입니다.모든 테스트를 실행했는데 이러한 오류가 나왔습니다. 해결책을 알려주시면 감사하겠습니다. java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@63bde6c2 testClass = hello.core.CoreApplicationTests, locations = [], classes = [hello.core.CoreApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@58670130, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@59d2103b, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@18518ccf, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6722db6e, org.springframework.boot.test.context.SpringBootTestAnnotation@e348e9fb], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:98) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) at java.base/java.util.Optional.orElseGet(Optional.java:364) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'memberServiceImpl' defined in file [C:\study\core\out\production\classes\hello\core\member\MemberServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:237) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1355) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1192) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454) at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152) ... 17 moreCaused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.member.MemberRepository' available: expected single matching bean but found 2: memoryMemberRepository,memberRepository at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:218) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1420) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:907) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:785) ... 41 more