배운 내용 정리
[ ch. 02 Spring MVC ]
23. 쿠키(Cookie)란
> 쿠키를 이용해서 로그인 ID를 기억 기능 만들기 실습












> 쿠키란? (Cookie)
: 이름과 값을 한 쌍으로 저장하는 작은 정보.
: 기본적으로 아스키 문자만 저장할 수 있음.
: 세미콜론, 공백도 저장할 수 없음.
: 한글은 URL 인코딩을 해 주어야 함.
: 서버에서 생성 후 전송되고, 브라우저에 저장됨.
: 쿠키를 저장하는 공간이 브라우저라는 것이 중요함.
: 유효기간 이후 자동으로 삭제됨.
: 서버에 요청할 때 domain은 일치하는 경우에만,
path는 일치하는 경우뿐만 아니라 그 하위경로까지 쿠키가 감.
: 쿠키는 여러 개 있을 수 있음.
: 사용자가 어떤 사이트에서 어떤 경로에 방문하면,
쿠키 중에 해당 사이트 경로에 해당하는 것은 자동으로 쿠키가 감.
> 쿠키의 작동 과정

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
1. 클라이언트가 서버에게 요청함.
2. 서버가 코드를 수행해서 쿠키가 만들어짐.
3. 쿠키를 응답에 담아서 보냄. → 응답헤더에 정보가 들어감.
5. 응답이 클라이언트에게 전달되면서 쿠키도 같이 전달됨.
6. 서버가 보내준 쿠키가 브라우저에 저장됨.
7. 클라이언트가 쿠키에 일치하는 서버에 요청을 보내면, 자동으로 쿠키와 요청이 같이 감.
→ 요청을 보내면, 요청헤더에 쿠키가 따라가게 되어 있음.
+ 예시
: 서버를 도서관이라고 생각하면 쉬움.
: 도서관에 처음 가면 id카드를 발급해 줌.
: 그 다음부터 id카드로 출입할 수 있음.
: 보유한 신분증은 여러 개지만, 도서관에서 발급해 준 id카드로만 출입가능함.
+ 정보를 브라우저에 저장하는 것이기 때문에
사용자가 쿠키를 삭제할 수 있고, 서버가 발급해 주는 쿠키를 거부할 수도 있음.
> 쿠키 = 클라이언트 식별기술
: 쿠키는 클라이언트를 구별하기 위한 기술.
: 서버는 누구한테 요청이 오든 응답만 해 주면 되지만,
경우에 따라서는 클라이언트를 구별해야 될 때가 있음.
→ 서버가 응답할 때 클라이언트에게 쿠키를 만들어 주는 것임.
: 쿠키가 브라우저에 저장됐다가 다시 서버에 요청할 때,
이 서버가 발급한 쿠키(id카드)가 자동으로 따라가게 되는 것임.
→ 서버에서는 자신이 발급해 준 id카드기 때문에 같은 클라이언트라는 것을 구별함.
> 쿠키의 생성
: 요청이 오면 서버가 아래의 코드를 실행해서 쿠키를 만듦.
Cookie cookie = new Cookie "id", "kkuno";
: 쿠키 생성
: 이름이 id, 값이 kkuno인 쿠키를 만든 것임.
cookie.setMaxAge(60*60*24);
: 유효시간 설정(초)
: 24시간이라는 뜻.
response.addCookie(cookie);
: 응답에 쿠키 추가
: Set-Cookie 헤더를 추가함.

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
+ 이 응답이 가면 브라우저에 쿠키가 만들어지는 것임.
> 유효기간
: 상대시간과 절대시간 중에 하나만 작성해도 됨.
: 브라우저마다 사용하는 태그가 달라서 둘 다 작성하는 것.
: HTTP쪽에 상대시간과 절대시간을 쓰는 경우가 있음.
> Max-Age (상대시간)
: 생성한 후로부터 68400초 후에 쿠키가 자동 폐기된다는 것.
> Expires (절대시간)
: 지정된 시간에 쿠키가 자동 폐기됨.
> 쿠키의 삭제와 변경
> 삭제
Cookie cookie = new Cookie ("id", "");
: 변경할 쿠키와 같은 이름의 쿠키를 생성함.
: ("이름", "값")
: 값은 넣지 않아도 됨.
cookie.setMaxAge(0);
: 브라우저에 똑같은 이름의 쿠키가 있으면 새로 받은 내용으로 갱신함.
→ 유효기간을 0을 설정하면 삭제가 됨.
response. addCookie(cookie);
: 응답에 쿠키 추가
> 변경
cookie.setValue(URLEncoder.encode("꾸노"));
: 값의 변경
: 꺼낼 때는 디코딩을 해야 함.
cookie.setDomain("www.fastcampus.co.kr");
: 도메인의 변경
cookie.setPath("/ch2");
: 경로의 변경
cookie.setMaxAge(60*60*24*7)
: 유효기간의 변경
+ 도메인과 경로를 설정하지 않으면, 서버의 응답으로 판단해서 결정됨.
> 쿠키 읽어 오기
Cookie[ ] cookie = request.getCookies( );
: 쿠키 읽기
: 쿠키가 여러 개일 수 있으니가 배열로 되어 있음.
for(Cookie cookie :cookies) {
String name = cookie.getName( );
String name = cookie.getValue( );
System.out.printf("[cookie]name=%s, value=%s%n", name, value);
}
: 브라우저가 자신이 가지고 있는 쿠키를 보내줌.
: 경로를 확인해서 일치하는 쿠키를 찾아서 쿠키 헤더에 넣어서 보내줌.
: 여기에서는 쿠키가 두 개 혹은 그 이상일 수도 있어서 배열로 반환하게 되어 있음.
+ 쿠키가 없으면 null이기 때문에 null 체크를 해 주어야 함.
> 쿠키 실습


+ 추가 설명
: 쿠키를 브라우저에서 직접 만들 수도 있음.
: 쿠키를 만들고 새로고침한 것.
: 쿠키 값을 읽어서 보여준 것임.

+ 추가 설명
: loginForm에서 checkbox를 확인해보면 value가 없음.
: 기본값은 on이기 때문에 String으로 되어 있으면 on으로 나옴.

+ 추가 설명
: checkbox일 때 매개변수를 boolean으로 설정하면,
스프링이 알아서 true혹은 false로 변경해 줌.
: loginForm에서 checkbox에 값을 주든 안 주든 상관없음.
: 값을 주려면 value로 주면 됨.





24. 세션(Session) - 이론
> 세선이란?
: 쿠키를 이용해서 서로 관련된 요청과 응답을 하나로 묶은 것.
: 원래 요청은 독립적인데, 이러한 요청을 하나로 묶어준 것임.
→ 독립적이다 = 요청간에 서로 관계가 없다
: 브라우저마다 개별 저장소(세션 객체)를 서버에서 제공함.
→ 세션이 쿠키를 이용하기 때문임.
: 쿠키는 브라우저에 저장되기 때문에,
브라우저마다 개별 저장소가 만들어지는 것임.
: 세션 객체는 서버에 저장됨.

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
1. 브라우저가 요청을 보냄
2. 서버가 응답에 세션ID를 쿠키에 저장해서 줌.
3. 다음 요청부터 요청에 쿠키가 자동으로 따라감.
→ 두 번째 요청부터 같은 세션임.
: 첫 번째 요청을 제외하고는 서버한테 요청의 세션ID가 계속 쿠키로 감.
: 쿠키 때문에 요청을 구별할 수 있게 됨.
: 요청에는 같은 세션ID라는 공통점이 생김.
: 같은 세션ID를 가진 요청은 같은 세션에 포함됨. → 그룹화
: 같은 세션에 포함되어 있는 동안 세션 저장소(객체)를 사용할 수 있음.
> 세션을 끝내는 방법
1. 수동 종료
: Invalidate 메서드
: 로그아웃을 누를 때 세션이 끝남.
2. 자동 종료
: Time out
: 일정 시간이 지나면 저절로 세션이 끝남.
+ 세션이 끝나고 나면, 새로운 세션ID가 발급됨.
→ 또 다른 세션이 시작됨.
+ 재정리
: 원래 요청과 응답은 독립적임.
: 쿠키를 이용해서 세션ID를 브라우저에게 보내줌.
: 그 이후의 요청에는 같은 세션ID가 요청에 포함되게 함.
: 이러한 요청을 하나로 묶어 주는 것이 세션임.
: 로그인부터 로그아웃까지가 하나의 세션이라고 생각하면 쉬움.
> 세션의 생성 과정
1. 브라우저가 요청함.
2. 서버가 무조건 세션 객체(저장소)를 만듦.
→ 세션 객체마다 세션ID를 가지고 있음.
→ 서버는 Set-Cookie라는 응답헤더를 이용해서 세션ID를 줌.
3. 저장소를 사용할 수 있게 세션ID가 담긴 쿠키를 만들어서 응답으로 보냄.
4. 브라우저에 쿠키가 저장됨.
5. 그 다음부터 요청을 보낼 때 쿠키가 자동으로 따라감.
6. 서버가 요청에 포함된 세션ID로 같은 브라우저에서 온 요청인지 아닌지 알 수 있음.
→ 세션ID가 일치하는 세션 저장소를 사용할 수 있음.
> 세션 객체 얻기

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
: 쿠키는 브라우저마다 저장됨.
: 서로 다른 PC거나 같은 PC에 있더라도 서로 다른 브라우저인 경우,
다른 세션ID를 서버로부터 받아서 저장하고 있음.
: 그 다음부터 요청하면, 브라우저에 저장된 세션ID가 자동으로 서버에 전송됨.
→ 요청을 보낸 클라이언트를 구별할 수 있음.
: 컨트롤러에서 세션 저장소를 사용하고 싶을 때는 request.getSession을 하면 됨.
→ 요청에 있는 세션ID를 보고 일치하는 세션 객체를 찾음.
: 세션 객체에 setAttribute를 하면, Key-Value 형태로 저장하여 사용할 수 있음.
: request는 요청 정보가 다 들어 있음.
: 세션ID는 요청헤더에 있음.
→ request 객체로부터 세션 객체를 얻어오는 메서드가 들어 있는 것임.
: 세션 객체 중에서 일치하는 것을 반환함.
: 반환하면 세션 참조 변수가 session 객체를 반환함.
: setAttribute를 이용하면 저장할 수 있음.
: 읽어올 때는 getAttribute를 사용함.
> 세션과 관련된 메서드

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
long getLastAccessedTime( )
: 최근 요청 → 제일 마지막 요청
boolean isNew( )
: getSession으로 세션을 얻어 왔는데,
세션이 종료되어 있으면, isNew가 true인 것임.
: 세션ID로 기존의 세션ID와 같은지 다른지 확인해도 됨.
void invalidate( )
: 세션 종료. 즉시 종료.
: 로그아웃할 때 클릭하면 이 메서드를 호출하면 됨.
> 세션의 종료
1. 수동 종료
HttpSession session = request.getSession( );
session.invalidate( );
: 세션 즉시 종료
session.setMaxInactiveInterval(30*60);
: 예약 종료
: 초 단위
: 30*60 → 30분 후 종료됨.
2. 자동 종료 - web.xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
: 자동 종료되는 설정은 꼭 넣어 주는 것이 좋음.
: 분 단위

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
1. 종료되면 새로운 세션ID를 줌.
2. 그 다음부터 요청에 새로운 세션ID를 사용함.
invalidate 메서드를 호출해도 마찬가지.
3. 다음 응답부터는 새로운 세션ID가 발급됨.
→ 기존에 사용하던 세션 저장소는 ID가 다르기 때문에 더 이상 사용할 수 없음.
: 새로운 세션ID가 발급된다는 것은 새로운 세션 객체가 만들어진다는 뜻임.
: 세션 저장소를 관리하는 스탠다드 매니저가 있음.
: 사용자에게 요청이 오면, 스탠다드 매니저가 세션 객체를 무조건 새로 만들고,
세션 객체의 ID를 쿠키로 반환함.
: 세션이 끝나면 스탠다드 매니저가 세션 객체를 자동으로 제거해 줌.
: 세션 저장소를 사용하면 프로그래밍 하기 편리함.
: 하지만 부담이 많이 가기 때문에 최소한의 데이터만 저장해야 함.
> 쿠키 vs 세션
| 쿠키 (Cookie) | 세션 (HttpSession) |
| 브라우저에 저장 | 서버에 저장 |
| 서버 부담 X | 서버 부담 O |
| 보안에 불리 | 보안에 유리 |
| 서버 다중화에 유리 | 서버 다중화에 불리 |
> 보안
: 서버는 보안이 철저함.
: 보통 일반 개인 PC는 다른 사람이 쿠키 내용을 볼 수도 있고,
삭제할 수도 있기 때문에 서버에 비하면 보안에 불리함.
→ 쿠키의 값을 저장할 때는 주로 암호화를 함.
> 서버 다중화
: 대부분은 서버가 한 대임.
> 작은 사이트의 경우
: 세션 객체가 하나이기 때문에, 데이터를 저장해도 아무 문제가 없음.
> 큰 사이트의 경우
: 기본으로 앞에 서버 한 대가 있고, 뒤에 여러 대의 서버를 둬서 다중화함.
: 서버에 부담도 없고, 서버 다중화에 유리하기 때문에 쿠키를 많이 이용함.
: 요청이 오면, 요청을 앞에 서버가 받아서 로드 밸런싱을 해 줌.
: 여러 대의 서버로 부하를 분산시키려고 서버 다중화를 함.
: 한 쪽의 변경을 다른 쪽에 반영해 주는 세션 객체 간에 동기화가 필요함.
: 이러한 서버 다중화는 세션 객체를 이용하는 것이 불리함.
→ 데이터를 여러 대의 서버에 동기화할 필요가 없기 때문에 쿠키에 저장하는 것이 더 유리함.
→ 쿠키를 암호화해서 많이 사용함.
> 세션 실습

+ 추가 설명
: 서버가 세션ID를 응답으로 보내줌.
: 이를 브라우저가 쿠키로 저장함.
: 헤더에 의해서 쿠키가 만들어짐.

+ 추가 설명
: 응답이 온 것을 확인할 수 있음.
Set-Cookie 헤더
: JSESSIONID와 값을 쿠키로 만들라는 것.

+ 첫 번째 요청에는 쿠키가 없음.

+ 추가 설명
: 두 번째 요청에는 쿠키가 따라감.
: 브라우저에 저장된 JSESSIONID가 요청에 계속 포함되어 있음.
: 서버는 JSESSIONID를 보고 서로 다른 요청이지만,
같은 브라우저로부터 온 요청이라는 것을 알 수 있음.
: 쿠키를 허용하지 않는 브라우저에는 모든 URL에 JSESSIONID를 붙여줌.
→ 서버에 요청할 때 세션ID가 같이 URL과 전송되도록 해야 함.
: 요청한 URL을 통해서 세션ID를 얻을 수 있기 때문에,
브라우저가 쿠키를 허용하지 않아도 괜찮음.
: 쿠키를 허용하지 않는 브라우저인 경우
loginForm에서 url 태그가 자동으로 세션ID를 붙여주는 일을 함.
→ "<c:url value="/login/login"/>"
: 쿠키를 허용하지 않는 브라우저도 있기 때문에
view를 작성할 때 링크에는 꼭 url 태그를 이용해서 작성해야 함.


+ 추가 설명
: 첫 번째 요청에는 세션ID를 두 가지 방법으로 보내줌.
→ 브라우저가 쿠키를 허용하지 않을 수 있기 때문에.
: 서버가 URL 뒤에 JSESSIONID를 붙여주고,
응답헤더를 이용해서도 JSESSIONID를 보내줌.
: 브라우저가 쿠키를 허용하지 않는 경우
→ Set-Cookie는 아무 효과가 없음.
→ URL 뒤에 오는 세션ID로 서버가 브라우저를 구별할 수 있음.

+ 쿠키가 허용된 경우에는 두 번째 요청부터 URL 뒤에 세션ID가 붙지 않음.

+ 요청에 쿠키가 왔으니까 굳이 붙일 필요가 없는 것임.
25 - 26. 세션(Session) - 실습 (1) & (2)
+ 설계 (그림 그리기)
: 형식적이기보다 나의 개발에 도움이 되게끔,
다른 사람과 소통할 수 있기 위해서 그림을 그리는 것임.
> 미로그인, 로그인 게시판 이용 실습











+ 클릭 순서
Home > Board > Login > Board > Home > Logout > Board > Login > Board로 오고 중단.
> session = "true" or session = "false"
: 세션이 시작하는 여부를 true/false로 구분하는 것임.
: session = true 가 디폴트.

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
: 로그인할 때 세션 객체에 아이디가 저장되고, 저장된 상태가 이어짐.
→ 세션은 서버에 부담이 많이 가기 때문에 세션 유지기간이 가능한 짧아야 함.
: Home과 Login 화면에서는 세션이 필요없음.
→ session = false 를 주는 것이 좋음.
> 세션이 있을 경우
: true/false 모두 세션을 만들지 않음.
> 세션이 없을 경우
: session = true 세션을 생성함.
: session = false 새로 세션을 생성하지 않음.
> session = false
: 세션이 필요없는 JSP화면에 주면, 세션을 늦게 시작할 수 있음.
: 기존 세션에 영향을 미치는 것이 아님.
→ 세션이 시작한 뒤에 있는 경우 세션이 끊어지는 것이 아님.
> session = "false" 실습

+ 참고
: session = "false" 인 경우
sessionScope과 pageContext.session은 사용 불가.
: sessionScope.id
→ pageContext.request.getSession(false).getAttribute("id")로 변경.
→ STS에서 에러라고 표시해도 무시하면 됨.



+ 추가 설명
: 세션을 만드는 이유는 사용자가 로그인한 다음,
여러 가지 사용자 정보를 세션 객체에 담아두기 위해서임.
: 로그인을 하지 않은 상태에서는
굳이 세션 객체가 필요하지 않기 때문에 false로 설정해야 함.
> @CookieValue

: id라는 이름을 가진 쿠키 값을 String cookieId에 넘겨줌.
: 내부에서 읽어올 수 있지만 CookieValue 애너테이션을 이용할 수도 있음.
ex. @CookieValue("JSESSIONID") String sessionId
27. 예외처리(1) - 실습










+ 추가 설명
: 처음에 URL 주소창에 직접 검색함.
: 첫 번째라서 앞에 페이지가 없는 것임. (null)


+ 추가 설명
: catch 블럭처럼 계속 추가 가능.
: /ex를 호출하면 Exception이 발생해서 catcher 메서드가 예외를 처리해 줌.
: /ex2를 호출하면 NullPointerException이 발생해서
catcher2 메서드가 예외를 처리해 줌.
→ 예외 종류가 일치하기 때문에.
: Exception은 모든 예외 중에서 최고 조상이기 때문에,
NullPointerException을 제외한 나머지는 catcher 메서드에서 처리함.
: 예외 정보가 매개변수로 메서드한테 자동으로 넘어감.
: 이를 모델에 담아서 view로 전달하는 것임.










+ 추가 설명
: 예외 처리는 더 가까이 있는 메서드가 처리하게 되어 있음.
: 공통적으로 처리할 예외는 별도의 클래스에 메서드를 만들어 놓고,
개별적으로 예외를 처리하고 싶을 때는 해당 컨트롤러 안에
추가적으로 ExceptionHandler 애너테이션이 붙은 메서드를 만들면 됨.
28. 예외처리(2) - 이론
> 실습


+ 추가 설명
: 톰캣이 보여주는 것.
: 예외 처리가 안 되니까 그 예외가 톰캣까지 전달되어서
톰캣이 기본적인 페이지를 보여주는 것임.
: 응답헤더를 보면 상태 코드가 500인 것을 확인할 수 있음.
: 사용자가 이 정보를 보면 이해를 못 할 수도 있고,
해커가 서버를 공격하는데 악용할 수도 있음.
→ 톰캣이 보여주는 기본 페이지 대신 사용자 친화적인 페이지로 바꾸는 것이 좋음.
> @ExceptionHandler
: 예외 처리를 위한 메서드를 작성하고 붙이는 애너테이션.

: @ExceptionHandler( 처리할 예외 작성 )
: 보통은 하나의 예외를 적음.
: 하나의 메서드로 여러 예외를 처리할 때는 배열로 적어주면 됨.
: Model에 예외를 저장해서 전달함.
: 발생한 예외 객체(ex)를 error.jsp에 전달한 것.
: jsp page에 isErrorPage 속성을 true로 주면,
m.addAttribute("ex", ex); 로 저장하지 않아도 됨.
→ <%@page isErrorPage="true"%>
: 발생한 예외를 기본 객체 exception을 이용해서 쓸 수 있음.
+ 추가 설명
: catcher 메서드에 있는 Model과 main 메서드에 있는 Model은 서로 다른 객체임.
→ 컨트롤러 메서드가 전달한 msg가 예외를 처리하는 catcher 메서드로 전달되는지 확인해 보면 됨.
→ Model 객체에 저장된 msg가 없어서 빈 괄호만 찍힌 것을 확인할 수 있음.
: 컨트롤러 메서드에서 msg를 저장해도, 예외 처리를 하는 메서드에 전달되는 것이 아님.
+ 서로 같은 객체였다면, 컨트롤러에서 예외가 발생하기 전에, 저장한 데이터가 catcher 메서드로 전달됨.
→ main 메서드에서 저장한 데이터 찍혔을 것임.
@ControllerAdvice
: 전역 예외 처리 클래스를 작성할 때 사용함.
: 모든 컨트롤러에서 발생하는 예외를 처리할 수 있는 클래스를 만들 수 있음.
: 이외에도 여러 용법으로 사용됨.
@ResponseStatus
: 응답 메시지의 상태 코드를 변경할 때 사용함.
: 다른 용법도 있지만, 일단 두 가지만 기억할 것.
1. 예외 처리 메서드 앞에 사용함.
: error.jsp를 보여주는데, 상태 코드가 200(요청 처리 성공)이라고 해 보자.
: 에러가 발생한 것을 처리해서 보여주면서 요청이 성공적으로 처리되었다고 나오면 안됨.
→ 상태 코드를 200번대가 아닌 400번대, 500번대로 바꿔주어야 함.
→ 적절한 것으로 바꾸면 됨.
→ 예외 디폴트 : 500
: METHOD_NOT_ALLOWED → 200번을 405번으로 바꾸려고 하는 것임.
2. 사용자 정의 예외 클래스를 만들 때 사용함.
: 상태 코드를 바꾸고 싶을 때 사용함.
: 디폴트인 500에서 사용자가 지정한 상태 코드로 바뀜.
+ 재정리
1. 요청 처리가 성공하지 않았을 때,
상태 코드 200을 에러 코드인 400번대나 500번 대로 바꿀 때 사용함.
2. 사용자 정의 예외 클래스를 만들었을 때,
상태 코드의 디폴트인 500이 아닌 다른 상태 코드로 바꾸고 싶을 때 사용함.
> @ResponseStatus 실습

+ 추가 설명
: 브라우저에서 예외가 잘 처리된 것을 확인할 수 있음.
: 그러나 잘 처리됐어도 예외가 발생한 것이기 때문에
응답 코드가 200번이 나와서는 안 됨.
: 요청이 처리되다가 에러가 발생했기 때문에 500번대 혹은 400번대가 나와야 함.
→ ResponseStatus 애너테이션을 이용해서 변경해 주어야 함.


+ 추가 설명
: error.jsp를 호출했을 때, error.jsp가 성공적으로 보여졌기 때문에,
상태 코드가 200이 나오는 것임.
: 원래 요청한 내용이 처리가 되지 않았기 때문에,
ResponseStatus 애너테이션을 이용해서 상태 코드를 500으로 변경해 주어야 함.












> <error-page> - web.xml
: 상태 코드별로 뷰를 지정해 줄 수 있음.
> SimpleMappingExceptionResolver

: 예외 종류별로 뷰를 지정할 수도 있음.
: 예외 종류(MyException)와 에러 뷰(페이지 | error400)를 연결해 주는 것임.
: 예외 처리 메서드가 특별히 할 일이 없어서 뷰만 반환할 경우
예외 처리 메서드를 만들지 않고 지정해 주는 것임.
: view-controller와 비슷함.
→ 메서드가 특별히 하는 일이 없어서 뷰만 반환할 때,
view-controller 태그를 이용해서 등록할 수 있는 것과 비슷함.
+ statusCodes
: 뷰에 대한 상태 코드 어떤 것으로 할지 정해줄 수 있음.


+ 추가 설명
: error400.jsp의 상태 코드를 400으로 설정했는데, 상태 코드가 500이 나옴.
→ jsp의 특징 때문임.
: error400.jsp에서 isErrorPage가 "true"로 설정되어 있으면,
상태 코드를 강제로 500으로바꾸게 되어 있음.


> ExceptionResolver

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
1. 클라이언트가 요청을 보내면 DispatcherServlet이 받음.
2. 해당 Controller에게 넘겨줌.
3. MyException 예외가 발생함.
(Controller 메서드 내에서 try-catch로 처리할 수도 있음.)
4. 예외가 자신을 호출한 쪽으로 전달하고, main 메서드는 죽음.

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
5. 예외가 DispatcherServlet으로 감.
6. DispatcherServlet은 예외를 처리하기 위해
handlerExceptionResolvers로 등록되어 있는 것을 순서대로 확인함.
→ DispatcherServlet에는 예외 처리 기본 전략이 3개가 등록되어 있음.
① ExceptionHandlerExceptionResolver

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
6-1. 먼저 ①에서 처리할 수 있는지 확인함.
발생한 예외가 NullPointerException이라고 하면,
이 예외를 처리할 수 있는 ExceptionHandler가 있는지 찾음.
같은 컨트롤러, ControllerAdvice 등록되어 있는 것을 찾음.
처리할 수 있다면, 해당 메서드(catcher2)가 처리하고
error 뷰를 DispatcherServlet에 주면, 응답을 하게 됨.
② ResponseStatusExceptionResolver
③ DefaultHandlerExceptionResolver

출처: [스프링의 정석 - 기초편] 남궁성과 끝까지 간다.
6-2. 찾지 못한 경우 ②로 넘어감.
ResponseStatus 애너테이션을 찾음.
②는 MyException이 발생하면, 상태 코드를 500에서 400으로 바꿔주는 일을 함.
ResponseStatus 애너테이션이 붙은 것을 처리해 주는 일을 해 주는 것임.
400번에 해당하는 뷰 → web.xml
web.xml에서 400 상태 코드에 해당하는 view가 있는지 확인함.
있는 경우 error400.jsp가 클라이언트한테 응답함.
6-3 없는 경우 마지막 ③으로 감.
스프링에 정의된 예외 상태 코드를 ③이 적절하게 400번대나 500번대로 바꿔주는 일을 함.
→ RequestParam 애너테이션에서 400번대와 500번대에 발생함.
> Dispatcher.properties

+ 추가 설명
: DispatcherServlet이 사용하는 기본 전략을 적어 놓은 곳임.
: 수정하기 위한 것이 아니라 스프링에서 만들어 놓은 것임.
후기
끝이 없는 것 같아 보였는데, 마지막 날도 끝나간다.
수강률 100%를 달성하지 못하고 끝낸 게 너무 아쉽고 한심하고..
마지막에 들은 강의는 시간에 쫓겨 급하게 들어서 기회가 된다면 다시 들어야 할 것 같다ㅎㅎ..
짧고 길었던 8주가 지나고 교육 기간도 끝이 났다.
앞으로는 어떤 방향으로 공부할지 막막하기도 하고..
내가 진정 웹 개발자로 살아갈 수 있을지 막막하기도 하다...
그치만 어떻게든 해내는 나를 믿으면서 열심히 해봐야지!
8주 동안 고생 많았고,
2024년에는 더 많이 성장할 수 있도록 노력하자ㅏ
앞으로도 화이팅!
'패캠 학습일지' 카테고리의 다른 글
| [패스트캠퍼스] 자바 강의 추가 학습 일지 (0) | 2024.03.08 |
|---|---|
| [패스트캠퍼스] Spring 강의 7주차 학습일지 (0) | 2023.12.26 |
| [패스트캠퍼스] Spring 강의 6주차 학습일지 (0) | 2023.12.20 |
| [패스트캠퍼스] Spring 강의 5주차 학습일지 (0) | 2023.12.12 |
| [패스트캠퍼스] 자바 강의 4주차 학습일지 (0) | 2023.12.05 |