• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

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>
...

01

  • 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";
      }
}

02

  • 한 방법은 한글처리 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";
      }
}

03

filter를 사용한 Spring 한글처리

04

  • 요청이 처리되기 전에 수행해야 할 작업(전처리)이 필요한 경우 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";
      }
}

05

  • 이어서 세션처리
    • 입력된 매개변수 값을 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>

06

  • 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";
      }
...

07

@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>
...

08

  • 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";
      }
...

09

  • 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";
      }
...


Java EESpring