Java EE 정리 35
16 Apr 2019
Reading time ~5 minutes
Java EE 정리 35 - Session, filter
Session
-
HttpSession 사용
- 값 설정, 값 얻기, 생존 시간 설정 가능
public String method명(HttpSession session) {
session.setAttribute("이름",값);
session.setMaxInactiveInterval(초);
session.getAttribute("이름");
...
}
-
@SessionAttributes() 사용(권장)
- 세션에 값 넣기만 가능
- Model의 addAttribute할 때 “이름”이 SessionAttribute의 이름과 같다면 requestScope, sessionScope에 모두 설정이되어 JSP에서 사용할 수 있다.
// import와 class 사이에 설정
@SessionAttributes(이름) // 값 설정만 가능
@Controller
public class 클래스명 {
// 설정된 Session은 Controller 내 어디서든 사용 가능
@RequestMapping(value="/...", method=GET)
public String method명(@RequestParam(...) 타입 매개변수명, Model m) {
m.addAttribute("이름",값);
// SessionAttribute이름과 같다면 세션에 값이 저장된다!
// JSP에서는 requestScope와 sessionScope로 둘 다 사용가능
// ${ requestScope }, ${ sessionScope }
...
}
...
- Session에 여러 이름을 사용할 때는 배열을 사용
@SessionAttributes({"이름","이름","이름"})
HttpSession 사용
- session/~.do로 이동하게되면 현재 URL이 /session/을 가진 상태로 이동하게 됨, 다시 같은 메뉴를 선택하여 이동하면 /session/session/~.do로 이동해서 404에러가 발생
- 홈으로 눌렀을 때 /session/이 없는 index.do로 이동하도록 수정
<!-- main_menu.jsp -->
...
<li><a href="http://localhost:8080/spring_mvc.index.html">홈으로</a></li>
...
<li><a href="session/use_session.do">HttpSession 사용</a></li>
<li><a href="session/use_session_att.do">@SessionAttribute 사용</a></li>
...
- RequestMapping value값으로 “/묶을이름/요청.do” 형식을 사용하면 요청을 특정 이름으로 묶어 처리할 수 있다.
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
...
@Controller
public class SessionController {
// 요청을 특정 이름으로 묶어서 처리하려면 value에 "/묶을이름/요청.do"의
// 형식으로 사용한다.
@RequestMapping(value="/session/use_session.do", method=GET)
public String sessionForm() {
return "session/session_form";
@RequestMapping(value="/session/session_param.do", method=POST)
public String sessionParam(SessionVO s_vo, HttpSession session) {
System.out.println("------- param is -------"+s_vo.getName()+" "+s_vo.getAddr());
return "session/use_session";
}
}
package kr.co.sist.controller.vo;
public class SessionVO {
private String name, addr;
// setter, getter
...
<!-- session_form.jsp -->
...
<div>
<form action="session_param.do" method="post">
<label>이름</label>
<input type="text" name="name" class="inputBox"/><br/>
<label>주소</label>
<input type="text" name="addr" class="inputBox"/><br/>
<input type="submit" value="전송" class="btn"/>
</form>
</div>
...
-
HttpServletRequest를 받아 한글처리를 해도 적용이 안된다
- HttpServletRequest가 이전(DispatcherServlet)에서 먼저 사용이 되었기 때문에(첫 줄이 아니게 되었기 때문에) 한글처리가 안된다
// SessionController
...
@RequestMapping(value="/session/session_param.do", method=POST)
public String sessionParam(SessionVO s_vo, HttpServletRequest request, HttpSession session) throws UnsupportedEncodingException {
// HttpServletRequest를 이용한 한글처리 시도
request.setCharacterEncoding("UTF-8");
System.out.println("------- param is -------"+s_vo.getName()+" "+s_vo.getAddr());
System.out.println("------- param is -------"+request.getParameter("name"));
return "session/use_session";
}
}
-
한 방법은 한글처리 method를 만들어 사용하는 것
- 이전에 만들었던 한글처리 method 사용
public class HangulConv {
public static String toUTF(String kor) {
// empty를 물어 볼 때 kor.equals("")하면 kor이 null일 경우 NullPointException이 발생
// 따라서 이제 엠티를 비교할 땐 "".equals(kor)로 처리를 한다.
try {
if (kor != null || !"".equals(kor)) { // null이나 empty가 아니면 변환
kor = new String(kor.getBytes("8859_1"),"UTF-8");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return kor;
}
public static String toEUC(String kor) {
try {
if (kor != null || !"".equals(kor)) {
kor = new String(kor.getBytes("8859_1"),"EUC-KR");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return kor;
}
}
-
한글처리 method를 가진 HangulConv 클래스를 이용해서 한글처리
- 하지만 한글 처리를 일일이 해줘야 하는 문제가 발생!
// SessionController
...
@RequestMapping(value="/session/session_param.do", method=POST)
public String sessionParam(SessionVO s_vo, HttpServletRequest request, HttpSession session) throws UnsupportedEncodingException {
System.out.println("------- param is -------"+HangulConv.toUTF(s_vo.getName())+" "+s_vo.getAddr());
System.out.println("------- param is -------"+request.getParameter("name"));
return "session/use_session";
}
}
filter를 사용한 Spring 한글처리
- 요청이 처리되기 전에 수행해야 할 작업(전처리)이 필요한 경우 filter를 사용
-
DD(Deployment Descriptor, web.xml)에 설정하여 사용
- Source Code의 수정 없이 부가적인 코드를 실행할 수 있다.
-
Spring Framework에서는 한글처리 filter를 제공
- CharacterEncodingFilter
- DD에 아래와 같이 설정해두면 요청이 CharacterEncodingFilter를 거쳐 설정한 charset으로 Encoding되어 사용할 수 있다
<!-- web.xml -->
...
<filter>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<filter-name>객체명</filter-name>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>객체명</filter-name>
<url-pattern>/*</url-pattern><!-- 모든 URL에 대해서 Filter 동작 -->
</filter-mapping>
- 한글처리를 위해 다음과 같이 설정
<!-- web.xml -->
...
<filter>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<filter-name>cef</filter-name>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>cef</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
// SessionController
...
@RequestMapping(value="/session/session_param.do", method=POST)
public String sessionParam(SessionVO s_vo, HttpSession session) throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
System.out.println("------- param is -------"+s_vo.getName()+" "+s_vo.getAddr());
System.out.println("------- param is -------"+request.getParameter("name"));
return "session/use_session";
}
}
-
이어서 세션처리
- 입력된 매개변수 값을 session에 저장하여 JSP에서 사용이 가능
// SessionController
...
@RequestMapping(value="/session/session_param.do", method=POST)
public String sessionParam(SessionVO s_vo, HttpSession session) throws UnsupportedEncodingException {
// 입력되는 매개변수를 Session에 할당
session.setAttribute("ses_name", s_vo.getName());
session.setAttribute("ses_addr", s_vo.getAddr());
String url = "session/use_session"; // ViewResolver를 통해서 이동
session.setAttribute("flag", "forward로 이동");
if(new Random().nextBoolean()) {
// View Resolver를 통하지 않고 이동
url = "redirect:use_session.jsp";
session.setAttribute("flag", "redirect로 이동");
}
return url;
}
}
<!-- use_session.jsp -->
...
<div>
<strong>세션 사용</strong><br/>
<strong>${ sessionScope.flag }</strong><br/>
<strong>이름 : </strong>${ sessionScope.ses_name }<br/>
<strong>주소 : </strong>${ sessionScope.ses_addr }<br/>
</div>
- Controller에서 Session값을 사용할 때엔 HttpSession을 매개변수로 받아 사용한다.
// SessionController
...
@RequestMapping(value="/session/use_session.do", method=GET)
// 세션 값을 Controller에서 받기, HttpSession을 매개변수로 받아서 처리한다
public String sessionForm(HttpSession session) {
String name=(String)session.getAttribute("ses_name");
String addr=(String)session.getAttribute("ses_addr");
// 받은 값은 DB조회 등 업무로직에 사용하면 된다.
// ...
return "session/session_form";
}
...
- Session을 사용해서 값을 저장하면 다른 페이지 갔다가 다시 오더라도 사용이 가능하다.
<!-- session_from.jsp -->
...
<div>
<form action="session_param.do" method="post">
<label>이름</label>
<input type="text" name="name" class="inputBox" value="${ ses_name }"/><br/>
<label>주소</label>
<input type="text" name="addr" class="inputBox" value="${ ses_addr }"/><br/>
<input type="submit" value="전송" class="btn"/>
<a href="remove_session.do">세션삭제</a>
</form>
</div>
...
- 세션을 삭제하는 요청 만들기
@Controller
public class SessionController {
@RequestMapping(value="/session/remove_session.do", method=GET)
public String removeSession(HttpSession session) {
session.removeAttribute("ses_name");
session.removeAttribute("ses_addr");
session.invalidate();
return "session/session_form";
}
...
@SessionAttributes 사용
@SessionAttributes({"an_name", "an_addr"})
@Controller
public class SessionController {
@RequestMapping(value="/session/use_session_att.do", method=GET)
public String anSessionForm() {
return "session/an_session_form";
}
...
<!-- session/an_session_from.jsp -->
...
<div>
<form action="an_session_param.do" method="post">
<label>이름</label>
<input type="text" name="name" class="inputBox" value="${ an_name }"/><br/>
<label>주소</label>
<input type="text" name="addr" class="inputBox" value="${ an_addr }"/><br/>
<input type="submit" value="전송" class="btn"/>
<a href="an_remove_session.do">세션삭제</a>
</form>
</div>
...
- @SessionAttributes를 사용하면 HttpSession을 받지 않고 Model을 받는다.
// SessionController
...
@SessionAttributes({"an_name", "an_addr"})
...
@RequestMapping(value="/session/an_session_param.do", method=POST)
public String anSessionParam(SessionVO s_vo, Model m) throws UnsupportedEncodingException {
// 세션에서 사용할 값을 Model객체에 설정한다.
// 단, 이름은 위에서 정의한 이름과 같아야 세션으로 값이 할당된다.
// 저장된 값은 requestScope과 sessionScope에 동일하게 할당된다.
m.addAttribute("an_name", s_vo.getName());
m.addAttribute("an_addr", s_vo.getAddr());
String url = "session/use_session_att"; // ViewResolver를 통해서 이동
m.addAttribute("an_flag", "forward로 이동");
return url;
}
...
<!-- use_session_att.jsp -->
...
<div>
<strong>세션 사용</strong><br/>
<strong>${ sessionScope.an_flag }/${ requestScope.an_flag }</strong><br/>
<strong>이름 : </strong>${ sessionScope.an_name }/${ requestScope.an_name }<br/>
<strong>주소 : </strong>${ sessionScope.an_addr }/${ requestScope.an_addr }<br/>
</div>
...
- SessionAttributes로 설정된 Session값은 기존 방식대로 삭제가 안된다
// SessionController
...
@RequestMapping(value="/session/an_remove_session.do", method=GET)
public String anRemoveSession(HttpSession session) {
session.removeAttribute("an_name");
session.removeAttribute("an_addr");
session.invalidate();
return "session/an_session_form";
}
...
-
HttpSession을 매개변수로 받아서는 @SessionAttributes에 설정된 값이 삭제되지 않는다
- SessionStatus 객체를 매개변수로 받아서 setComplete메소드를 호출하여 세션을 삭제한다
// SessionController
...
@RequestMapping(value="/session/an_remove_session.do", method=GET)
public String anRemoveSession(SessionStatus ss) {
ss.setComplete();
return "session/an_session_form";
}
...