안녕하세요. 좋은 강의 감사합니다. 직렬화, 역직렬화 관련해서 질문이 있습니다. 저는 Spring 프레임워크를 사용해서 프로듀서와, 컨슈머를 각각 따로 서버를 만들어서 개발 하고 있습니다. 수업 내용은 단순히 String이지만 제가 실무에 사용하려고하는건 웹 애플리케이션 과 같이 DTO 클래스로 받은 데이터를 그대로 프로듀서에서 send()에 담아서 보내고 있습니다. 컨슈머에서 DTO로 받으려고 관련 자료를 찾아 보니 JsonSerializer가 있어 해보았습니다. Object 로 받아서 여러 DTO를 받을 수 있는 Consumer factory를 만들다 보니 여러 에러가 발생해서 ObjectMapper를 사용했습니다. @Component public class ObjectMapperService { private final ObjectMapper objectMapper = new ObjectMapper(); public <T> T convertValue(String json, Class<T> valueType) throws JsonProcessingException { return objectMapper.readValue(json, valueType); } } @Component @Slf4j @Data @RequiredArgsConstructor public class KafkaConsumer { private final ObjectMapperService mapper; @KafkaListener(topics = "member-join", containerFactory = "commonKafkaListenerContainerFactory") public void receiveMemberJoin(ConsumerRecord<String, String> consumerRecord, Acknowledgment acknowledgment) throws Exception { String value = consumerRecord.value(); MemberJoin memberJoin = mapper.convertValue(value, MemberJoin.class); String recommendCode = memberJoin.getRecommendCode(); log.info("recommendCode: {}", recommendCode); log.info("received payload = {}", memberJoin.toString()); acknowledgment.acknowledge(); } } 이런식으로 사용해서 DTO클래스로 사용했는데 실무에서는 어떤식으로 하는지 궁금합니다. 혹시 참고할 수 있는 정보가 있을까요? 감사합니다.
1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 강의 내용 들으면서 예시 프로그램 만들어 봤습니다. MemberDTO 에는 회원 가입시 비밀번호 확인 하는 부분이 없습니다. 이때, 비밀번호랑 비밀번호 확인란이랑 같은 것이 입력되었는지 확인하고 싶어서 이렇게 ModelAttribute로 member랑 mbrPwdConfirm을 넘겨 받아서 member의 pwd와 mbrPwdConfirm의 값이 같은지 비교했습니다. 그후 로그인 화면으로 리다이렉트 했는데, 이때, 이렇게 위에 mbrPwdConfirm부분이 쿼리로 나타납니다. singIn 함수에서 mbrPwdConfirm 부분을 제거 하고, request.getParameter("mbrPwdConfirm")을 하면 되긴합니다. 왜 전자의 방식은 안되고 후자의 방식은 되는 지 궁금합니다. 또한, 리다이렉트시 이 부분을 없애고 싶은데, 그러면 modelAttribute 부분을 없애야 하는데... 그러면 signIn함수에서 값을 사용을 못합니다....
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. ========================================= 헤매다가 해결했는데 다른 분들께 도움이 될 것같아서 커뮤니티에 남깁니다 ㅎ_ㅎ .gradle 폴더 내 6.8.2 파일 삭제(gradle 충돌 방지) gradle/wrapper/gradle-wrapper-.properties 수정 distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip build.gradle 파일 수정 plugins { id 'java' id 'org.springframework.boot' version '3.2.5' id 'io.spring.dependency-management' version '1.1.4' } group = 'hello' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() } javax -> jakarta 수정 // import javax.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
public class OrderController { private OrderService orderService; private MemberService memberService; private ItemService itemService; @GetMapping(value = "/order") public String createForm(Model model) { List<Member> members = memberService.findMembers(); List<Item> items = itemService.findItems(); model.addAttribute("members", members); model.addAttribute("items", items); return "order/orderForm"; } @PostMapping("/order") public String order(@RequestParam("memberId") Long memberId, @RequestParam("itemId") Long itemId, @RequestParam("count") int count) { orderService.order(memberId, itemId, count); return "redirect:/orders"; } } 제가 http관련 수업을 들었지만, 코드로 적용할 때, 좀 헷갈리는 부분이 있어서 질문드립니다. @GetMapping은 기본적으로 "order" url에 이동했을 때, 실행되는 것이 맞나요? order 페이지로 이동했을 때, 자동으로 createForm 메소드가 실행돼서 모델에 members와 items를 담고 order/orderForm으로 전달하는 절차가 맞나요? 반대로 @PostMapping은 기본적으로 "order" url에서 값의 전달이나 변경이 있을 때, 실행되는 것이 맞나요? order url에서 값을 입력하고 버튼과 같은 동작을 누르면, 그 때 order 메소드가 실행돼서 매개변수로 넘어온 memberId, itemId, count로 주문해서 저장하는 것이 맞나요? 결론적으로 차이점을 말하자면, get방식은 해당 url로 접속했을 때 실행되는 것이고, post는 해당 url에서 값을 변경이나 전달할 때 실행되는 것이 맞나요?
[질문 내용] 여기에 질문 내용을 남겨주세요. https://drive.google.com/file/d/1fuxg2PcUZOT1bxTbwcTS5ZLdbO-Iz_M5/view?usp=drive_link 현재 제 프로젝트 압축파일을 구글 드라이브에 업로드했습니다. 현재 듣고 있는 강의는 섹션7. 조회한 빈이 모두 필요할 때, List,Map입니다. 듣고 있는 부분은 8분34초 입니다. https://www.inflearn.com/questions/1089023/ 이 답변을 참고해서 해결방안 2, 해결방안 3을 모두 적용해봤지만 오류가 해결되지 않고있습니다. 어떤작업을 해야할까요..?
안녕하세요 강의 잘 보고 있습니다. 다름이 아니라 예외를 처리하는 부분에서 이해가 잘 가지 않는 부분이 이렇게 질문을 드립니다. 스프링 시큐리티의 FilterChainProxy의 끝단에 예외를 처리하는 ExceptionTranslationFilter가 존재합니다. 해당 필터가 인가 예외를 처리하는 것까지는 이해하였습니다. 그러나 인증예외를 다루는 것이 조금 이해가 가지 않습니다. 스프링 시큐리티에서 제공하는 formLogin 인증을 포함한 모든 인증 방식은 ExceptionTranslationFilter앞에 존재합니다. 그럼에도 불구하고 인증 필터들에서 발생하는 예외들을 ExceptionTranslationFilter에서 처리를 합니다. 기존의 저는 예외가 발생할 즉시 바로 자신을 호출한 객체에게 예외를 반환하며 프로세스가 진행한다 알고 있는데 이는 스프링 시큐리티에서 인증예외를 처리하는 흐름과는 정 반대의 흐름입니다. 혹시 인증 필터에서 해당 예외가 발생할시 예외를 Throw하는 것이 아닌 다른방식으로 예외를 감싸서 ExceptionTranslationFilter까지 흘러가는 건가요? 아니면 제가 놓치는 부분이 있는걸까요?
개인적으로 Mock은 상태를 (내가 작성한 값을) 반환하는 것 , Stub은 상태가 (내가 작성한 구현대로) 반환되는 것 이라고 정의를 내리고 있습니다. 이와 같은 표현으로 차이를 이해하고 있어도 괜찮을까요? 아니면 좀 더 명확한 표현이 있을까요? Mock 객체에 우리가 원하는 행위를 정의(Stubbing)하면, 그 객체는 이제 Mock 객체라고 해야하나요 아니면 Stub 객체라고 해야하나요? 아래 코드를 보고 Mock 객체인 mailSendClient의 send 메서드에 대한 Stubbing이 이루어졌다. 라고 하면 맞는 표현인가요? @ExtendWith(MockitoExtension.class) class MailServiceTest { @Mock private MailSendClient mailSendClient; @Mock private MailSendHistoryRepository mailSendHistoryRepository; @InjectMocks private MailService mailService; @DisplayName("메일 전송 테스트") @Test void sendMail() { // given when(mailSendClient.send(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); // when boolean result = mailService.sendMail("", "", "", ""); // then assertThat(result).isTrue(); // verify(mailSendHistoryRepository, times(1)) // .save(any(MailSendHistory.class)); } } mailSendClient는 Mocking하더라도 상태검증을 할 수도 있고, Stubbing하더라도 행위검증을 할 수도 있지 않나요? 이 둘의 차이는 Mockist와 Classicist의 차이이지, Mock과 Stub의 차이라고 할 수 없지 않을까요?
예전에 영한님이 답변하신 내용 중에 스프링이 제공하는 트랜잭션은 처음 시작한 트랜잭션을 기반으로 전파됩니다. 그러니까 서비스에서 트랜잭션을 시작하면 리포지토리의 트랜잭션이 해당 트랜잭션을 그대로 이어 받습니다. 라는 내용이 있었습니다. 그렇다면, 컨트롤러, 서비스, 리포지토리 순으로 코드가 진행된다고 할 때, 만약 서비스 계층에 @Trasnactional(readonly=false) 가 걸려있고 리포지토리 계층에 @Trasnactional(readonly=true) 가 걸려있으면 서비스 계층이 먼저 호출되므로 readonly=false 옵션이 적용된 채로 리포지토리 계층까지(기존 리포지토리 계층의 옵션은 무시된채로) 코드가 흘러가는걸까요?
안녕하세요? 섹션8. 메서드 기반 권한 부여 강의 보다가 잘 안되는 부분이 있어서 질문 드립니다! (16분 쯤에 설명 나오는 부분입니다!) @GetMapping("/user/{id}") @PreAuthorize("#id == authentication.name") public String authentication(@PathVariable(name = "id") String id){ return id; } 해당 강의에서 user 로 로그인 시 위 url 로 접근이 가능했는데, 똑같이 해봤는데 403 이 떴습니다. 혹시나 해서 공유해주신 github 프로젝트로 해당 branch 로 체크아웃했더니 같은 현상이 나타납니다. 이것저것 시도해보다가 스프링 공식페이지에서 @P 어노테이션에 대한 설명이 있길래 아래와 같이 도입해봤더니 정상동작합니다. @GetMapping("/user/{id}") @PreAuthorize("#id == authentication.name") public String authentication(@P("id") @PathVariable(name = "id") String id){ return id; } https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html 강의 하실 때보다 시큐리티 버젼이 또 올라가서 안되는 부분이 생긴 것일까요? 아니면 제가 어떤 부분을 놓치고 있는걸까요? ㅠ
[질문 내용] @Configuration 이 붙은 클래스는 스프링 컨테이너에 설정 정보를 의미하는것으로 @Configuration 이게 붙은 클래스도 싱글톤이 보장되어야 하기 때문에 @Bean으로 등록되어 싱글톤을 보장하고 자동주입의 경우에 빈 이름을 @Component 에노테이션이 붙은 클래스를 빈 이름으로, 실제 의존관계 주입이되는 반환 객체를 @AutoWried 에노테이션이 붙은 생성자로 주입되는게 맞을까요?! 제 머릿속에 있는 걸 그려봤는데 저런식으로 되는게 맞을까요?!
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 이 의미를 제가 이해한 대로라면 application.properties에 제가 아무 것도 추가하지 않으면 스프링 부트가 알아서 application.properties에 spring.messages.basename=messages 이걸 추가하고, 이렇게 messages만 지정되어도 부가적으로 messages_en.properties, messages_ko.properties 이것들도 인식되는 거로 이해했습니다. 꼭 ko나 en 말고도 messages_temp.properties 또는 messages_sdfsdf.properties 이것들도 다 인식된다고 보면 되나요? 아니면 _ 뒤에 와야 하는 건 kr이나 en 등 몇 가지가 따로 지정되어 있는 걸까요? 2) 또 하나 궁금한 점이 있습니다. 스프링 부트를 쓰지 않고 @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasenames("messages"); messageSource.setDefaultEncoding("utf-8"); return messageSource; } 이 코드를 쓴다고 한다면, 이때도 messageSource.setBasenames("messages"); 이렇게 messages만 지정하면 messages_en.properties , messages_ko.properties 다 인식할 수 있나요?
실제 서비스에서 수백 수천의 사용자가 접속을 하였는데 풀에 등록된 커넥션이 100개밖에 없으면 선착순 100명에 들지 못한 나머지 사람들은 계속 대기 하고 반환된 풀을 가져다 사용하는거로 이해했습니다. 관리자 입장에서 사용자 대기를 줄이기 위해 풀의 최대 갯수를 최대로 많이 하면 사용자의 대기 없이 즉각적으로 접근이 가능해서 더 좋은 서비스를 제공이 가능한것 같은데 굳이 기본 풀 갯수를 10개로 설정한 이유가 있나요? 그리고 풀의 최대갯수는 몇까지 가능한가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 찾아보니까 맥이나 리눅스만되고 윈도우는 안만들어지는게 맞는거같은데.. 이게 맞나요? 아래파일들이 생성되던데 아래파일들로는 System.out.println 로그는 확인할수가없네요ㅠㅠ catalina.out파일처럼 실시간으로 기록시키는법은없나요??
Spring boot redirect질문입니다. 최근 spring boot, thymleaf를 사용하여 사이드 프로젝트를 진행중에 있습니다. spring boot서버를 클라우드에 배포를 하고 서비스를 테스트 과정에서 클라이언트의 요청에 따라 api를 통해 redirect를 하는 과정이 있습니다. 문제는 redirect를 하게되면 배포 서버 도메인으로 요청 되는것이 아니라 localhost 로 요청이 되어 원하는 화면으로 넘어가지 않습니다. 예를 들어 (1) https://port-0-teammatchservice-1cupyg2klvm5dc4u.sel5.cloudtype.app/ (2) https://localhost:8080/ 첫번째 주소로 redirect를 해야되는데 두번째 주소로 리다이렉트가 됩니다. 메인 페이지에서 다른 페이지로 넘어가는 거는 문제가 없지만 redirect를하게 되면 도메인이 localhost 로 바뀌어서 문제가 되고 있습니다. 그래서 이 문제를 해결하기 위해서 RedirectView를 사용해서 배포서버 도메인에 맞게 url을 수정하여 요청하는 방식을 하려고 합니다. 혹시 이 방법 말고 일괄적으로 redirect의 도메인 주소를 바꿀 수있는 방법이 있을까요?없다면 이 상황에서는 어떤 방법으로 하는게 좋을까요?
//==생성 메서드==// public static OrderItem createOrderItem(Item item, int orderPrice, int count) { OrderItem orderItem = new OrderItem(); orderItem.setItem(item); orderItem.setOrderPrice(orderPrice); orderItem.setCount(count); item.removeStock(count); return orderItem; } 이러한 생성메서드는 언제 사용하는건가요? 코드를 분석해보니 연관관계에서 다 대 1인 케이스에서, '다'쪽에서 생성 메서드를 사용하는 것 같은데 맞나요? 감사합니다.