묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
th:if ${param.status} / 뷰 템플릿 메시지 추가 부분 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] (컨트롤러)@PostMapping("/add") public String addItemV6(Item item, RedirectAttributes redirectAttributes){ Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId",savedItem.getId()); redirectAttributes.addAttribute("status", true); //PRG (Post / Redirect / Get) 으로 문제를 해결 return "redirect:/basic/items/{itemId}"; } (html 타임리프 부분)<h2 th:if="${param.status}==true" th:text="'저장 완료!'"></h2> <h2 th:if="${#bools.isTrue(param.status)}" th:text="'저장 완료2!'"></h2> (요청 URL)http://localhost:8080/basic/items/1?statushttp://localhost:8080/basic/items/1?status=true수업에 보면 redirectAttribute에서 파라미터를 설정해줘서 status=true가 쿼리 스트링으로 넘어가는걸 확인했습니다.여기에서 실험정신이 들어서 status=true3 이라던가, status=false로 직접 url을 입력해서 요청했는데 제가 생각하는 bool true 가 아닌데도 true 처리가 되어서 저장완료와 저장완료2 라는 문구가 나오게 됩니다.타임리프에서는 어떻게 처리가 되길래 쿼리스트링이 false 여도 저장완료가 나오게 되는건지 궁금합니다.. 아니면 제가 어디선가 잘못 친건지 잘 모르겠습니다
-
미해결실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
안녕하세요 강사님 도메인 생성 시 주 생성자에 관한 질문드립니다.
안녕하세요 강사님~ 강의 너무 재밌게 잘 보고 있습니다.강의중에 User 리팩토링 과정에서 userLoanHistories를 주생성자에 선언하셨는데@Entity class User( @Column(nullable = false) var name: String, val age: Int?, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, ) { // 클래스 바디로 내려도 되나요? @OneToMany(mappedBy = "user", cascade = [CascadeType.ALL], orphanRemoval = true) val userLoanHistories: MutableList<UserLoanHistory> = mutableListOf() (...) }기존 자바코드에서는 이 컬랙션은 내부적으로 사용될뿐 getter로 접근하는 부분이 없기에 굳이 주생성자에 선언하는 것보다 클래스 바디로 내리는게 뭔가 더 자연스럽지 않나 하여 질문드렸습니다..!
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
안녕하세요 압축프로그렘을 다운받은후에 compile해보니 오류가 발생해서 질문드립니다
이유가 뭘까요 사진 첨부해드릴게요 이거는 다른 글을 보니 추가해주니 해결되었다던데 저는 여젼히 컴파일에서 오류가 발생하네요
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Test코드에 response와 request 순서가 반대가 아닌가요 잘 이해가 안되는 것 같습니다
클라이언트가 request하니까 request가 먼저 아닌가요?서버가 response받으니까 response인가요?개념 이해가 잘 안되는 것 같습니다.. 어떻게 이해하면 좋을까요?
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
SpringMemberControllerV3 메서드
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]SpringMemberControllerV3에서 각 메서드를 String으로 반환하여도 정상작동 하는 이유가 무엇인가요??adapter에서 String반환값을 이용해서 ModelAndView를 생성해서 Dispatcher Servlet으로 반환하나요?
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HttpServletRequest request, HttpServletResponse response 파라미터
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]SpringMemberSaveControllerV1 클래스에서 HttpSerlvet을 상속받지 않았는데 HttpServletRequest request, HttpServletResponse response 객체를 사용 할 수 있는 이유가 궁금합니다.
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
@RequestMapping
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@RequestMapping에서 url이 매핑이 되는 순간 Dispatcher Servlet에서 RequestMappinghandlerMapping과 RequestMappinghandlerAdapter가 호출되면서 RequestMapping에 해당하는 메서드가 실행되는건가요?
-
미해결스프링 핵심 원리 - 기본편
order 관련 코드가 이해가 안됩니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요강사님 코드를 계속 따라오다 코드를 한번 쭉 훑어 보는 시간을 가졌는데 갑자기 이해가 안되어 강의를 다시 봤는데도 헷갈려 질문 드립니다. OrderApp 클래스에서 OrderService orderService = applicationContext.getBean("orderService", OrderService.class); Order order = orderService.createOrder(memberId,"itemA",10000); 라고 사용할 수 있는 이유가 뭔가요??orderService는 인터페이스 이고,orderService에 있는 메소드는 추상 메소드라서 그 내용이 구현되지 않은 상태이므로, orderService.createOrder 메소드를 바로 사용할 수 없는 것 아닌가요?? OrderServiceImpl 클래스에서코드:private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy;//인터페이스에만 의존하도록 설계. 이렇게 해서 구체적인 구현체에는 신경을 안씀. @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository=memberRepository; this.discountPolicy=discountPolicy; } @Override public Order createOrder(Long memberId, String itemName, int itempPrice) { Member member = memberRepository.findById(memberId); int discountPrice = discountPolicy.discount(member, itempPrice); return new Order(memberId, itemName, itempPrice, discountPrice); }코드에서. 아래 코드가 잘 이해가 안됩니다.private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy;//인터페이스에만 의존하도록 설계. 이렇게 해서 구체적인 구현체에는 신경을 안씀.MemberRepository라는 인터페이스를 위와 같이 사용하고 구성하는 이유가 명확하게 잘 와닿지 않습니다.이렇게 설계하는 이유가 아래 첨부한 사진과 같을 것이라고 예상은 되는데.. 설명 부탁드리겠습니다.private final MemberRepository memberRepository;private final DiscountPolicy discountPolicy;// 코드에서인터페이스에 private와 final을 붙인 이유가 무엇인가요??MemberRepository라는 것은 멤버들의 ID가 저장되어 있기 때문에 모든 클래스들이 접근하고 수정될 수 있어야 하는 것 아닌가요?? 그리고 자바 스프링에서 인터페이스의 역할은 무엇인지 알 수 있을까요??아래와 같은 사진과 같이 설계하는 것이 의존성 주입을 위해서 라는 것은 어렴풋이 이해하겠습니다..근데 명확하게 인터페이스가 어떤 역할을 한다는 것이 잘 이해가 안됩니다. 인터페이스란 말 그대로 "클래스에서 어떤 값을 가져올 때, 인터페이스에 정의된 형식을 통해서 값을 가져온다?"이런 느낌으로 이해하면 될까요?? 5.그리고 이걸 종합적으로 이해하면자바 스프링에서는 "빈과 인터페이스와 직접적으로 연결된 느낌(?)이고, 인터페이스의 구체적인 내용(메소드 등)은 그 인터페이스를 현재 사용하는 자바 클래스(구현체)에서 정의한다." 이렇게 이해하는게 맞나요?즉, 인터페이스를 정의 해놓고, 상황에 따라 필요한 구현체를 갈아 끼운다라는 표현이 맞는건가요?? 모르는 부분이 많아 횡설수설 적었네요 죄송합니다.더위 조심하시고 설명 부탁드립니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
@GetMapping과 MemberController클래스
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]처음에 나오는 내용에 대한 질문입니다.혹시 @GetMapping("/members/new") 어노테이션에 대한 내용을 왜 MemberController클래스에 만드는 건지 알 수 있을까요?꼭 MemberController클래스에 만들어야 하는 건가요??
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
servlet 생성시점
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]HttpServlet을 상속받은 클래스는 어느 시점에 생성이 되나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
Spring Security 를 포함한 WebMvcTest 질문드립니다.
안녕하세요 좋은 강의 덕분에 테스트에 대해 많이 알게 되었습니다 :)스프링 시큐리티를 포함한 테스트와 관련해서 질문을 드려보고자 글을 쓰게 되었습니다. (강의에서는 스프링 시큐리티를 사용하지 않지만 테스트와 관련해서 물어볼 곳이 마땅치 않아 이 곳에 글을 남기는 점 양해해주시면 감사하겠습니다)@RequiredArgsConstructor @RestController @RequestMapping("/api") @Slf4j public class AuthController { private final AuthService authService; @PostMapping("/auth/sign-up") public String signUp(@RequestBody SignUpRequest request) { authService.signUp(request); return "회원가입 성공"; } }현재 회원가입을 하는 컨트롤러의 메서드는 다음과 같습니다. @Service @RequiredArgsConstructor @Slf4j @Transactional(readOnly = true) public class AuthService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; @Transactional public void signUp(SignUpRequest request) { if (userRepository.findByEmail(request.getEmail()).isPresent()) { throw new AlreadyExistException("이미 존재하는 이메일입니다."); } if (userRepository.findByNickname(request.getNickname()).isPresent()) { throw new AlreadyExistException("이미 존재하는 닉네임입니다."); } User user = User.builder() .name(request.getName()) .email(request.getEmail()) .password(request.getPassword()) .nickname(request.getNickname()) .role(UserRole.USER) .build(); user.passwordEncode(passwordEncoder); userRepository.save(user); } }그리고 실제 회원가입이 진행되는 로직은 이렇습니다. 그리고 제가 WebMvcTest 어노테이션을 사용해서 테스트 코드를 작성한 건 다음과 같습니다.@ActiveProfiles("test") @AutoConfigureMockMvc @WebMvcTest(AuthController.class) class AuthControllerTestWithWebMvcTest { @Autowired protected MockMvc mockMvc; @Autowired protected ObjectMapper objectMapper; @MockBean private AuthService authService; @MockBean private UserRepository userRepository; @DisplayName("회원가입 한다.") @CustomMockUser // 회원가입을 해야되는데 인증이 필요하다? -> 논리적으로 말이 안 됨 -> 올바른 테스트? @Test void signUp() throws Exception { // given SignUpRequest request = SignUpRequest.builder() .name("zun") .email("zun@test.com") .password("12345") .nickname("zunny") .build(); // then mockMvc.perform(post("/api/auth/sign-up") .content(objectMapper.writeValueAsString(request)) .contentType(APPLICATION_JSON) .with(csrf()) ) .andExpect(status().isOk()) .andDo(print()); } }보시다시피 회원가입 API에 요청이 제대로 되는지를 확인하기 위해 @CustomMockUser 라는 어노테이션을 사용하고 있습니다. (이 어노테이션은 테스트에서 인증을 처리하기 위해 만든 어노테이션입니다. 호돌맨님 강의를 참고해서 만들었습니다.)제가 혼란스러운 부분은 테스트코드에 써놓은 주석처럼 회원가입이 제대로 되는지를 테스트하기 위한 컨트롤러 코드인데 이걸 통과시키기 위해 인증을 담당하는 @CustomMockUser를 사용하는 것이 올바른 테스트인가 하는 의문입니다.@WebMvcTest를 사용하지 않고 @SpringBootTest를 사용하면 다음처럼 할 수가 있습니다.@ActiveProfiles("test") @AutoConfigureMockMvc @SpringBootTest class AuthControllerTest { @Autowired private UserRepository userRepository; @Autowired private ObjectMapper objectMapper; @Autowired private MockMvc mockMvc; @BeforeEach void tearDown() { userRepository.deleteAllInBatch(); } @DisplayName("회원가입 한다.") @Test void signUp() throws Exception { //given SignUpRequest request = SignUpRequest.builder() .name("zun") .email("zun@test.com") .password("12345") .nickname("zunny") .build(); //expected mockMvc.perform(post("/api/auth/sign-up") .content(objectMapper.writeValueAsString(request)) .contentType(APPLICATION_JSON) ) .andExpect(status().isOk()) .andDo(print()); } } 혹시 이와 관련해서 우빈님은 어떻게 생각하시는지, 그리고 스프링 시큐리티를 사용하는 프로젝트에서는 컨트롤러 쪽 테스트를 어떻게 하는 것이 좋은지 알려주시면 감사하겠습니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
rollback(false) 로 회원 추가 후, rollback(false) 없애고 다시 동일한 회원 추가 시
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]위의 회원가입 함수를 처음에 rollback(false)로 실행하면 데이터베이스에 Name이 "kim"인 데이터가 들어가는걸 확인했습니다. 질문1이후에 rollback(false)를 제거하고 다시 회원가입 함수를 실행하면 join에서 기존에 db에 "kim" 이라는 회원이 존재하기 때문에 예외가 발생해야 하는 것 아닌가요? 그런데 왜 정상적으로 join되었다가 롤백되는건지 궁금합니다.질문2예외가 발생한다고 예상했지만 오히려 기존의 "kim" 회원 또한 사라졌습니다. 기존의 데이터조차 사라지는 이유가 무엇인가요?. 테스트 하기 전 기존에 데이터베이스에 있던 데이터들은 롤백되어도 그대로 있어야 하는것 아닌가요? *혹시 테스트 메서드를 실행할때, 기본적으로 데이터베이스를 비우고 시작하는 건가요? 그렇다면 다시 롤백했을때 비어있는 데이터베이스로 돌아오게 되고, 그러면 위 궁금증이 해소되긴 합니다.
-
해결됨Practical Testing: 실용적인 테스트 가이드
Stock 엔티티의 예외처리 관련하여 질문 드립니다.
안녕하세요 강사님, 먼저 좋은 강의 잘 듣고 있어서 감사의 말씀 드립니다.테스트에 대한 질문은 아니지만 강의 중 작성해주신 코드에 관하여 궁금증이 생겨 질문 드립니다.만약 문제가 되는 경우에는 삭제하도록 하겠습니다. 먼저 궁금증이 생긴 위치는 다음과 같습니다.Business Layer 테스트 (3) 강의의 31:07Stock 엔티티의 deductQuantity 메소드에서 예외를 발생시키는 코드public void deductQuantity(int quantity) { if (isQuantityLessThan(quantity)) { throw new IllegalArgumentException("차감할 재고 수량이 없습니다."); } this.quantity -= quantity; } [질문]강의 중에서 deductQuantity 메소드에서 왜 isQuantityLessThan로 검증해야 하는지 설명해 주셨는데 그 부분은 이해가 되었습니다.그런데 예외 메세지를 직접 문자열로 작성해주는 부분에서 궁금증이 생겼습니다.스프링 빈에서 MessageSource 인터페이스를 통해 별도의 properties 파일로 예외 메세지 관리가 가능한데, 엔티티는 스프링 빈으로 등록되는 것이 아니어서 MessageSource를 통해 예외 메세지를 가져올 수 없을 것이라 생각됩니다. (그러나 deductQuantity가 호출되는 시점에서 진짜로 차감할 재고 수량이 있는지 체크하는 것도 타당하다고 생각합니다.) 그렇다면 서비스에서는 MessageSource를 통해 에러 메세지를 가져오되, 엔티티에서는 문자열로 직접 작성하는 방법밖에 없을까요? (대부분의 메세지는 properties 파일에 작성해두고, 엔티티에서만 직접 문자열로 작성하는 것이 약간 통일되지 않았다는 느낌이 들기도 하는데 어쩔 수 없는 것 같기도 합니다..)혹시 현업에서도 MessageSource로 메세지 처리가 가능한 부분은 MessageSource를 사용하고, 그렇지 않는 부분에서는 직접 문자열로 작성하는 방식이 많이 사용되는지도 궁금합니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
레퍼지토리가 여러개인 경우
만약 A라는 인터페이스를 상속받은 B,C,D 클래스가 모두 Repository로 컨테이너에 등록이 되어있고Service에서는 A 인터페이스를 선언하여 컨테이너로부터 주입을 받고자 한다면, 어떤것이 주입되는 것인가요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
실행을 시키다가 중지시키면
이렇게 빨간 글자들이 나오는데 문제 없는건가요? 강사님은 안뜨시는데 저만 뜨네요
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
레디스 라이브러리 장단점에 대해서 혼동이 있어서 질문드립니다.
강의 내용에 따르면 Redisson 을 사용하면 락 흭득 재시도를 기본으로 구성한다는 말씀을 해주셨습니다.RedissonLockStockFacade 예제를 보면decrease 메서드 내부에서 getLock 으로 락을 흭득하고 lock.tryLock() 호출을 통해 락을 잡는 다는 것으로 이해하였습니다.이 때 락 흭득 재시도를 lock.tryLock() 내부에서 이루어 지는 건가요??또한 lettuce 사용 시 락 흭득 재시도를 하는 과정은 while(!redisLockRepository.lock(key)) 를 통해서 스핀락 형태로 이루어지는건가요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
WAS 에 오류가 전달되는 방식의 차이에 대해 질문있습니다.
ServletExController 에서 sendError() 로 직접 오류를 WAS 에 전달해주면 Exception 이 터지지않은 것으로 간주되어 ErrorPageController 에서 사용중인httpServletRequest.getAttribute(ERROR_EXCEPTION) 의 결과가 로그에 찍히지않은 것이고, Exception 을 throw 해주어 간접적으로 WAS 에게 오류를 전달해주면 Exception 이 터진것으로 간주되어 httpServletRequest.getAttribute(ERROR_EXCEPTION) 의 결과가 로그에 찍힌것으로 이해하면 될까요? 답변부탁드리겠습니다!!
-
해결됨스프링 핵심 원리 - 기본편
Extract Method 창이 안 생깁니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네[질문 내용]Ctrl + Alt + m 누르고 다시 m 눌러도 안되고 Geforce Experience를 들어가서 게임 내 오버레이 기능을 OFF하면 된다는데 전 그것도 안 깔려져 있습니다. 어떻게 하면 해결할까요?
-
미해결스프링부트 시큐리티 & JWT 강의
[5강] admin, manager로 로그인시 403에러
안녕하세요! 강의 잘 듣고 있습니다.다름이 아니라 5강을 진행하던 중, DB에서 ROLE_ADMIN, ROLE_MANAGER로 바꾸어 주었는데도 403에러가 떠서 질문드립니다.<SecurityConfig>package com.example.SpringSecurity.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.security.web.SecurityFilterChain;@Configuration@EnableWebSecurity // 스프링 시큐리티 필터가 스프링 필터체인에 등록이 됨.@EnableMethodSecurity(securedEnabled = true)public class SecurityConfig {@Bean public BCryptPasswordEncoder encodePwd(){return new BCryptPasswordEncoder(); }@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {return http.csrf(AbstractHttpConfigurer::disable) // 사이트 위변조 요청 방지 .authorizeHttpRequests((authorizeRequests) -> { // 특정 URL에 대한 권한 설정. authorizeRequests.requestMatchers("/user/**").authenticated(); authorizeRequests.requestMatchers("/manager/**").hasAnyRole("ADMIN", "MANAGER"); // ROLE_은 붙이면 안 된다. hasAnyRole()을 사용할 때 자동으로 ROLE_이 붙기 때문이다. authorizeRequests.requestMatchers("/admin/**").hasRole("ADMIN"); // ROLE_은 붙이면 안 된다. hasRole()을 사용할 때 자동으로 ROLE_이 붙기 때문이다. authorizeRequests.anyRequest().permitAll(); }).formLogin((formLogin) -> {formLogin.loginPage("/loginForm") // 권한이 필요한 요청은 해당 url로 리다이렉트 .loginProcessingUrl("/login") // login 주소가 호출되면 시큐리티가 낚아채서 대신 로그인을 해준다. .defaultSuccessUrl("/"); //로그인 성공시 /주소로 이동 }).build(); }} <IndexController> package com.example.SpringSecurity.controller;import com.example.SpringSecurity.model.User;import com.example.SpringSecurity.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.ResponseBody;@Controllerpublic class IndexController {@Autowired private UserRepository userRepository; @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; @GetMapping({"/",""})public String index(){return "index"; }@GetMapping("/user")public @ResponseBody String user(){return "user"; }@GetMapping("/admin")public @ResponseBody String admin(){return "admin"; }@GetMapping("/manager")public @ResponseBody String manager(){return "manager"; }@GetMapping("/loginForm")public String loginForm(){return "loginForm"; }@GetMapping("/joinForm")public String joinForm(){return "joinForm"; }@PostMapping("/join")public String join(User user){System.out.println(user); user.setRole("ROLE_USER"); String rawPassword = user.getPassword(); String encPassword = bCryptPasswordEncoder.encode(rawPassword); user.setPassword(encPassword); userRepository.save(user); // 패스워드가 암호화가 안되어있으면, 회원가입은 잘되나 Security를 이용해 로그인 할 수 없다. return "redirect:/loginForm"; }@GetMapping("/info")public @ResponseBody String info(){return "개인정보"; }} 코드는 이러합니다. SecurityConfig는 v6이어서 수정하였습니다. 에러 해결에 도움 부탁드려요,,항상 좋은 강의 감사합니다!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ExceptionResolver ModelAndView 반환
안녕하세요스프링 MVC 2편 강의 중 'HandlerExceptionResolver 시작' 강의를 수강 중에 있는데요.강의시간 13:19분쯤에'빈 ModelAndView를 반환하면 뷰를 렌더링하지 않고, 정상흐름으로 서블릿이 리턴된다.''ModelAndView에 View, Model 등의 정보를 지정해서 반환하면 뷰를 렌더링한다.'라고 되어 있습니다. Api는 json데이터를 주고 받는 것인데 ModelAndView를 넘겨준다는게 이해가 가지 않습니다.jsonView로 담아서 모델앤뷰로 리턴하는 것도 아니고 화면으로 넘기는 모델앤뷰를 어떤의미로 사용하는 건가요? 그리고 만약 페이지 화면을 리턴하는 것이라면 여기서 빈 ModelAndView를 반환할 때는 따로 다른 뷰를 렌더링하지 않고 Exception이 발생했던 페이지 그대로 유지하나요?그리고 ModelAndView에 View, Model 등의 정보를 지정해서 반환해 뷰를 렌더링할 때에도 마찬가지로 정상흐름으로 서블릿이 리턴되는 것인가요?답변 부탁드립니다.