묻고 답해요
169만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
webDataBinder
ArgumentResolver가 파라미터를 만들 때 WebDataBinder에 존재하는 validator를 순차적으로 찾아서 적용시키는 건가요??
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
CRUD에 따른 ResponseDto를 보내는 유형 및 ResponseDto 구성 방식에 대한 질문
안녕하십니까 영한님.영한님 덕분에 JAVA Spring 기반 백엔드 개발의시작을 할 수 있었고,이제는 5개월 차 스타트업 백엔드 개발자로써 커리어를 시작하게 되었습니다. 현업에 와서는 오히려 취준생 때 보다 더 많은 고민을 하게 되느데요, 질문 1. 그중 최근에 CRUD의 각 상황별 API 응답을 어떻게 보내는게 적절할지, 질문 2. 그리고 ResponseDto를 어떻게 구성하는것이 적절할지에 대한 고민을 팀장님과 함께 하고있어서, 영한님의 생각을 여쭙고자 질문글을 올리게 되었습니다.답변 해주시면 정말 감사할 거 같습니다! Q1. 생성, 조회 , 수정, 삭제 API의 응답을 각각 어떻게 보내시는지 여쭤보고 싶습니다. 가장 먼저 조회의 경우는 말 그대로 path의 Entity 및 관련된 Entity 정보를 조합하여 응답 DTO로 변환하여 보내고 있습니다. 그런데 나머지 Write Operation에 대한 응답을 어디까지 보내야 하냐가 이슈 입니다.예를들면 엔티티의 생성의 경우 엔티티의 응답 DTO를 보내면 - 프론트에서 별도의 조회 API 호출 없이 바로 프론트가 화면에 뿌려줄 수 있으니깐 저는 생성의 경우에도 조회와 마찬가지로 Entity의 정보를 조합하여 응답 DTO로 변환하여 보내고 있었습니다. 그런데 이러한 부분이 Command Query Sperate 원칙에 어긋나는것 같아, 영한님께서는 혹시 생성한 Entity의 Key만 보내시는지, 아니면 Entity의 정보를 DTO로 변환하여 보내시는지 궁금합니다. 만약 Entity의 Id만 보내신다면 이후에 별도로 조회API를 호출해야 하고 그 또한 비용일텐데 이러한 부분은 어떻게 하시는지 여쭤보고 싶습니다. 이제 수정 API인데요,제가 다룬 비즈니스 로직의 경우 수정 비즈니스 로직이 다양하고 , 각 비즈니스 로직의 경우 다뤄지는 Entity의 종류가 다른 경우였습니다. (중심 Entity는 동일하지만, 연관된 Entity를 누구까지 건드리냐의 차이) 그래서 하나의 통일된 응답으로 보내기 모호한 점이 첫 번째 이유이고,애초에 수정 후에 프론트 화면에서 그 엔티티의 정보를 보여줄 필요가 없어서 라는 두번째 이유에 의해서 에초에 엔티티의 Id값도 보내지 않고 있었는데요,이 수정 API의 응답을 영한님은 어떻게 진행하지는지 그 이유가 궁금합니다. 마지막으로 삭제의 경우는 정말, 프론트에게 보낼 응답이 없어도 되는 경우 라고 생각했는데요,팀장님의 의견은 만약에 나중에 삭제한 Entity를 복구하는 요구사항이 추가되는것을 고려하여Id 정도는 넘기자는 의견을 내어주셨습니다.마찬가지로 삭제의 경우도 어떤식으로 수행하시는지 그 이유가 궁금합니다. Q3. 마지막으로 Entity의 ResponseDto의 필드를 어떤식으로 구성하시는지 궁금합니다 예를들면 저의 경우는 API는 프론트와 서버 간의 스펙이라고 생각하고, Entity의 단건조회의 경우는 단건 조회용 ResponseDto를, 전체조회의 경우는 전체 조회용 SummaryResponseDto를 별도로 만들어서 사용하고 있었습니다. 저희 팀장님 께서는 프론트쪽도 일을 해오시다가 , 백엔드쪽 분야로 전향하신 케이스 인데요,그렇다 보니 어떻게 해야 프론트의 생산성이 올라가는지를 고려하시는 분이셨고,팀장님의 생각은 서버에서 넘겨주는 응답에 일관성이 있어야 그 응답을 사용하는 프론트 측도 학습이 되고 놓치는 부분 없이 생산성이 올라간다는 의견이셨습니다. 그래서 Entity별로 당장 사용하지 않더라도 가능한 모든 필드를 담은 ResponseDto를 하나만 만들고,해당 ResponseEntity의 조합으로 각 API별 응답 Dto를 만들어서 사용하면 ,프론트 측 에서는 일관성 있는 응답값을 사용할 수 있다는 의견이셨습니다.물론 이 방법이 네트워크 패킷의 양을 쓸데없이 증가시킨다는 것을 알고 계시면서도,생산성에 큰 영향을 미치는 부분이라고 생각하셨습니다. 예를들어 다음과 같이 각 Entity의 응답 Dto의 조합별로 API의 ResponseDto를 만들 수 있습니다.ResponseDto{ UserDto{id : 1,name : “aaa”… // User엔티티의 거의 모든 필드} ItemDto{ id : 2,name : “bbb”,… // Item엔티티의 거의 모든 필드}} 저는 이러한 부분에 대해 생각해 본 적이 없이,그냥 제가 “해당 API를 호출하는 화면에서 필요한 정보들만을 담아 (혹은 여러 화면에서 쓰인다면 여러개를 고려) ResponseDto를 각각 만들어서” 넘겼는데요 영한님께서는 이러한 ResponseDto를 구성하는 부분에 있어서상황별로 필드를 재구성 하여 ResponseDto를 정의하여 사용하시는 편 인지 (SummaryResponseDto 등의 별도 Dto에 사용될 Entity의 필드들을 풀어서 정의하시는지)아니면 생산성을 고려하여 각 Entity별 Dto를 만들고, 이들을 조합하여 ReponseDto를 정의하시는 편 이신지 ,혹은 다른 규칙이 있으신지 궁금합니다. 물론 그렇다고 , 팀장님의 의견에서 전체조회시 사용하는 DTO와 단건조회시 사용하는 DTO가 동일하더라도,전체조회 후 단건조회를 할때 단건조회 API를 호출하지 말고 기존 Front가 가지고 있는 값을 쓰지는 말자는 의견 이십니다 (단건조회API는 별도로 호출해야 한다)그저 핵심은 프론트가 다루는 ResponseDto의 일관성을 위해서 입니다 (결론은 생산성을 위해) 긴글 읽어주셔서 감사합니다.항상 건강하셨으면 좋겠고,다음 강의들도 손꼽아 기다리고 있습니다!
-
미해결Practical Testing: 실용적인 테스트 가이드
생성과 수정 API 응답, 그리고 그 응답 Dto를 어떻게 구성할 것인가에 대한고민
안녕하십니까 강사님.저는 이제 5개월차가 된 신입? 백엔드 개발자 입니다.다름이 아니라 , 생성과 수정 API에 대한 응답으로 어떤 정보까지 넘기는것이 적합할지에 대해 고민을 하던 도중 강사님의 생각을 여쭤보고 싶어 질문을 드리게 되었습니다. Q1. 강사님 께서는 생성, 조회 , 수정, 삭제 API의 응답을 각각 어떻게 보내시는지 여쭤보고 싶습니다. 가장 먼저 조회의 경우는 말 그대로 path의 Entity 및 관련된 Entity 정보를 조합하여 응답 DTO로 변환하여 보내고 있습니다. 그런데 나머지 Write Operation에 대한 응답을 어디까지 보내야 하냐가 이슈 입니다.예를들면 엔티티의 생성의 경우 엔티티의 응답 DTO를 보내면 - 프론트에서 별도의 조회 API 호출 없이 바로 프론트가 화면에 뿌려줄 수 있으니깐 저는 생성의 경우에도 조회와 마찬가지로 Entity의 정보를 조합하여 응답 DTO로 변환하여 보내고 있었습니다. 그런데 이러한 부분이 Command Query Sperate 원칙에 어긋나는것 같아, 강사님께서는 혹시 생성한 Entity의 Key만 보내시는지, 아니면 Entity의 정보를 DTO로 변환하여 보내시는지 궁금합니다. 만약 정보를 다 보내신다면 이후에 별도로 조회API를 호출해야 하고 그 또한 비용일텐데 이러한 부분은 어떻게 하시는지 여쭤보고 싶습니다. 이제 수정 API인데요,제가 다룬 비즈니스 로직의 경우 수정 비즈니스 로직이 다양하고 , 각 비즈니스 로직의 경우 다뤄지는 Entity의 종류가 다른 경우였습니다. (중심 Entity는 동일하지만, 연관된 Entity를 누구까지 건드리냐의 차이) 그래서 응답으로 보내기 모호한 점이 첫 번째 이유이고,애초에 수정 후에 프론트 화면에서 그 엔티티의 정보를 보여줄 필요가 없어서 라는 두번째 이유에 의해서 에초에 엔티티의 Id값도 보내지 않고 있었는데요,이 수정 API의 응답을 성렬님은 어떻게 진행하지는지 그 이유가 궁금합니다. 마지막으로 삭제의 경우는 정말, 프론트에게 보낼 응답이 없어도 되는 경우 라고 생각했는데요,팀장님의 의견은 만약에 나중에 삭제한 Entity를 복구하는 요구사항이 추가되는것을 고려하여Id 정도는 넘기자는 의견을 내어주셨습니다.마찬가지로 삭제의 경우도 어떤식으로 수행하시는지 그 이유가 궁금합니다. Q2. 마지막으로 Entity의 ResponseDto의 필드를 어떤식으로 구성하시는지 궁금합니다 예를들면 저의 경우는 API는 프론트와 서버 간의 스펙이라고 생각하고, Entity의 단건조회의 경우는 단건 조회용 ResponseDto를, 전체조회의 경우는 전체 조회용 SummaryResponseDto를 별도로 만들어서 사용하고 있었습니다.(이런식으로 각 상황별 ResponseDto를 별도로 정의하고, 그 안에 관련된 Entity들의 필드를 직접 풀어넣는 방법) 저희 팀장님 께서는 프론트쪽도 일을 해오시다가 , 백엔드쪽 분야로 전향하신 케이스 인데요,그렇다 보니 어떻게 해야 프론트의 생산성이 올라가는지를 고려하시는 분 이셨고,팀장님의 생각은 서버에서 넘겨주는 응답에 일관성이 있어야 그 응답을 사용하는 프론트 측도 학습이 되고 놓치는 부분 없이 생산성이 올라간다는 의견이셨습니다. 그래서 Entity별로 당장 사용하지 않더라도 가능한 모든 필드를 담은 ResponseDto를 하나만 만들고,해당 ResponseEntity의 조합으로 각 API별 응답 Dto를 만들어서 사용하면 ,프론트 측 에서는 일관성 있는 응답값을 사용할 수 있다는 의견이셨습니다.물론 이 방법이 네트워크 패킷의 양을 쓸데없이 증가시킨다는 것을 알고 계시면서도,생산성에 큰 영향을 미치는 부분이라고 생각하셨습니다. 예를들어 다음과 같이 각 Entity의 응답 Dto의 조합별로 API의 ResponseDto를 만들 수 있습니다.ResponseDto{ UserDto{ id : 1, name : “aaa” … // User엔티티의 거의 모든 필드 } ItemDto{ id : 2, name : “bbb”, … // Item엔티티의 거의 모든 필드 }} 저는 이러한 부분에 대해 생각해 본 적이 없이,그냥 제가 “해당 API를 호출하는 화면에서 필요한 정보들만을 담아 |(혹은 여러 화면에서 쓰인다면 여러개를 고려) ResponseDto를 각각 만들어서” 넘겼는데요 강사님께서는 이러한 ResponseDto를 구성하는 부분에 있어서상황별로 필드를 재구성 하여 ResponseDto를 정의하여 사용하시는 편 인지아니면 생산성을 고려하여 각 Entity별 Dto를 만들고, 이들을 조합하여 ReponseDto를 정의하시는 편 이신지 혹은 다른 규칙이 있으신지 궁금합니다. 물론 그렇다고 , 팀장님의 의견에서 전체조회시 사용하는 DTO와 단건조회시 사용하는 DTO가 동일하더라도,전체조회 후 단건조회를 기존 Front가 가지고 있는 값을 그대로 쓰지 말고.,단건 조회용 API를 다시 호출하자 입니다!그저 핵심은 프론트가 다루는 ResponseDto의 일관성을 위해서 입니다 (결론은 생산성을 위해) 항상 좋은 강의,그리고 무엇보다도 강상님의 의견과 고민을 강의에 녹여주셔서정말 감사할 따름입니다. 덕분에 함께 고민하고 많이 배우는거 같습니다. 긴 글 읽어주셔서 감사합니다!
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
rejectValue() 사용시 arguments에 따른 defaultMessage
검증 로직에서 arguments 값이 있는 경우 defaultMessage를 작성하지 않으면 컴파일 에러가 발생합니다.이 이유는 무엇인가요? arguments는 메세지에 사용하는 인자를 뜻한다고 했는데 사용할 인자는 있는데 사용대상이 없을 경우를 대비한걸까요? if (!StringUtils.hasText(item.getItemName())) { bindingResult.rejectValue("itemName","required"); } if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) { bindingResult.rejectValue("price","range",new Object[]{1000,1000000},null); }
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
jpql 엔티티 인지 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]일단은 해결 했습니다.findAllString 이용하는데 Order를 얘가 모르는 거 같아서..String jpql = "select o From jpabook.jpashop.domain.Order o join o.member m";이렇게 패키지경로까지 다 명시해줬더니 인지를 하더라구요..안 그러면 org.hibernate.query.sqm.UnknownEntityException: Could not resolve root entity 'Order' at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:1960) ~[hibernate-core-6.2.13.Final.jar:6.2.13.Final] at org.hibernate.query.hql.internal.SemanticQueryBuilder.visitRootEntity(SemanticQueryBuilder.java:253) ~[hibernate-core-6.2.13.Final.jar:6.2.13.Final] ...............얘가 이렇게 Order 인지 못한다고 오류가 뜹니다..원래 엔티티는 그냥 @Entity 등록 하면 알아서 인지 되는걸로 알고 있었는데..왜 이런 걸까요?package jpabook.jpashop.domain; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Entity(name = "orders") @Getter @NoArgsConstructor(access = AccessLevel.PUBLIC) public class 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; public void changeMember(Member member){ this.member = member; member.getOrders().add(this); } public void addOrderItem(OrderItem orderItem){ orderItems.add(orderItem); orderItem.setOrder(this); } private void setOrderDate(LocalDateTime orderDate) { this.orderDate = orderDate; } public void changeDelivery(Delivery delivery){ this.delivery = delivery; delivery.setOrder(this); } private void setStatus(OrderStatus status) { this.status = status; } public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems){ Order order = new Order(); order.changeMember(member); order.changeDelivery(delivery); for (OrderItem orderItem : orderItems) { order.addOrderItem(orderItem); } order.setStatus(OrderStatus.ORDER); order.setOrderDate(LocalDateTime.now()); return order; } public void cancel(){ if(delivery.getStatus() == DeliveryStatus.COMP){ throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다."); } this.setStatus(OrderStatus.CANCEL); for (OrderItem orderItem : orderItems) { // orderItem.getItem().removeStock(orderItem.getCount()); orderItem.cancel(); } } public int getTotalPrice(){ int totalPrice = 0; for( OrderItem orderItem : orderItems){ totalPrice += orderItem.getTotalPrice(); } return totalPrice; } }
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
조회 및 읽기 트랜잭션 적용 문의
안녕하세요 트랜잭션 옵션 소개 강의를 시청 중에 궁금한 점이 있어 질문 드립니다. 데이터베이스에서 조회 및 읽기만 수행을 할 때 데이터의 변경이 없어 트랜잭션이 필요하지 않다고 생각하는데 굳이 트랜잭션을 거는 이유가 있을까요?? 보통은 클래스 레벨에 트랜잭션을 걸게되어 안에 있는 여러 메서드에도 트랜잭션이 자동으로 걸리게 되어 조회 혹은 읽기 메서드에도 트랜잭션을 의도하지 않게 걸리게 되는 것 일까요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ArgumentResolver 에서 null 체크
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요.인터셉터에서 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); log.info("인층 체크 인터셉터 실행 {} ",requestURI); HttpSession session = request.getSession(); if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null ){ log.info("미인증 사용자 요청"); response.sendRedirect("/login?redirectURL="+requestURI); return false; } return true; }세션이 있는지 체크를 하고 있는데,ArgumentResolver 에서 @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { log.info("resolveArgument 실행"); HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); HttpSession session = request.getSession(false); if (session == null) { return null; } return session.getAttribute(SessionConst.LOGIN_MEMBER); } 세션이 있는지 다시 체크하는 이유가 따로 있을 까요?인터셉터에서 이미 세션을 체크하고 , 세션이 없으면리다이렉트 시키는데, 중복 된 코드 아닌가요??
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
MemberForm은 이미 모델에 들어가 있는거죠?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]검증오류가 날 시 BindingResult에 의해 들어가는 게 아니라,저렇게 인자로 받는 건 이미 모델에 들어가 주는거죠?
-
해결됨실무 환경 그대로 주문게시판 만들기 웹개발 기초 마스터
별첨 자료가 어디있는지요
안녕하세요 강의를 수강하고 있습니다. 별첨 자료에 쿼리랑 참고하려고 하는데 별첨자료 파일이 어디있는지 못찾겠어서 경로 알려주시면 감사드립니다.
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
named lock vs 비관적 락
좋은 강의 너무 감사합니다.강의를 보며 궁금한 점이 생겨서 질문 드립니다. named lock을 통해 동시성 문제를 해결하는 예시를 보았을 때, 비관적 락과 무엇이 다른 것인지 큰 차이를 느끼지 못했습니다.named lock이 비관적 락에 비해 가지는 장단점에 비해 찾아보니, timeout 설정이 좀 더 간편하다는 내용 말고는 유의미한 차이를 찾지 못했습니다.(그러나 비관적 락 + queryhint 를 사용하면 비관적 락 사용 시에도 딱히 어려움 없이 timeout을 설정할 수 있었습니다.) 혹시 named lock이 비관적 락에 비해 지니는 장단점과, 어떤 경우에 비관적 락 대신 Named lock을 통해 분산락을 구현하시는지 궁금하여 질문드립니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
SpringPhysicalNamingStrategy 바뀐건가요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]찾아도 안나오는데 CamelCaseToUnderscoresNamingStrategy 이걸로 바뀐 것 같네요.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
정적 팩토리 메서드에 static이 붙어야 하는 이유
안녕하세요. 강의 잘 보고 있습니다! 다른 분 질문에 궁금한 것이 해소되지 않아 질문드립니다.https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-JPA-%ED%99%9C%EC%9A%A9-1&unitId=24297&category=questionDetail&q=30892&tab=community정적 팩토리 메소드 사용 이유중에 static 메모리에 올라가기때문에 새로운 객체를 생성하지 않는 장점이 있는 거라고 알고 있습니다. 이 예제의 경우 static을 빼도 JPA가 엔티티로 관리하면서 어차피 사용할 수 있는 부분아닌가요..? 라는 질문에서 강사님께서는 static을 빼보면 이해될 거라고 답변하셨습니다.제가 생각하기로는 정적 팩토리 메서드 안에서 생성자를 통해 인스턴스를 생성하는 것은 똑같아 보이고, 호출할 때 new가 아닌 Order.createOrder()로 호출하는 것 외에는 차이점을 못 느꼈습니다.조금 더 상세한 가르침을 주시면 감사하겠습니다!
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
List<Domain> -> List<Response> 변환을 Controller에서 하는 게 맞나요?
Domain -> Response 변환 코드를 Domain에 정의해두고Controller에서 Domain 메서드를 호출해서 Response를 변환하는게 맞나는 건 이해했습니다. 근데 실제 API에 해당 내용을 적용하려고 보니 Domain 단 건 조회보다는 List<Domain>을 반환하는 경우가 훨씬 많았습니다. 따라서 List<Domain>을 List<Response>로 변환해야 하는데 해당 작업을 for문이나 Stream으로 Controller로 처리하려니 Controller 코드도 지저분해지고 Controller가 하는 역할에 부합하지 않게 되는 것 같습니다.List<>를 변환할 때는 어디서 하는게 올바른 것인지 질문드립니다!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
세션아이디에 대해 질문드립니다..
HttpSession session = request.getSession();을 하게되면 쿠키가 생성되고, 쿠키의 이름은 JSESSIONID, 쿠키의 값은 랜덤값이라고 이해했습니다. 하지만 이전 강의를 보면 쿠키의 값을 세션id와 동일하게 설정을하고, 쿠키의 값을 통해 세션저장소에서 세션을 조회했는데요. 하지만 코드에서는 session.setAttribute(SessionConst.LOGIN_MEMEMBER, loginMember)로 상수를 세션id(key)로 지정했는데 이렇게 하면 SessionConst.LOGIN_MEMEMBER를 통해 세션저장소에서 세션을 조회해야하지않나요? 쿠키의 value와 세션저장소의 세션id가 동일하지않은데 어떻게 조회할수 있는지 궁금합니다..
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
deleteUser 관련 질문
현재 코드에서는 name을 기준으로 delete를 하는데요, findByName(name)을 이용한 코드에서 DB 안에 같은 이름의 회원이 2명 이상인 경우엔 오류가 생깁니다. 그 이유가 find는 return 개수가 1건이기 때문에 rollback 된다고 생각했습니다.이 버그를 수정하기 위해서 deleteUser의 파라미터는 Long id 로 수정했는데, 또 안 되더라고요...?findAll을 쓰면 같은 이름을 가진 모든 회원이 삭제될 것 같고... 어떻게 하면 동명이인의 회원 중에서 내가 원하는 한 회원만 삭제할 수 있나요? + 추가 방금 다른 학생분의 질문과 답변을 읽었습니다. 같은 내용의 질문인 것 같네요!그러면 파라미터를 Long id 로 변경하되, 현재 실습 중인 UI에서도 코드를 수정해야하는 부분이 있기에 삭제가 안 되는 게 맞다고 이해하면 될까요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
v1~v5에서 어느정도까지 알고넘어가야하는지 질문드립니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)ㄴ[2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)네[질문 내용]v5까지 강의를 진행했는데요코드를 다 따라하긴했는데 v3부터 각 코드가 무슨 역할을 하는지 이건 왜 이렇게 되는지 확실하게 짚고 넘어가는게 힘드네요..ㅠㅠ v1~v5까지는 mvc의 변화과정이니까 세세하게 코드를 이해하려 하지 말고 그냥 여기서는 왜 이렇게 바꾸는지, 이전 버전과 다른건 뭔지 등 큰 틀만 알고 넘어가도 큰 문제 없을까요?
-
미해결스프링 핵심 원리 - 고급편
@target 관련
안녕하세요 강의 잘 듣고 있습니다.강의 말미에 args, @args, @target은 단독으로 사용하면 안 된다고 하셨고 다음과 같은 이유를 말씀하셨습니다. '실제 객체 인스턴스가 생성되고 런타임에 적용 여부를 알 수 있다'아규먼트의 실제 타입을 요구하는 args, @args는 비교적 직관적으로 이해했는데, @target은 어째서 런타임에 적용 여부를 알아야만 하는 걸까요? 마치 @within이 그런 것처럼 클래스 내부에 특정 어노테이션이 있으면 해당 클래스부터 부모 클래스까지 AOP를 적용하면 될 것 같은데 말이죠.
-
해결됨스프링 핵심 원리 - 고급편
포인트컷 표현식 질문
안녕하세요 강의 잘 듣고있습니다.강의에서 등장하는 AtTargetAtWithinAspect의 execution 표현식을 보면 * hello.aop..*(..)로 기재되어 있습니다.이전 강의에서 학습했던 표현식(* hello.aop..*.*(..))과 어떤 차이점이 있는건가요?
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
MVC 패턴에서의 검증 책임이 누구에게 있는 지 궁금합니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요.안녕하세요 MVC 패턴에 대해 생각해보다가 고민이 생겨 질문을 남겨봅니다! 강의를 보면 사용자의 입력값 내지 요청에 대한 입증 책임을 가지는 것은 Controller이고, 그 요청에 대한 비즈니스 로직에 관한 검증 책임은 Service쪽에서 가져간다고 보는 것이 맞을까요? 예를 들어 회원가입을 하는 상황이라고 할 때, "닉네임은 한글로만 이루어진다"라는 상황에서 닉네임을 영어로 쳤다고 가정하면 이에 대한 검증은 Controller, "회원 간 중복된 닉네임은 가질 수 없다"라는 상황에선 Service 쪽에서 한다고 보는 것이 맞을까요? 그렇다면... view에서 검증을 하면 안 되는 이유나 비효율적인 예를 하나 들어주실 수 있으실까요??
-
해결됨재고시스템으로 알아보는 동시성이슈 해결방법
트랜잭션 전파속성, 데이터 소스
안녕하세요. 강의 잘 보고 있습니다. 의문이 생겨 질문을 남깁니다. 트랜잭션 전파속성을 REQUIRES_NEW로 해서 새로 생성한 이유가 있을까요? 그냥 REQUIRED로 하면 안되나요??강의 내에서 데이터소스를 분리하는 것을 추천해주셨는데, 커넥션 풀 사이즈를 늘리면 안되나요?? 감사합니다.