월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
PathVariable 앞에 커스텀 애노테이션을 붙이면 동작이 안 됩니다.
안녕하세요!@PathVariable 앞에 제가 만든 커스텀 애노테이션을 붙인 후 ArgumentResolver가 동작 되길 기대 했으나, supportsParameter나 resolveArgument에 어떠한 log가 찍히지 않는 것을 확인 했습니다.그런데 이유는 모르겠지만 @ModelAttribute 앞에 커스텀 애노테이션을 붙였을 때에는 동작 하더라고요. 왜 PathVariable 앞에 커스텀 애노테이션을 붙였을 경우에는 동작이 안 되는 지 모르겠습니다.구글링이나 GPT를 통해서도 열심히 찾아 봤으나 그 이유를 찾지 못했는데요. 문제점이 무엇인지 알려주시면 감사 드리겠습니다..!// 커스텀 애노테이션 @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Month { } // 컨트롤러 public Class 클래스 { ...... public 리턴타입 메서드(@Month @PathVariable Integer month) {} } // ArgumentResolver @Slf4j public class MonthArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { log.info("MonthArgumentResolver supportsParameter={}", parameter); return parameter.hasParameterAnnotation(Month.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { HttpServletRequest httpServletRequest = (HttpServletRequest) webRequest.getNativeRequest(); log.info("MonthArgumentResolver resolveArgument={}", httpServletRequest); return 1; // 임시로 1로 반한 함 } } // config @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(new MonthArgumentResolver()); } }
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Thymeleaf 3.1에서의 thymeleaf-extras-java8time 관련 업데이트 사항
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의에선 인텔리제이 우측 Gradle의 Dependencies에서 thymeleaf-extras-java8time 라이브러리를 찾을 수 있었는데, 제 인텔리제이에선 찾을 수 없더라고요. 검색해 보니 아래 링크에서https://www.thymeleaf.org/doc/articles/thymeleaf31whatsnew.html 1.4. Core support for the java.time package 항목에 The thymeleaf-extras-java8time extras module has been integrated into the Thymeleaf core: the #temporals expression utility object is now always available. 이렇게 나와 있습니다.타임리프 3.1부터는 스프링 부트가 자동으로 라이브러리를 추가해 줄 필요도 없이, 바로 사용할 수 있는 거로 변경된 거라고 보면 될까요? +)https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#appendix-b-expression-utility-objects 타임리프 3.1 공식 문서 튜토리얼에 Temporals(java.time) 관련 내용이 추가되었습니다.1. 타임리프 - 기본 기능.pdf(v20240224)에 있는 공식 문서는 3.0이라서 링크 첨부드립니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ModelAttribute 사용 이유가 헷갈립니다.
@Slf4j @Controller @RequiredArgsConstructor public class LoginController { private final LoginService loginService; @GetMapping("/login") public String loginForm(@ModelAttribute("loginForm") LoginForm form) { return "login/loginForm"; } @PostMapping("/login") public String login(@Valid @ModelAttribute LoginForm form, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "login/loginForm"; } Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); if (loginMember == null) { // 정보 불일치 시... // reject : 글로벌 오류 bindingResult.reject("loginFail", "아이디 또는 비밀번호가 맞지 않습니다."); return "login/loginForm"; } // 로그인 성공 처리 // TODO return "redirect:/"; // 성공 시 홈으로 리다이렉트 } }안녕하세요 '로그인 기능' 강의를 듣고 궁금한 점이 생겨 질문을 올립니다. @GetMapping("/login") public String loginForm(@ModelAttribute("loginForm") LoginForm form) { return "login/loginForm"; }위 메서드는 "/login"이라는 GET 요청이 오면 loginForm 파일을 실행하게 됩니다. 따라서 단지 화면을 출력하는 역할에 불과한데, 왜 @ModelAttribute("loginForm") LoginForm form을 작성하신건지 이해가 잘 가지 않습니다. @GetMapping("/login") public String loginForm() { return "login/loginForm"; }그냥 위처럼 작성하면 안되는건가요? 만약 PostMapping처럼 데이터를 저장하는 요청이라면, ModelAttribute를 통해 LoginForm의 인스턴스를 저장하는 것이 이해가 가지만,GetMapping에는 왜 작성하신건지 이해가 잘 안갑니다 ㅠㅠ감사합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
스프링메세지 소스 사용 오류
@SpringBootTest public class MessageSourceTest { @Autowired MessageSource ms; @Test void helloMessage() { String result = ms.getMessage("hello", null, null); assertThat(result).isEqualTo("안녕"); } }를 실행했더니org.opentest4j.AssertionFailedError: Expecting: <"??">to be equal to: <"안녕">but was not.필요:"안녕"실제 :"??" 2024-04-07 17:34:37.790 INFO 6288 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'오류가 뜹니다. 이유가 뭔가요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
스프링 부트 3.0 미만에서 #session과 session의 차이
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]학습 자료에 나온 스프링 부트 3.0 미만 기준 내용에서 궁금한 점이 있습니다. ${#request}${#response}${#session}${#servletContext}${#locale} 타임리프는 위와 같은 기본 객체들을 제공하고,param, session 같은 편의 객체도 제공한다고 이해했습니다. 그런데 #session과 session은 무슨 차이가 있는 건가요? 다른 건 몰라도 세션은 #session을 바로 쓰면 되는데 편의 객체로 session을 또 제공하는 이유를 모르겠습니다. 문서를 보니 #이 붙으면 웹 컨텍스트 객체이고, param, session 같은 편의 객체는 컨텍스트에 추가된 맵이라서 # 없이 접근 가능하다곤 나와 있는데.. 아직 잘 모르겠네요.. 사용법이 다른가요? 전 스프링 부트 3.0 이상이라 테스트해 보기 좀 힘들어서 질문드립니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
라디오버튼이 강제 설정이 되지 않는 이유는?
라디오 버튼을 아래와 같이 수정했는데 , 상품등록 폼의 첫번째 라디오 버튼이 강제 설정이 안됩니다. 이유가 뭘까요? <div th:each="type, status : ${itemTypes}" class="form-check form-check-inline"> <input type="radio" th:field="*{itemType}" th:value="${type.name}" th:checked="${status.index == 0}" class="form-check-input"> <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label"> BOOK </label> </div>
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
WebServerCustomize의 어노테이션을 주석처리 하는 이유??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@Component를 주석처리하면 스프링 빈에 등록이 안되어 있으니 개발자가 예외처리를 안하고 발생한 예외를 스프링이 자동으로 처리하게 하도록 위함인건가요? 스프링은 /error의 경로로 자동 등록되는것은 이해하였는데 그 하위 html파일에 어떻게 매핑이 되는건지 잘 모르겠습니다. 그 이전에는 직접 경로를 설정해 주었는데 스프링이 자동으로 하는 경우에는 에러코드가 이름으로 설정된 html파일을 자동으로 보여주는 건가요?
- 미해결스프링 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 2편 - 백엔드 웹 개발 활용 기술
SendError 의 두번째 매개변수는 어디서 확인할 수 있나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? [질문 내용]response.sendError(404, "404 오류!");해당 코드에서 두번째 매개변수는 콘솔에도 브라우저의 응답에서도 확인할 수 없는데 왜그런걸까요?검색해보니까 server.error.include-message and server.error.include-binding-errors 이런설정들을 해보라고해서 해봤는데 그래도 응답에 포함되는거같지않아서요..ㅠ"404 오류!" 이 텍스트는 어디서 확인할 수 있을까요?
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
로그인 쿠키 처리 HomeController에서 질문이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]쿠키를 이용한 로그인 여부를 처리하기 위해 @RequirdArgsConstructor를 사용 하였는데 이 어노테이션은 생성자를 직접 작성하지 않도록 해주는 어노테이션으로 이해 하였는데 굳이 작성해주는 이유가 있나요?멤버리포지토리에서 값을 꺼내오기 위해 의존성을주입하여 private final MemberRepository memberRepository;를 작성해주셨는데 final을 실수로 생략 하였더니 500 오류가 발생하였습니다. 그 이유가 있나요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타임리프에서 어떤 부분이 typeMismatch 오류 메시지를 출력하는 건가요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.<div class="field-error" th:if="${errors?.containsKey('price')}" th:text="${errors['price']}"> 가격 오류 </div>타임리프의 이 부분이 typeMismatch에 대한 메시지 코드인 '숫자를 입력해주세요' 를 출력하는 건가요? 아니면 <input type="text" id="price" th:field="*{price}" th:errorClass="field-error" class="form-control" placeholder="가격을 입력하세요">이 부분의 th:field가 오류 감지하고 출력하는 건가요
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.강의에서 다른 타입이 바인딩 되면 자동으로 FieldError 생성해서 BindingResult에 넣는다고 이해했는데요 이걸 타임리프에서 어떤 부분이 출력을 해주는 건가요? 강의 뒤쪽보니까 th:field가 오류있으면 자동으로 보관된 값 출력해준다고 해서 th:field를 지우면 오류 표시가 안되나? 하고 지워봤는데 그대로 동작하더라고요 이유가 뭘까요 다른 타입을 매핑하면 화면에 오류메시지가 다른 타입이 바인딩 되었다는 메시지랑 저희가 BindingResult에 넣은 "가격은 1,000~1,000,000 까지 허용됩니다."메시지도 같이 출력되더라고요 그런데 저 메시지는 if문으로 판별해서 null이 거나 1000보다 작거나 1000000보다 크면 넣어주는데 필드가 다른 타입이면 if문이 작동하지 않을 것 같은데 왜 FieldError가 넣어지는 거죠?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
localhost:8080/template/layout 호출시 Whitelabel Error가 뜹니다.
(TemplateController)(base.html)(layoutMain.html)(에러화면) 왜 오류가 뜨는지 잘 모르겠습니다
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
에러코드 필터 , 인터셉터, AOP 선택
강의 수강 후 제 프로젝트에 AOP 로직을 적용해 보았습니다. 에러코드를 AOP를 빼서 모듈별로 적용했는데 에러코드의 경우 필터나 인터셉터로는 안되는 것일까요? 어떤 기준으로 공통 사용 부분을 필터, 인터셉터, AOP로 나눠서 각각 적용해야할지 모르겠습니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
basic-objects 에 관해 질문이 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]강사님의 HTML 코드, Java 코드 모두 복붙하여 진행하였는데, White Label 이 나옵니다.이 부분에서 #을 빼서 바로 받는 부분에 오류가 발생하는데, 왜 그런걸까요?? 제가 오타를 쳤을 까봐 코드도 강사님 것을 복붙 하였는데도 같은 오류가 납니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
도메인과 웹이 백, 프론트를 의미하는건가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]웹을 다른거로 바꾸어도 도메인은 바꾸지 않아도 된다고 설명해주신 부분이 프론트 클라이언트를 앱을 이용하든 웹을 이용하든, 리액트, html,css,is를 이용한 프론트를 이용하든 백앤드는 변경이 없어도 된다는것과 같은 말인건가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Boolean타입이 null일떄와 false일떄 어떤 위험이 있어서 히든 필드를 사용하나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]히든필드를 이용하여 체크를 안하면 널값이 들어가서 히든필드를 사용한다고 이해하였는데 널값이 들어가면 널포인트 예외 처리때문에 그런건가요? 단순히 널값이 문제라면 boolean타입을 이용하여 널값을 안받고 false로 받아도 되는거 아닌가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
리액트를 사용시 인라인 기능이 가능한가요?, 스크립트 영역의 데이터들을 출력하려면 어떻게 하나요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]리액트를 이용하여 프론트를 개발하면 리액트도 자바 스크립트 언어이니 똑같이 인라인 기능을 사용할 수 있나요? 자바 스크립트, 리액트 둘다 모르는 상태이지만 리액트가 자바 스크립트 기반이라고 알고 있어서 질문 드립니다.서버를 실행하였는데 스크립트 코드를 표시하려면 어떤 식으로 코드를 작성해야 하나요? 스크립트 영역 외부에서 <p th:text=“${user.username}></p>을 사용해보았는데 표시가 안되었습니다. 그리고 객체를 json으로 받았는데 json의 값들을 사용하려면 어떻게 해야 하나요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Bean Validation
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]Bean Validation는 두 가지 경우가 있다하였습니다. 1. @ModelAttribute 2. HttpMessageConverter를 이용하는경우이 두 경우에 대해서 속성 타입이 일치하지 않아 바인딩이 실패하는 경우1의 경우 해당 필드에 대해서 Bean Validation이 적용되지 않고 나머지 필드들은 정상 적용되어 나머지 필드들은 정상 바인딩 되고, Validator를 사용할 수 있다하였습니다.2의 경우 컨트롤러가 호출되지않고, Validator가 적용되지 않는다하였습니다.그렇다면 1의 경우 해당 필드(즉, 속성이 불일치하여 바인딩 되지 않는 필드)의 경우 Bean Validation 뿐만 아니라 Validator도 적용되지 않는지 궁금합니다. 그리고 typeMismatch의 경우는 어디에 속하는 것인지 궁금합니다. 또한, Bean Validation의 경우 글로벌 Validator가 적용되어 있어, @Valid, @Validated만 적용하면, 검증 오류가 발생하였을 때, FieldError, ObJectError를 생성해서 BindingResult에 담아주는 것으로 알고 있습니다.그렇다면 Bean Validation의 경우 꼭 코드에 명시적으로 BindingResult를 써야하는지 궁금합니다.제 생각은 굳이 쓰지 않더라도 즉, BindingResult를 명시하지 않더라도 Bean Validation에서 @Validated가 적용되었을 때, 검증 오류가 발생한다면 메세지 소스를 만들어 해당 메시지를 클라이언트에 전송하면 되는 것 아닌가 생각이듭니다. (CSR 방식입니다.) 이외에 혹시 추가적으로 알고있으면 좋은 정보들도 부탁드립니다. 감사합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
컨버터와 포맷터 우선순위 질문
조금 억지 질문이긴한데요"1000" -> "1,000" 으로 바꿔주는 StringToCommaConverter A와"1000" -> "1,000"으로 바꿔주는StringCommaFormatter B가 있다면A와 B중 어떤게 먼저 실행되나요?또"1000" -> "1,000$"으로 바꿔주는StringDollarFormatter C까지 있다면B와 C중 어떤게 먼저 실행되나요?