월 16,940원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
인터셉터 로그 순서 문의
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]아래 캡처처럼 로그가 나오는데, LogInterceptor다음에 LoginCheckInterceptor의 로그가 나와야 하는거 아닌가요? (/item url 을 접속했을 때 나오는 로그들 입니다.) LogInterceptor preHandle의 REQUEST를 쏘고나서 바로 LoginCheckInterceptor의 preHandle의 로그들이 나와서 문의 드립니다. 제가 잘못 알고 있는 거 같은데 다시 한번 설명 부탁 드립니다. 그리고 postHandle의 로그는 왜 안나온건지 궁금합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
select에서 sequence로 반복할경우 선택된 값이 보여지게 할려면 어떤식으로 해야할까요?
<select name="where" title="초급" class="sel_auto" th:field="*{beginnerCount}"> <option value="0">초급</option> <option th:each="num: ${#numbers.sequence(1, 10)}" th:text="${num + '명'}" th:value="${num}">1</option> </select>위와같이 numbers.sequence로 1~10까지 select로 만들었는데서버에서 th:field=*{beginnerCount} 값을 받아와서 만약 받아온 값이 5라고 하면 5가 선택되어지도록 하고 싶은데이럴 경우에는 어느부분을 수정을 해야 서버에서 받은 값이 선택이 되어질까요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@InitBinder
@InitBinder 를 사용하면어떤 매핑이 들어와도 @InitBinder 안의 검증기가 적용된다고 하셨는데이전에 mvc 설명에서 @modelattribute로 써주면 안의 내용이 모든 곳에서 다 적용되는것과 다른 개념인가요 ? 둘의 차이는 @InitBinder 를 사용하면@Validated 인자가 들어간 곳에서만 작동하는것 의 차이인가요 ?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
validator 질문 드립니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. ItemValidator를 보면, target을 Item으로 캐스팅 하는데 오류가 없을까요? target으로 입력될 ItemSaveForm은 Item으로 형변환하기엔 없는 필드가 존재합니다.(Id) 강사님께선 어떻게 원할하게 돌아가는지 궁금하네요.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
세션 사용시 memberId가 계속 같이 넘어오는 현상 문의
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]세션 저장소를 이용해서 클라이언트 요청을 서버로 받아오는데, 계속해서 memberId 값이 함께 넘어오고 있습니다. 코드를 봐도 문제가 없는것처럼 보이는데 제가 원인이 되는 코드를 못찾고 있는 거 같아 문의 드립니다. 어디를 삭제하거나 고치면 되나요? [SessionManager]package hello.login.web.session;import org.springframework.stereotype.Component;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Arrays;import java.util.Map;import java.util.UUID;import java.util.concurrent.ConcurrentHashMap;/** * 세션 관리 */@Componentpublic class SessionManager {public static final String SESSION_COOKIE_NAME = "mySessionId"; private Map<String, Object> sessionStore = new ConcurrentHashMap<>(); // 세션 저장소 /** * 세선 생성 * sessionId 생성 (임의의 추정 불가능한 랜덤 값) * 세션 저장소에 sessionId와 보관할 값 저장 * sessionId로 응답 쿠키를 생성해서 클라이언트에 전달 */ public void createSession(Object value, HttpServletResponse response){// 세션 id를 생성하고, 값을 세션 저장소에 저장 String sessionId = UUID.randomUUID().toString(); sessionStore.put(sessionId, value); // 쿠키 생성 Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId); response.addCookie(mySessionCookie); }/** * 세션 조회 */ public Object getSession(HttpServletRequest request){Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); if (sessionCookie == null){return null; }return sessionStore.get(sessionCookie.getValue()); }/** * 세션 만료 */ public void expire(HttpServletRequest request){Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); if (sessionCookie != null){sessionStore.remove(sessionCookie.getValue()); }}public Cookie findCookie(HttpServletRequest request, String cookieName){if (request.getCookies() == null){return null; }return Arrays.stream(request.getCookies()).filter(cookie -> cookie.getName().equals(cookieName)).findAny().orElse(null); }} [LoginController]package hello.login.web.login;import hello.login.domain.login.LoginService;import hello.login.domain.member.Member;import hello.login.web.session.SessionManager;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;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 javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@Slf4j@Controller@RequiredArgsConstructorpublic class LoginController {private final LoginService loginService; private final SessionManager sessionManager; @GetMapping("/login")public String loginFor(@ModelAttribute("loginForm") 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("logout") public String logout(HttpServletResponse response){expireCookie(response, "memberId"); return "redirect:/"; }@PostMapping("logout")public String logoutV2(HttpServletRequest request){sessionManager.expire(request); return "redirect:/"; }private static void expireCookie(HttpServletResponse response, String cookieName) {Cookie cookie = new Cookie(cookieName, null); cookie.setMaxAge(0); response.addCookie(cookie); }} [HomeController]package hello.login.web;import hello.login.domain.member.Member;import hello.login.domain.member.MemberRepository;import hello.login.web.session.SessionManager;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.CookieValue;import org.springframework.web.bind.annotation.GetMapping;import javax.servlet.http.HttpServletRequest;@Slf4j@Controller@RequiredArgsConstructorpublic class HomeController {private final MemberRepository memberRepository; private final SessionManager sessionManager;// @GetMapping("/") public String home() {return "home"; }// @GetMapping("/") public String homeLogin(@CookieValue(name = "memberId", required = false) Long memberId, Model model){if(memberId == null){return "home"; }// 로그인 Member loingMember = memberRepository.findById(memberId); if(loingMember == null){return "home"; }model.addAttribute("member", loingMember); return "loginHome"; }@GetMapping("/")public String homeLoginV2(HttpServletRequest request, Model model){// 세션 관리자에 저장된 회원 정보 조회 Member member = (Member) sessionManager.getSession(request); // 로그인 if(member == null){return "home"; }model.addAttribute("member", member); return "loginHome"; }}
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
인터셉터 제한시 리다이렉트 처리하지 않는 경우
질문이 있는 부분은 강의에서 인터셉터를 통해 로그인 인증을 구현하는 부분입니다.요청 중 로그인이 필요한 페이지에 로그인하지 않은 채 요청을 보내면 response.sendRedirect()를 하여 HTTP 응답 Location 헤더를 통해 /login 으로 리다이렉션하고 있습니다.@Slf4j public class LoginCheckInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); HttpSession session = request.getSession(false); log.info("인증 체크 인터셉터 실행 {}", requestURI); if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) { log.info("미인증 사용자 요청"); response.sendRedirect("/login?requestURL=" + requestURI); return false; } return true; } } 그러다 문득 response.sendRedirect() 을 주석처리하면 어떻게 될까 궁금해졌습니다.즉, 인터셉터 제한되는 상황에서 리다이렉트 처리하지 않으면 WAS 또는 스프링이 어떻게 처리하는지 궁금해진 것인데요. 해당 코드를 주석처리하고 로그인이 필요한 페이지로 브라우저를 통해 요청을 하얀색 화면이 나오는 것을 확인하였습니다.@Slf4j public class LoginCheckInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); HttpSession session = request.getSession(false); log.info("인증 체크 인터셉터 실행 {}", requestURI); if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) { log.info("미인증 사용자 요청"); //response.sendRedirect("/login?requestURL=" + requestURI); return false; } return true; } }포스트맨으로 응답을 확인하니 다음과 같았습니다.인터셉터 제한되는 상황이므로 컨트롤러가 호출되지 않았다는 사실은 알 수 있었지만,정확히 어떠한 흐름으로 응답이 처리되는지는 이해할 수가 없어 질문을 하게 되었습니다. 인터셉터 제한되는 상황에서 리다이렉트 처리하지 않으면, 이러한 응답은 누가 어떻게 보내주는 것인가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
bindingResult.rejectValue
bindingResult.rejectValue를 사용 할때bindingResult.rejectValue("itemName","required.item.itemName");이런식으로 required 만 사용하는게 아닌 full 경로를 입력해도 작동하는데이렇게 사용해도되는건가요? 아니면 이렇게 사용하면 문제점이있는건가요 ?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Test값 안녕 -> ?? 으로 인식되네요
위는 message.properties 입니다. 이는 Test 구요 안녕의 값을 Test하지만 실제는 ??로 인식이되네요어딘가에서 한글이 깨진거같은데 뭘까요
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:for="${#ids.prev('regions')}"
해당 th:for="${#ids.prev('regions')}" 구문을 사용해서regions에 대한 id값을 자동으로 할당받지 않아도즉 th:for="${#ids.prev('regions')}" 구문을 빼는것을 얘기합니다.소스보기를 하니 자동으로 regions 1,2,3 아이디값이 들어있는데이 경우에는 thymeleaf가 th:for="${#ids.prev('regions')}"를 사용하지 않아도 th:for="${#ids.prev('regions')}" 를 사용한것처럼 자동으로 인식해서 만들어줬다고 봐야할까요 ?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
비동기 Validation 오류코드 클라이언트에 반환하는것..
제가 회원가입과 로그인을 비동기로 처리하는데요. 일반 요청처럼 binding result에 오류 코드 담아서 클라이언트로 보내야하는데.. 아직 제 실력으로는 이걸 해결하기가 어렵네요 ㅠ커뮤니티 뒤져본결과 해당 비동기 처리하는 공유해주신 게시물들을 봐도 너무 어렵더라구요..이부분에 있어서 영한님 강의가 없을까요? ㅠ 하..추천 쿼리큘럼에 스프링부트 DB 1,2편까지는 구매해놨습니다..아직 API 예외처리 강의를 수강하지 못했는데, 이부분을 좀 더 이해할 수 있으려나요...
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
사이드 프로젝트를 만드려고 하는데 어느편까지 봐야할까요?
사이드 프로젝트를 만드려고 하는데 어느편까지 보고 만드는게 좋을까요?강의를 다 듣고 사이드 하기에는 좀 늦을 것 같아서...
- 해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
editForm.html
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 강의를 듣던 중 editForm.html에서 저장버튼의 타입은 submit으로 되어있고 저장버튼을 누를시에 form에 action이 item.html로 되어있는데 컨트롤러로 어떻게 가는지 궁금합니다!
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
프로젝트 세팅 DB
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 이번에 2편부터 보고있는데 강의를 보고 초기 프로젝트를 세팅만 했는데 DB가 있는거처럼 저장이되고 리스트가 뜨네요. DB를 세팅하지않고도 이렇게 저장수정목록이 뜰수있는 이유가 궁금합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
REST API로 통신
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]단계별 메시지 처리는 타임리프에서만 매칭이 되나요? REST API에서는 단계별 메시지 매칭이 되지 않는지 궁금합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
MVC1편을듣고왔는데 바로 DB1편으로
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]MVC1편을듣고왔는데 바로 DB1편으로 넘어가도되나요 ?MVC2편은 DB1편을 듣고나서 MYBATIS로 MVC1편에서 배운내용을 토대로 자그마한 토이프로젝트 하나 만들어보고 MVC2편을 듣고싶은데 그렇게 해도될까요 ?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
editForm에서 라디오 버튼
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]라디오 버튼을 복습하다가 수정 페이지에서 궁금한 점이 생겨 질문합니다.<div>상품 종류</div> <div th:each="type : ${itemTypes}" class="form-check form-check-inline"> <input type="radio" th:field="*{itemType}" th:value="${type.name()}" class="form-check-input"> <label th:for="${#ids.prev('itemType')}" th:text="${type.description}" class="form-check-label">BOOK</label> </div>만약에 아이템의 상품 종류가 책일 때,라디오 버튼이 반복문을 돌면서 모든 th:field의 itemType의 값은 책이 되는데 어떻게 책에 해당하는 버튼에만 체크 기능이 삽입되는지 궁금합니다.혹시 th:field에 값이 있다면 th:value와 비교해서 같다면 해당 라디오버튼에 checked가 삽입되는 걸까요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
dependency 추가
제가 실수로 프로젝트를 생성할 때 dependency를 추가못해서 intellij내에서추가하려고 https://velog.io/@dnwlsrla40/Intellij-intellij%EC%97%90%EC%84%9C-%EB%B0%94%EB%A1%9C-dependency-%EC%B6%94%EA%B0%80위 사이트를 참고해서 추가하려는데 search for artifact가 no result가 나오는데 어떻게 해결해야 하나요
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
multipart/form-data에서 List 사용하는 방법
안녕하세요질문이 있습니다!! multipart/form-data를 사용할 때 아래와 같은 요청은 컨트롤러에서 바인딩이 불가능 한 것일 까요..? name=items[0] Bag name=items[1] Book name=items[2] JpaBook import org.springframework.web.multipart.MultipartFile; import java.util.List; public class MyRequestDTO { private String username; private List<String> items; private MultipartFile file; // Getter와 Setter 메서드 } 감사합니다.
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
ResponseStatusException 관련 질문 드립니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 강의 중에 강사님께서 개발자가 직접 변경할 수 없는 예외에는 @ResponseStatus를 적용할 수 없다고 하셨는데, 이러한 예외가 예를 들어 무엇이 있나요? BadRequestException처럼 RuntimeException과 같은 예외를 상속받아 처리할 수 없는 경우를 말씀 하시는 건지 궁금합니다 ! 또한, ResponseStatusException은 어떤 경우에 사용되는지 구체적으로 궁금합니다. 동적으로 처리를 하기 위해서만 쓰이는 것인가요?
- 미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
경로문제 제가이해한게 맞는지 추가질문입니다.
https://www.inflearn.com/questions/1031594/%EC%97%84%EC%B2%AD-%EA%B8%B0%EC%B4%88%EC%9D%B8%EB%8D%B0-%EA%B8%B0%EC%96%B5%EC%9D%B4%EC%95%88%EB%82%98%EB%84%A4%EC%9A%94-%E3%85%A0%E3%85%A0-%EA%B2%BD%EB%A1%9C%EB%AC%B8%EC%A0%9C에 대해 제가 이해한게 맞는지 질문드립니다.만일 @RequestMapping("/basic")이있고 @GetMapping("text-basic") @GetMapping("/text-basic") 두개가있으면 위는 /basic/text-basic에 매핑되는 거고아래는 /text-basic에 매핑되는게 맞나요??