-
UML: ClassDiagram,SequenceDiagram, Servlet:FilterJAVA 2021. 7. 26. 12:56
UML: Sequence Diagram
Class Diagram: 정적다이어그램 Sequence Diagram: 동적다이어그램(시간순서대로)
// control 의 업무진행 과정을 순서대로 자세히 나타낼 수 있다.Class Diagram
control
- 메모
요청사항 + 요청명 + 받는 parameter 기입 'key : value'
- forward 메모
1) 보내는 parameter = 'key:value'
2) 해당사항이 어떤조건인지 '정상' 루트인지 '비정상' 루트인지
1. Sequence Diagram 작성하기 // 컨트롤들의 내부,외부 순서
Interactions ( Basic ) : 왼쪽 하단의 Toolbox 탭 Lifeline (이미 생성한 클래스(control) 을 끌어당겨 놓으면 알아서 lifeline 으로 생성.)
이름: '객체명 : 클래스명' (control 의 객체명은 딱히 중요치 않으니 "Lifeline1:클래스명" 으로Self Message : 이 컨트롤에서 해야 할 업무들(내부에서 검사) Message
이름: 가리킨 것이 control 로, forward 할 때 '해당 컨트롤 요청명'
가리킨 것이 DAO 로, 그 메서드를 사용할 때 '메서드(매개변수)'
가리킨 것이 view 로, 'forward(업무 후 추출한 값)'
1. -- > (Message 선 더블클릭하고 양옆에 뜨는 선택사항중 Add Replay Message) = 메서드 호출 후 받는 return 값
이름: return 변수명 이니 '변수명'
해당 return 값이 객체라면 그 클래스를 가져오고 '변수명 : 클래스명' 에 변수명을 똑같이 설정
2. [] ( Message 선 누르고 오른쪽하단 상세탭에 guard ) : 조건을 나타낼 때 사용.Interactions ( Advanced ) : 왼쪽 하단의 Toolbox 탭 Found Message : 해당 control 의 '메서드(request 가 가지고 온 parameter)' 기입
해당 message 더블클릭하고 add note : 해당 컨트롤의 요청명 기입오른쪽의 회원상세업무에 대한 Class Diagram 을 , 왼쪽의 Sequence Diagram 으로 순서대로 자세히 작성 실제 Sprging 상황. 위의 Sequence Diagram 의 1번 순서와 똑같음.
@Controller public class 회원상세보기 implements IControl{ @Autowired IMemberDAO memberDAO; @RequestMapping("detail_member") public ModelAndView process(int no) { } }
2. 위 작성을 토대로 코드작성(설계서 그대로 해보기)
>> 회원상세보기.java
public class 회원상세보기 implements IControl{ IMemberDAO memberDAO = new MemberDAO(); @Override public ModelAndView process(HttpServletRequest request, HttpServletResponse response) { int 회원번호 = Integer.valueOf(request.getParameter("no")); // 로그인 여부검사 boolean 로그인 = false; HttpSession session = request.getSession(false); if(session != null && session.getAttribute("name") != null) { 로그인 = true; } ModelAndView mv = new ModelAndView(); if(!로그인) { mv.addObject("message", "로그인 후 이용이 가능합니다."); mv.setViewName("forward:/prepare_login.do"); return mv; } Member findedMember = memberDAO.findByNo(회원번호); mv.addObject("findedMember", findedMember); mv.setViewName("회원상세창"); return mv; } }
control 들은 멤버변수없이 메서드만 있는 상태가 없는 클래스다(빈객체=Stateless). Spring 에서는 이를 빈객체라 하여 관리해주는 것이다
이 Spring 에서 빈객체로 선언되면 컨테이너(톰캣서버) 가 실행되어 초기화할 때 같이 데이터가 올라간다.
그러면 각 요청마다 계속 초기화, 선언해서 속도가 늦춰졌던걸 컨테이너 범위에서 초기화 하므로서 방지할 수 있다.>> Profile.java (회원상세창에 띄울 프로필사진을 위해 작업하는 control)
public class Profile implements IControl{ IMemberDAO memberDAO = new MemberDAO(); @Override public ModelAndView process(HttpServletRequest request, HttpServletResponse response) { int no = Integer.valueOf(request.getParameter("no")); Member member = memberDAO.findByNo(no); ModelAndView mv = new ModelAndView(); mv.setViewName("profile"); mv.addObject("profile", member.getProfile()); return mv; } }
>> profile.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page trimDirectiveWhitespaces="true" %> //꼭 기입!!!(자꾸 OutputStream이 이미 읽었다고 뭐라함, 그리고 whitespace가 있다고 한다는데..?) <% byte[] profile = (byte[])request.getAttribute("profile"); response.setContentType("image/jpeg"); ServletOutputStream os = response.getOutputStream(); os.write(profile); %>
>> 회원상세창.jsp
<body> <h1>회원상세</h1> 성명 <input type = "text" id="name" readonly="readonly" value="${findedMember.name}"><br> 프로필<img src="profile.do?no=${findedMember.no}"/><br> 우편번호 <input type = "text" id="post" readonly="readonly" value="${findedMember.post}"><br> 주소 <input type = "text" readonly="readonly" value="${findedMember.address}"> <br> 상세주소 <input type = "text" readonly="readonly" value="${findedMember.detailaddress}"> <br> 전화번호 <input type = "text" readonly="readonly" value="${findedMember.tel}"/><br> 이메일 <input type = "text" readonly="readonly" value="${findedMember.email}"/><br> 아이디 <input type = "text" readonly="readonly" value="${findedMember.id}"><br> </body>
Filter
Filter 만들기 (LoginFilter 만들기) FrontController 보다 먼저 모든(다수Filter 생성가능) Filter 의 doFilter() 를 수행하고 FrontController 로 간다. 1. HttpServlet 을 상속받아 Http 에서 Tomcat 서버안에 돌아가는 Servlet 을 상속받고
Filter 를 구현한다.2. Login 확인을 위한 코드를 그대로 작성한다.
- session 같은 경우는 현재 Http 규격이라 HttpSession 이기 때문에 request 도 부모인 ServletRequest 로 얻어지지 않고
HttpServletRequest 로 형변환 하여 getSession(false) 해야한다.
- 로그인 안했을 때는 prepare_login.do 컨트롤로 가도록 forward 시킨다.추가사항 : String table 로 따로 class 를 만들어 로그인 하지 않았을 때 던지는 message 들을 요청명에 따라 다르게 나오도록 설정할 수 있다.
// 규격화 된 상황은 아니다.3. chain.doFilter(request.response) 작성한다.
다음 Filter 로 chain 되게하는 방법이다.(끝나면 FrontController 로)
순서는 현재 filter 에서 로그인여부에 걸린다면 forward 하면서 끝나거나
현재 filter 에 걸리지않으면 chain.doFilter() 로 다른 filter 들까지 호출하고 이 메서드 끝나면 chain.doFilter() 밑의 코드들을 실행시킨다.4-1. web.xml 에 <filter> 를 <filter-name> 을 정하고 <filter-class> 로 어디에 있는 필터클래스인지 설정한다.
4-2. <filter-mapping> 에 위의 <filter-name> 을 가져와 매핑준비하고 <url-pattern> 에 매핑할 컨트롤 주소들을 적는다.>> LoginFilter.java
이제 나머지 control 에 있는 로그인 확인 업무를 다 지워도 된다.
import javax.servlet.Filter; //javax.servlet 꺼다. ... public class LoginFilter extends HttpServlet implements Filter { public void init(FilterConfig filterConfig) throws javax.servlet.ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, javax.servlet.ServletException { // 요청전 // HttpSession 을 얻으려면 이 메서드는 ServletRequest 객체이기 때문에 HttpServletRequest 객체로 형변환하여 가져와야한다. // HttpServletRequest 는 ServletRequest 를 상속받았다. HttpSession session = ((HttpServletRequest)request).getSession(false);//없으면 null 값을 준다. boolean 로그인 = false; if (session != null && session.getAttribute("no") != null) { 로그인 = true; }; if(!로그인) { request.setAttribute("message", "로그인 후 이용이 가능합니다."); RequestDispatcher rd = request.getRequestDispatcher("prepare_login.do"); rd.forward(request, response); return; } chain.doFilter(request, response); // 응답전 } public void destroy() { } }
>> web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>loginFilter</filter-name> <filter-class>com.stone.mvc.env.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/prepare_board.do</url-pattern> <url-pattern>/add_board.do</url-pattern> <url-pattern>/detail_member.do</url-pattern> </filter-mapping> </web-app>
>> 로그인창.jsp
만약 로그인 안하고 위 매핑되어 있는 페이지로 가려하면 이렇게 이 로그인창이 뜨며 message 가 넘어와 출력된다.
<body> <h1>로그인</h1> <p>${message}</p> <form action="login.do" method="post" onsubmit="return 필수입력()"> id <input type="text" id="id" name="id"/> password <input type="password" id="password" name="password"/> <input type="submit" value="로그인"/> </form> </body>
'JAVA' 카테고리의 다른 글
Spring:Mapping,Repository,Autowired(DI),multipartFile (0) 2021.07.26 Spring, Tomcat Servers의xml파일정리 (0) 2021.07.26 로그인아웃, session (0) 2021.07.26 redirect, forward,spring 서두 (0) 2021.07.26 JSP: FrontController 직접 구현해보기 (0) 2021.07.26