묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 핵심 원리 - 기본편
모바일(코틀린) 앱을 제작하려하는데 스프링을 이용해서 rest api 서버를 만드려고 합니다.
모바일(코틀린) 앱을 제작하려하는데 스프링을 이용해서 rest api 서버를 만드려고 합니다. 시간이 촉박해서 최대한 적게 배우고 만들고 싶은데 그렇다면 어느정도까지 스프링을 알아야 할까요?
-
미해결스프링 핵심 원리 - 기본편
다음 강의 커리큘럼에 대해 궁금한게 있습니다
안녕하세요. [ 스프링 핵심원리 기본편 / 자바 ORM 표준 JPA 프로그래밍 기본편 / 스프링 입문 ] 이 세 강의를 들은 후 SpringBoot - JPA(Mysql ) 을 활용한 프로젝트를 진행해보고 있습니다. 그런데 [ SpringBoot - JPA(Mysql ) 의 설정 ( application.properties )] , [ 엔티티와 빈 컨테이너 구현 ] 관련해서 어려운게 있어서 추가적으로 강의를 하나 더 듣고 싶은데 1. 모든 개발자를 위한 HTTP 기본 상식 2. 실전! 스프링 부트와 활용 1 3. 실전! 스프링 부트와 활용 2 4. 실전! 스프링데이터 JPA 이 네 가지 강의 중 지금 제가 듣기 적합한게 있을까요? 물론 다 들을 거긴한대 프로젝트와 연관해서 수업을 듣고 싶어 질문남깁니다. 감사합니다.
-
미해결스프링 핵심 원리 - 고급편
createNextId() 메서드에서 항상 새로운 객체를 생성하는 이유가 궁금합니다.
항상 영한선생님 강의 정말 잘 보고 있습니다. 그런데 제가 지식이 부족하여 질문을 하나 올립니다. 5분30초 쯤에 만드는 createNextId()메서드에서 항상 레벨에 1을 더해서 새로운 TraceId를 반환하는데 처음에 만들어진 객체에 1을 계속 더해서 갖고가는 것이 아니라 계속 새로운 객체를 생성하는 이유가 궁금합니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
gradle 프로젝트 open 오류 발생
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 처음으로 mac 환경에서 프로젝트를 열려고 하는데 이 오류 때문에 진행을 못하고 있네요.. 프로젝트 파일을 다시 삭제하고 열어봐도 pc를 재부팅하고 다시 시작해도 똑같은 오류가 계속 발생합니다. 구글링에 검색해봐도 마땅한 해결방안이 나오지 않아 답답하네요ㅜㅜ 프로젝트 구성도 이상합니다.. 파일을 열때마다 "._java"와 같은 텍스트 파일이 생겨요
-
미해결
[전자정부] 한 화면에 폼 입력,저장 리스트화면을 구현하려고합니다
ajax를 쓰지않고 그냥 저장누르면 새로고침되면서 리스트에 추가되게 만들고있는데 java초보라 어렵네요오류코드를 보니 sql에서 에러난거같은데 아무리봐도 제대로 넣은거같습니다.DB에서 직접넣은 데이터는 리스트에 잘나옵니다... 근데 form에서 입력하면 아래 오류가 뜨네요..혹시 다른문제가 있을까요? 몇시간을 삽질하고있는건지 모르겠습니다 ㅠㅠ 에러코드 2022-03-20 22:09:15,731 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml] sql.xml <sqlMap namespace="CodeSpace"> <typeAlias alias="egovMap" type="egovframework.rte.psl.dataaccess.util.EgovMap"/> <typeAlias alias="codeVO" type="egovframework.example.sample.service.CodeVO"/> <insert id ="codeDAO.insertCodes"> INSERT INTO codes(codegid,codegnm,code,codenm,useat) VALUES(#codegid#,#codegnm#,#code#,#codenm#,#useat#) </insert> <select id="coodDAO.selectCodesList" resultClass="egovMap"> SELECT codegid,codegnm,code,codenm,useat FROM codes ORDER BY codegid ASC </select> </sqlMap> Controller @Controller public class CodeController { @Resource(name="codeService") private CodeService codeService; @RequestMapping(value="/codeList.do") public String selectCodesList(@ModelAttribute("Codevo") CodeVO vo, ModelMap model) throws Exception{ List<?> list = codeService.selectCodesList(vo); System.out.println("list ===>>" + list); model.addAttribute("resultlist",list); return "code/codeList"; } @RequestMapping(value="/codeWriteSave.do") public String insertCodes(@ModelAttribute("Codevo") CodeVO vo) throws Exception{ String result = codeService.insertCodes(vo); if (result == null) { System.out.println("저장성공"); } else { System.out.println("저장실패"); } return "foward:/codeList.do"; } } jsp <form:form action="/codeWriteSave.do" method="post" commandName="Codevo"> <label>그룹코드<form:input path="codegid"/> <label>그룹명<form:input path="codegnm"/> <label>코드<form:input path="code"/> <label>코드명<form:input path="codenm"/> <label>사용여부 <form:radiobutton path="useat" value="Y" label="Y"/> <form:radiobutton path="useat" value="N" label="N"/> </label> <button type="submit" onclick="fn_submit(); return false">저장</button> <button type="reset">취소</button> </form:form>
-
미해결스프링 부트 개념과 활용
안녕하십니까 기선님!!!!! webclient와 비동기관련 질문요청드립니다
안녕하십니까. 기선님처럼 되고싶은 1년차 주니어 개발자입니다. 제 개인 프로젝트 중에 현재는 동기방식 restTemplate으로 한번에 여러 군데에 요청을 던지는 기능이 구현되어 있는데 일부 요청이 오래 걸리는 것들이 있어서 스레드를 오래 물고있다는 판단을 하여 해당 기능을 nio 방식으로 전환하려고 합니다.(webclient)웹서버는 io/nio모두 지원하는 undertow를 사용하고 있으며, 스프링 mvc를 사용하고 있습니다. 본론으로 제가 해당 프로젝트에 한번 외부로의 요청에 각각 응답시간이 다른 여러곳에 일부는 오래걸리는 요청을 던지기 위해 비동기 처리로 수정하여 개발하려고 하는데, @Async나 CompletableFuture말고 webflux를 추가하여 mvc+webflux의 형태로 개발해도 괜찮을지 여쭤보고 싶습니다.(이게 개인 프로젝트가 아닌 실무에서도 가능할지) webflux와 mvc를 같이 쓰면 않좋다는 이전 토비님 말씀과 예전 구글링 글들도 있지만, 제 개인적인 생각에는 undertow는 예전 3.0 서블릿과는 다르게 io/nio를 함께 처리해주기 때문에 webflux + mvc 두개를 같이 써서 필요한 부분에 비동기 처리중에서도 pub/sub구조와 backpressure가 구현되어 있는 webflux-reacotr를 일부 도입해도 괜찮지 않을까하여 여러곳들을 전전하며 찾아보고 있었습니다.제 부족한 실력으로는 어깨너머로 알게된 지식으로 스스로 원하는 결론을 그냥 내린것 같은 생각이 강하게 들고, 마땅한 결론에 도달하지 않아서 여쭙고싶습니다!!!!!
-
미해결예제로 배우는 스프링 입문 (개정판)
unable: to acces jarfile target/*.jar
java -jar target/*.jar 이 실행되지않아 target파일로 들어간뒤에도 실행되지않아 전체이름을 다 쳤더니 실행되었습니다. 왜 *가 먹히지 않았던걸까요?
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
bindingFailure 의 용도
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]마지막 부분 10:45 시간에 질문 있습니다. qqqq를 넘기면 컨트롤러에서 타입에러로 자동으로 필드에러를 만들텐데요~ 이후에 어쩔수없이 item.getPrice() 가 null 이니깐 2번째 if 문안에서 addError 메서드로 저희가 선언한 필드에러를 추가하는 것 까지는 이해했습니다. 근데 저희가 선언한 필드에러는 bindingFailure 는 false로, 타입에러?(바인딩실패)는 아니다라고 지정했기 때문에 qqqq와 같은 문자를 넘기면 해당 필드에러는 무시될거라고 생각했습니다 그런데 저희가 추가한 필드에러의 디폴트 메세지가 출력되네요 "가격은 1,000~1,000,000 까지 허용합니다" (bindingFailure가 false이고, 발생한 에러는 타입에러라서 메시지가 표시 안될줄 알았습니다) 그냥 bindingFailure 에 상관없이 필드에러가 추가되었다면 타임리프가 다 처리해버리는 것 인가요 ?
-
미해결실전! 스프링 데이터 JPA
repository는 entity당 개별로 생성해줘야 하나요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의내용을 보면 Member와 Team 엔티티가 있고 JpaRepository를 상속받은 repository 또한 각각 만들어져 있습니다. 단순한 조회는 이미 정의되어있는 메소드로 가능하지만, 다른 테이블(엔티티)와 조인하는 경우에는 직접 정의해서 사용 가능하다는 내용의 강의였는데요 그럼 만약 4개 5개 복잡한 엔티티들과 연관된 쿼리들을 정의하고 싶다면 어느 repositroy에 정의를 해야할지 고민입니다. 여러 엔티티를 1개의 repository로 관리하고자 해도, 상속받을때 <>속에 특정 엔티티를 넣어줘야하는데, 그럼 어떤 엔티티를 넣어야할까요? 코딩에 정답은 없겠지만은 실무에서는 관례쩍으로 어떤식으로 구현을 하는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
@CookieValue 타입 컨버팅 관련
안녕하세요. 에러 해결이 어려워 질문을 남기게 되었습니다. 11:40까지 코드를 작성하고 localhost:8080으로 들어가면 Whitelabel Error Page가 뜨는데요. String 타입을 Long타입으로 바꾸는데 실패했다는거 같은데, 9:30에 말씀하신 컨버팅 기능에서 오류가 생긴걸까요? (경고 내용 텍스트: WARN 20100 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "test"]) 이 부분을 지우면 에러가 발생하지 않습니다. @CookieValue(name = "memberId", required = false) 두 컨트롤러의 코드는 다음과 같습니다. LoginController.java package hello.login.web.login;import hello.login.domain.login.LoginService;import hello.login.domain.member.Member;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.HttpServletResponse;@Slf4j@Controller@RequiredArgsConstructorpublic class LoginController { private final LoginService loginService; @GetMapping("/login") public String loginForm(@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.getLoginId())); response.addCookie(idCookie); return "redirect:/"; }} HomeController.java package hello.login.web;import hello.login.domain.member.Member;import hello.login.domain.member.MemberRepository;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;@Slf4j@RequiredArgsConstructor@Controllerpublic class HomeController { private final MemberRepository memberRepository; // @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 loginMember = memberRepository.findById(memberId); if (loginMember == null) { return "home"; } model.addAttribute("member", loginMember); return "loginHome"; }}
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
th:block 활용
th:block을 현업에서 많이 사용할까요? div두개를 큰 div나 다른 구역을 나누는 html 태그로 나누고 th:each돌리는것보다 렌더링시에 제거되는거 말고 얻을 수 있는 장점이 있을까요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
AOP 적용 질문
안녕하세요 AOP 중 궁금한점이 생겨 질문드립니다! [질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 질문을 쭉 봤는데 해당 내용이 없었습니다.3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)네[질문 내용] 이부분에서 찍어보면 다음과 같이 EnhancedBySpring~ 이부분이 스프링이 AOP 를 처리하기 위해 프록시로 복제된 객체로, AOP를 사용하게되면 사용된다는 내용으로 이해했습니다. 강의 자료에 보면, 다음과 같은 내용이 있는데, AOP와 관련된 코드들 (예제에서는 시간을 측정하는 코드, 시간측정하는 클래스를 주입하는 코드)을 제거 한 후에도 MemberController 에서 Service 클래스를 sout 으로 찍어볼 경우, 똑같이 EnhancedBySpring~ 하는 객체가 찍혀 나옵니다. 이 부분이 위에 AOP 적용 전 그림 에서 진짜 객체들만 사용한다는 위 그림과 과 맞지 않는데, 그렇다면 Spring 에서는 AOP 관련된 코드가 없어도 자동적으로 AOP를 위해 프록시 객체를 사용하도록 강제(?) 처리 되는건지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
webapp index.html 관련
webapp 폴더 추가 후index.html을 생성 후 서버를 기동시키고 접속하였을 때 Whitelabel Error Page가 발생 할 경우 입니다. Intellij에서 빈 모듈(spring-mvc) 생성 후 빈 모듈 안에서 새로운 모듈(servlet)을 생성하였을 경우 index.html에 접속이 되지 않는 것 같습니다. 실행 후 Tomcat의 로그에서도 WelcomePage 관련 로그가 출력되지 않았으며 http://localhost:8080과 http:localhost:8080/index.html에 접속할 수 없었습니다. 이후 프로젝트를 종료하고 빈 모듈(spring-mvc)이 아닌 빈 모듈 안에서 생성한 새로운 모듈(servlet)의 build.gradle을 통해 프로젝트를 새로 연 후 서버를 기동하면 WelcomePage 관련 로그가 출력 되며 http://localhost:8080에 문제없이 index.html에 접속할 수 있었습니다. 원인은 아직 잘 모르겠지만 멀티 모듈 또는 빈 모듈에서 새로운 모듈을 생성한 경우 Intellij에서 webapp을 찾지 못하는것 같습니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
app-plain.jar의 역할
안녕하세요, 수강 중에 궁금한 점이 있어 질문드립니다. :) 스프링 부트 프로젝트를 ./gradlew build 명령어로 빌드를 하고 나면, hello-plain.jar와 hello.jar의 두 개의 jar 파일이 생성됩니다. 구글링을 해 본 결과, 스프링 부트에서 빌드하면 Plain Archive도 함께 만들어지며 이를 방지하고 싶으면 build.gradle에 별도의 설정을 하면 되는 것, 그리고 Plain Archive가 무엇인지도 알게 되었습니다. 그런데 Plain Archive는 어디에 쓰려고 만들어진 건지, 목적이 무엇인지를 모르겠습니다. 의존성이 포함되지 않은 파일이 왜 필요한 건가요?
-
미해결스프링부트 시큐리티 & JWT 강의
BycryptPasswordEncoder 주입시 순화참조 문제
저는 mac m1버전 인텔리제이 spring boot 2.64 버전 java8 로 하고있습니다. 저도 13:41 BycryptPasswordEncoder를 주입하니 SecurityConfig와 순환참조가 걸려 진행이 되지 않았습니다. 그래서 PrincipalOauth2UserService에서 private BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); 이렇게 생성하여서 진행하였습니다. 혹시 강의를 보시는 다른 분들을 위해 참고 코드를 남겼습니다.
-
미해결실전! 스프링 데이터 JPA
entitygraph관련 궁금증
안녕하세요!! 만들어주신 로드맵을 열심히 공부하고 있는 학생입니다! @entityGraph와 관련하여 추가적인 궁금증이 있어 질문드립니다. 먼저 해당 내용에 대해 repository 내에서 findAll() 메소드를 상속받아, 여기에 fetch join을 부여해 주는 것으로 이해했는데요 혹시 이렇게 상속받으면 findAll 메소드 자체가 바로 fetch join을 진행하는것이 아닐까 해서요 예를 들어 A 위치에서는 member의 변수만을 필요로 하고, B 위치에서는 team까지 가져오려 하면 A에서는 LAZY로 유지되는 것이 좋고, B에서는 바로 fetch join하는 것이 나을 거라 생각하는데 위의 방식이면 둘 다 바로 fetch join을 진행할 것 같다고 생각하는데 이게 맞을까요?? 혹시 맞다면 어떤 식으로 고치는것이 더 최적화될지 궁금합니다.... --- 추가로 혹시 @entityGraph는 무조건 left outer join에서만 적용되는 것일까요??
-
미해결스프링 핵심 원리 - 기본편
자신의 클래스에서 자신을 static으로 선언하는 부분 재 질문입니다.
안녕하세요. 앞전에 질문드렸던 내용이 계속 이해되지 않아서 정리 후 재 질문 남깁니다. 먼저 제 생각은 이렇습니다. 애플리케이션이 실행되는 시점에 .java 파일은 .class파일로 바뀌어서 사용되고, static 영역에 static 변수들이 세팅됩니다. 이 두개의 경우 중 적어도 한 경우에 SingletonService 클래스의 private static final SingletonService instance = new SingletonService(); 이 코드가 실행될 수 밖에 없다고 생각합니다. 위의 그림은 해당 코드가 실행될 때를 나타내본 것입니다. 해당 그림의 인스턴스에 들어오는 값들을 보면 static 멤버변수, 메소드, 생성자 등 모든 클래스의 구성요소들이 들어오게 됩니다. 이 중 저는 static 멤버변수 부분이 의아합니다. 이에 관련되어 두가지 질문사항이 있습니다. 1. static 영역에는 50의 참조값을 가지는 instance 객체가 생성 되었습니다. 하지만 그 인스턴스 실제 값을 보면 private static final SingletonService instance = new SingletonService(); 이 코드가 들어가 있습니다. 이때 저는 `이코드가 무한 반복된다.`, 또는 `이미 instance라는 변수가 static 영역에 선언되어 있기 때문에 에러가 난다.` 두가지 중 하나의 일이 발생할 것으로 추정해 말이 안되는 코드 아닌가라는 의문이 생깁니다. 그럼에도 불구하고 잘 작동하는 것을 보니 제가 생각한 부분이 틀렸고, 모르는 부분이 존재하는 것으로 생각됩니다. 실제로 이 부분이 어떻게 동작하며 실행되는지 자세히 알고 싶습니다. 2. 두번째 질문은 private static final SingletonService instance = new SingletonService(); 이라는 줄이 실행될 때 실행 시점에 관련한 의문입니다. 이 코드가 실행될 시점은 .class 파일을 만들려고 .java 파일을 읽거나 instance 변수를 static 영역에 등록하려고 해당 코드를 실행시키거나 하는 두 시점 중 하나라고 생각이 듭니다. 두 시점 중 해당 코드가 실행되는 순간을 보면, 첫 줄에 멤버변수가 작성되어 있기 때문에 클래스의 뒷 부분인 메소드, 생성자는 아직 존재하지 않는다고 생각합니다. 그렇다면 인스턴스에 값을 채워서 참조값을 올릴때, 인스턴스에 넣을 값이 멤버변수 빼고는 존재하지 않는데 어떻게 코드가 동작하고 있는지에 관련해 의문이 남습니다. 이부분도 제가 모르는 것이 있거나 잘못 알고 있는 부분이 있는 것 같습니다. 관련된 자세한 설명과 동작방식을 알고 싶습니다. 고맙습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
왜 UUID로 find하지 않고 SESSION_COOKIE_NAME으로 find 하나요?
왜 UUID로 find하지 않고 SESSION_COOKIE_NAME으로 find 하나요? 그렇게하면 보안상 사용한다던 UUID가 의미가 없지않나요? 해킹하는 사람 입장에서는 쿠키 이름만 알아도 정보를 가져올수있으니까요
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
{itemId} 매핑원리 질문입니다.
@PostMapping("/{itemId}/edit")public String edit(@PathVariable long itemId,@ModelAttribute Item updateParam) { itemRepository.update(itemId,updateParam); return "redirect:/basic/items/{itemId}"; } 위 코드의 메서드가 실행될 때, {itemId} 에 @PathVariable long itemId 가 매핑되는데 매핑되는 원리가 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
세션 형태 관련 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 직접 만든 세션에서는 세션id로 UUID를 이용해서 랜덤한 값을 만들어서 세션 보관을 하고 이 세션id를 쿠키의 값으로 전달했는데 HttpSession의 경우는 쿠키가 다음과 같다고 하셨습니다. JSESSIONID=5B78E23B513F50164D6FDD8C97B0AD05 그럼 5B78E23B513F50164D6FDD8C97B0AD05 가 톰캣이 만든 세션id인가요? 다른 글에서 세션들을 보관하는 세션 저장소가 하나 더 있다고 봤는데 위에서 랜덤값인 세션 id가 key 이고 value가 Map(편의상 Map2) 인 Map형태의 세션 저장소가 있고 value인 Map2 또한 세션 저장소로 랜덤한 세션id 로 인증된 특정한 사용자만 사용하는건가요? Map2에서 저희가 session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); 등록한게 있는거 같구요. 만약 제가 생각한게 맞다면 굳이 왜 이런 형태를 이용하나요? 직접 만든 Session 처럼 처음부터 랜덤한 값을 세션 키로 이용하면 Map 하나로 해결될것 같아서요.