ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 모델1 모델2 책임 분리, JSON, Header-22.06.07~22.06.08
    웹프로그래밍 2022. 6. 8. 21:24
    728x90

     

    <복습>

    1.책임의 분리구조

    2.jsp, 서블릿 컨테이너 차이점 : 개발자와 역할분담 어떻게 하느냐에 따라

     서블릿은 개발자가 해야한다면 jsp컨테이너 템플릿 ui만 서블릿 , 클래스만든는것은 jsp컨테이너가 알아서..

    3.시큐어 보안 가이드 - > 검증

    4. mime text : 피어와피어 사이에서 데이터가오갈때 어떤 형식 어떤것인지 정의한것

    Model -> Model2 ->ajax -> XML/JSON(Marshalling)

    오늘은 XML/JSON(Marshalling) 이 과정을 해보겠다!!!

    request header 개념도 같이 보자.

     

    XML/JSON 왜 쓸까? 

    https://www.json.org/json-ko.html

    마셜링의미:

    객체의 메모리 구조를 저장이나 전송을 위해서 적당한 자료형태로 변형하는 것을 의미한다.

    Marshalling 은 보통 서로 다른 컴퓨터 혹은 서로 다른 프로그램 간에 데이터가 이동되어야 할 경우 사용된다.

     


    json일때
    html일때
    xml일때

    =>Accept : 나는 이러이러한 데이터만 받을 수 있어라고 셋팅하는것 

    응답데이터는 xml이어야 하는데 Response가 html임

    상태코드가 200이지만 

    콘솔에는 에러가

    언마셜링(다른 장소에서 잘왔나 컨테이너를 체크) 하려고했지만 타입이 맞지않아 에러 , json이지만 html이므로...

    <FactorialServlet.java>

    package kr.or.ddit.servlet04;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/04/factorial.do")
    public class FactorialServlet extends HttpServlet{
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		String accept =req.getHeader("Accept");  (추가!)
    		
    		//클라이언트 보내는 모든 데이터는 검증이 필요함!!!!
    		String param = req.getParameter("number");
    		if(param!=null && param.matches("\\d+")){
    			String pattern ="%d! =%d";
    			int number =Integer.parseInt(param);
    			//재귀 호출
    			long result= factorial(number);
    			String expression = String.format(pattern, number, result);
    			
    			Map<String, Object> resultMap = new HashMap<>();
    			resultMap.put("expression",expression);
    			resultMap.put("result",result);
    			(추가!)
    			if(accept.contains("json")) {
    				//응답 데이터를 json으로 표현 방식 변경. -Marshalling(native 언어로 표현된 데이터를 범용 표현 방식의 언어로 바꾸는 과정)
    				//JSON(JavaScript Object Notation) JSON을 객체화해야함
    				//{"expresssion":123123} 즉 {"expresssion":"6!=720"}
    				StringBuffer json = new StringBuffer();
    				json.append("{");
    				 for(Entry<String, Object> entry : resultMap.entrySet()/*맵을 셋으로 바꿈*/) {
    		               String key = entry.getKey();
    		               Object value = entry.getValue();
    		               
    		               if("expression".equals(key)) {
    		                  json.append("\"" + key.toString() + "\" : \"" + value.toString() + "\"");
    		               }
    		        }
    				json.append("}");
    				PrintWriter out =resp.getWriter();
    				out.println(json);
    				
    			}else {
    				
    				// request(Map존재) scope사용
    				req.setAttribute("expression", expression);
    				//서버사이드 방식임 그래서 /WebStudy01없어야함
    				String view ="/WEB-INF/views/FactorialView.jsp";
    				req.getRequestDispatcher(view).forward(req, resp);
    			}
    					
    		}else if(param!=null && !param.matches("\\d+")){
    			 //클라이언트에게 잘못됐다는것을 에러메세지 
    			 resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "펙토리얼 연산은 양수와 숫자만으로 처리");
    			 return;
    		 }
    		
    	}
    	
    	public long factorial(int number) {
    		if(number<0)
    			throw new IllegalArgumentException("음수에 대해서는 연산 불가");
    		if(number ==0){
    			return 1;
    		}else{
    					return number*factorial(number-1);
    		}
    		
    	}
    	
    }

    <factorial.jsp>

    <%@page import="java.util.Objects"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>04/factorial.jsp</title>
    <script type="text/javascript" src="<%=request.getContextPath()%>/resources/js/jquery-3.6.0.min.js"></script>
    
    </head>
    <body>
    <h4></h4>  
    <!-- 1.Model -> Model2 ->ajax -> XML/JSON(Marshalling) -->
    <!-- 2! ->2*1 =2, 3! ->3*2*1 =6 -->
    연산을 자바 스크립틀릿 기호만으로 반복 곱하기 연산 수행 <br>
    <!-- <form action="명령어_요청URL" method="파라미터 전송 방법 & 요청의 목적" enctype="요청 데이터의 표현 방식"></form> -->
    
    <form action="<%=request.getContextPath()%>/04/factorial.do" name="facForm">
     
     <input type="number" name="number" min="0" value="" />
     <input type="text" name="dummy" value="asas"/>
     <input type="submit" value="="/>
    </form>
    
    <div id ="resultArea">
    
    </div>
    
    <script>
    //발생한 이벤트는 파라미터로 들어오며, 이벤트에는 그 이벤트를 발생시킨 타켓이 들어가 있다.
    		let resultArea =$("#resultArea"); //변수로 받아놓는게 좋음
    		let facForm = $("form[name]").on("submit",function(event){
    			event.preventDefault();
    			//form 의 submit 이벤트의 기본 특성은 동기 요청.
    			console.log(event.target);
    			console.log(this);
    //			$(this) -> httpelement 에서 JQuery객체화
    //          XMLHttpRequest 객체를 활용한 비동기 요청
    			let action =this.action; //$(this).attr("action");
    			let method = this.method;
    			let data =$(this).serialize(); //Query String 생성
    			console.log(data); //ex)parm1=value&param2=value2
    			$.ajax({
    				url: action,
    				method:method,
    				data:data,
    				dataType:"json"  //text, html, json, xml, script->main type :text, 파일업로드 처리를 비동기로? (FormData)
    				,success:function(resp,status,jqXHR){ //resp : html소스 옴, json으로 바꿨으므로 {"expression":"6!=720"}
    					//$("#resultArea").html(resp);
    					$("#resultArea").html(resp.expression);
    			
    				},
    			    error :function(jqXHR, status, error){
    			    	console.log(jqXHR)
    			    	console.log(status)
    			    	console.log(error)
    			    }
    			});
    			return false;
    		});
    		console.log(facForm);
    		
    		
    </script>
    
    </body>
    </html>

    serialize : 데이터를 전송 혹은 저장하기 위해 바이트 배열의 형태로 변환하는 작업. 통신이나 저장하기 위해서 데이터를 일렬로 세움. ex) param1 = value1&param2 = value2
    jquery ajax로 호출하기 전에 serialize를 해주면 form 안에 값들을 한 번에 전송 가능한 
    data로 만들 수 있어 많은 data를 보낼 때 유용하다.]

    <JSON 형태- 다른시스템으로 데이터를 만들어 보내고 싶을때 적은양의 데이터를 보낼  수 있어서 사용하게됨>

    JSON 형태
    
    1) " " :true나 숫자는 안붙어도 됨
    
    let 객체변수 ={
    
        "변수명1" : 값1,
    
        "변수명2 ": 값2,
    
          ...
    
        "변수명n" : 값 n
    
    };
    
    2)
    
    let 객체변수 =[값1, 값2,...값n];
    
    ----------------------------------------------------------------------
    
    ex) let man ={  // man이라는객체의 멤버 변수가 2개 있다..
    
        "name":"홍길동",
    
         "age" :30
    
    };
    
    man.name  ==>홍길동
    man.age ==>30
    
    man["name"] ==>홍길동
    man["age"] ==>30
    
    //배열
    let names =["홍길동","이순신","강감찬","이몽룡"]
    names[0] ==> "홍길동"
    names[3] ==> "이몽룡"
    
    resp={"expression" : "6!=720"};
    resp.expression하고 꺼내면 됨!!

     


    --0608--

    선생님 버전

    => 이부분이 바로 마셜링 작업!!! , 직렬화시켜 보냄

    받는쪽(클라이언트)에서는 역직렬화를 하고 언마셜링함 복원된 객체가 이제 resp가 들어가있음

     

    메소드가 get일때

    Accept 헤더 :  반드시 답장을 json으로 해 

     

    메소드가 post일때

    => 이 데이터가 아니라 view source누르면 이게 진짜 서버로 넘어가는 데이터

    =>서버로 넘어가고 있는 데이터


    => contentType이 빠짐 

    jsp응답 나가는 구조는 모델1이다.

    책임을 분리해보겠다.


    중복을 없애고 책임을 분리해보자

    데이터타입이json일때 -> jsonView.do로 이동하고 -> 이동해서 처리한것을 다시 요청한곳으로 보내는 순서로 진행

    package kr.or.ddit.servlet04;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/04/factorial.do")
    public class FactorialServlet extends HttpServlet {
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		String accept = req.getHeader("Accept");
    		// 클라이언트 보내는 모든 데이터는 검증이 필요함.
    		String param = req.getParameter("number");
    		if(param!=null && param.matches("\\d+")){
    			String pattern = "%d! = %d";
    			int number = Integer.parseInt(param);
    		// 	재귀 호출: recursive call
    			long result = factorial(number);
    			String expression = String.format(pattern, number, result);  // 6! = 720
    			req.setAttribute("expression", expression);
    			req.setAttribute("result", result);
    			req.setAttribute("test", "한글데이터");
    			String view = null;
    			if(accept.contains("json")) {
    				view = "/jsonView.do";
    			}else {
    				view = "/WEB-INF/views/FactorialView.jsp";
    			}
    			req.getRequestDispatcher(view).forward(req, resp);
    			
    		}else if(param!=null && !param.matches("\\d+")){
    			resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "팩토리얼 연산은 양수와 숫자만으로 처리");
    			return;
    		}	
    	}
    	
    	public long factorial(int number){
    		if(number<0)
    			throw new IllegalArgumentException("음수에 대해서는 연산 불가"); 
    		if(number==0){
    			return 1;
    		}else{
    			return number * factorial(number - 1);
    		}
    	}
    
    }

    <kr/or/ddit/commons/JsonMarshallingViewServlet.java>

    package kr.or.ddit.commons;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebServlet("/jsonView.do")
    public class JsonMarshallingViewServlet extends HttpServlet{
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		resp.setContentType("application/json;charset=UTF-8");
    		// 응답데이터를 json 으로 표현 방식 변경. - Marshalling(native 언어로 표현된 데이터를 범용 표현 방식의 언어로 바꾸는 과정)
    //		JSON(JavaScript Object Notation)
    //		{"expression":123123}    {"expression": "6! = 720" , }
    		StringBuffer json = new StringBuffer();
    		String jsonPtrn = "\"%s\":\"%s\" , ";
    		json.append("{");
    		Enumeration<String> attrNames = req.getAttributeNames();  //여러개의 속성이름들가져옴
    		while (attrNames.hasMoreElements()) { attrNames="expression" ,"result" 이렇게 이름만!! 
    			String key = (String) attrNames.nextElement();
    			Object value = req.getAttribute(key); //여기서 꺼낼 수 있는 이유는 set으로 담아왔기 때문
    			json.append(String.format(jsonPtrn, key, value));
    		}
    		int lastIndex = json.lastIndexOf(",");
    		if(lastIndex >= 0 ) { //0보다 크면 ,가 있다. 해당안되면-1나옴
    			json.deleteCharAt(lastIndex);
    		}
    		json.append("}");
    		PrintWriter out = resp.getWriter();
    		out.println(json); // Serialize : 데이터를 전송 혹은 저장하기 위해 바이트 배열의 형태로 변환하는 작업.
    	}
    }

    Enumeration<String> attrNames = req.getAttributeNames();

    getAttributeNames() 여기에 키값만 들어옴!!

     

    <04.factorial.jsp>

    <%@page import="java.util.Objects"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>04/factorial.jsp</title>
    <script type="text/javascript" src="<%=request.getContextPath()%>/resources/js/jquery-3.6.0.min.js"></script>
    
    </head>
    <body>
    <h4></h4>  
    <!-- 1.Model -> Model2 ->ajax -> XML/JSON(Marshalling) -->
    <!-- 2! ->2*1 =2, 3! ->3*2*1 =6 -->
    연산을 자바 스크립틀릿 기호만으로 반복 곱하기 연산 수행 <br>
    <!-- <form action="명령어_요청URL" method="파라미터 전송 방법 & 요청의 목적" enctype="요청 데이터의 표현 방식"></form> -->
    
    <form action="<%=request.getContextPath()%>/04/factorial.do" name="facForm" method="get">
     
     <input type="number" name="number" min="0" value="" />
     <input type="text" name="dummy" value="asas"/>
     <input type="submit" value="="/>
    </form>
    
    <div id ="resultArea">
    
    </div>
    
    <script>
    //발생한 이벤트는 파라미터로 들어오며, 이벤트에는 그 이벤트를 발생시킨 타켓이 들어가 있다.
    		let resultArea =$("#resultArea"); //변수로 받아놓는게 좋음
    		let facForm = $("form[name]").on("submit",function(event){
    			event.preventDefault();
    			//form 의 submit 이벤트의 기본 특성은 동기 요청.
    			console.log(event.target);
    			console.log(this);
    //			$(this) -> httpelement 에서 JQuery객체화
    //          XMLHttpRequest 객체를 활용한 비동기 요청
    			let action =this.action; //$(this).attr("action");
    			let method = this.method;
    			let data =$(this).serialize(); //Query String 생성
    			console.log(data); //ex)parm1=value&param2=value2
    			$.ajax({
    				url: action,
    				method:method,
    				data:data,
    				dataType:"json"  //text, html, json, xml, script->main type :text, 파일업로드 처리를 비동기로? (FormData)
    				,success:function(resp,status,jqXHR){ //resp : html소스 옴
    					//$("#resultArea").html(resp);
    					//resultArea.html(JSON.stringfy(resp));
    					$("#resultArea").html(resp);
    					//alert(resp.test);
    				},
    			    error :function(jqXHR, status, error){
    			    	console.log(jqXHR)
    			    	console.log(status)
    			    	console.log(error)
    			    }
    			});
    			return false;
    		});
    		console.log(facForm);
    		
    		
    </script>
    
    </body>
    </html>

     

    get방식일때

    굳이 바디를 만들지 않아도 됨

    즉 바디는 메소드가 post일때만 바디가 만들어지고 get방식일때는 body가 안만들어진다.

     

    <form method="post">
    	<input type="hidden" name="_method" value="PUT">
    </form>
    바디가 있는put이 된다. 
    즉 원래 메소드로 정하게 됨
    
    <form method="get">
    	<input type="hidden" name="_method" value="PUT">
    </form>
    바디가 없는 put이 됨

    메소드를 생략한 모든 메소드는 GET방식 !!!! 바디는 없고 Line과 Header만 존재 

    수신자에게(URL) 어떤 요청(Method)을 보낼까를 표현하고 있음

    a href , img src  ,iframe, script, link href : GET방식, form을 제외한 나머지들 get방식이며 form은 메소드에 따라get인지post인지 바뀜...

     

    Accept :  요청을 보냈을때 응답데이터를 어떤형태로 받겠다.(내가 받아야하는 데이터)

    응답데이터의 컨텐트 타입으로서, 맨 우선순위 타입(text/html)으로 받겠다.. 

    =>압축 형식 중 이런것들만 받을 수 있다는것

    =>로케일 코드, Locale : language /country  언어는 한국어 지역은 한국  en-Us 언어는 영어 지역은 미국 

    내가 받아야하는 데이터 언어 가능하면 한국어로 해주고 , 우선순위적용으로 최우선은 한국 그다음은 ko(북한), 그래도 없으면 영어라도 줘라

     

    기본객체들을 뜻함

    (컬렉션의 개념은 꼭 알아두기)

    <requestHeader.jsp>

    <%@page import="java.util.Enumeration"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>05/requestHeader.jsp</title>
    </head>
    <body>
    <h4>요청 헤더의 종류</h4>
    <table>
    	<thead>
    		<tr>
    			<th>헤더이름</th>
    			<th>헤더값</th>
    		</tr>
    	</thead>
    	<tobody>
        <%
    		String pattern ="<tr><td>%s</td><td>%s</td></tr>";  
        	Enumeration<String> headerNames=request.getHeaderNames();
    		while(headerNames.hasMoreElements()){
    			String name =headerNames.nextElement();
    			String value = request.getHeader(name);
    			out.println(String.format(pattern, name, value));
    		}
    
        %>
        </tobody>
    </table>
    <pre>
         요청헤더 : 클라이언트와 요청에 대한 부가 정보를 key/value 형태로 표현한 데이터
    </pre>
    </body>
    </html>

    1.Request Line : Protocol/version URL Method
      Request Method (Http Method) : 요청의 목적, 요청의 포장 방식(body 생성 여부 결정)
          1)GET     (R) -서버의 데이터 조회
          2)POST    (C) -서버쪽에 새로운 데이터 생성
          3)PUT     (U) -수정(바디 필요할수도 없을 수도)
          4)DELETE  (D) -삭제(바디 필요할수도 없을 수도)
          5)OPTION : 서버가 현재 method를 지원하는지 여부를 확인하는 preFlight 요청에 사용되는 메소드.
          6)HEAD : 응답데이터를 body가 없는 메타 데이터만 받기 위한 요청에 사용.
          7)TRACE : 서버를 트래킹해서 디버깅하는 경우 사용.
          
    2.Request Header : client에 대한 부가 정보(meta data)
    3.Request Body(Message Body, Content Body) : 클라이언트가 서버로 전송하는 컨텐츠(내용)
       method 가 Post인 경우에만, 한정적으로 생성되는 영역.
       **method가 GET인 경우, 모든 데이터는 Request line을 통해  Query String(**)의 형태로 전송됨


     

    <script>
    	alert("<%=message%>");
    </script>

    이것때문에 에러 

    자바와 자바스크립트 데이터 공유 불가 

    <script>
    	alert('<%=message%>');
    </script>

    <userAgent.jsp>  

    -os가 추가되면 if문을 계속 늘려야하는 단점존재

    <%@page import="java.util.Enumeration"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>05/userAgent.jsp</title>
    </head>
    <body>
    <pre>
    	클라이언트의 시스템을 파악하고,
    	해당 OS에 대한 정보를 alert 창으로 렌더링.
    	(당신의 OS는 "%s"입니다.) 
    </pre>
    <%
    	String pattern ="당신의 OS는 \"%s\"입니다.";
    	String agent = request.getHeader("User-Agent");
        agent = agent.toUpperCase();
        String osName =null;
        if(agent.contains("WINDOWS")){
        	osName ="윈도우";
        }else if(agent.contains("ANDROID")){
        	osName ="안드로이드";
        }else if(agent.contains("IPHONE")){
        	osName ="아이폰";
        }else{
        	osName ="식별불가OS";
        }
        String message=String.format(pattern,osName);
       
        
    	
    %>
    
    <script>
    	alert('<%=message%>');
    </script>
    </body>
    </html>

    <%@page import="java.util.Map"%>
    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Enumeration"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>05/userAgent.jsp</title>
    </head>
    <body>
    <pre>
    	클라이언트의 시스템을 파악하고,
    	해당 OS에 대한 정보를 alert 창으로 렌더링.
    	(당신의 OS는 "%s"입니다.) 
    </pre>
    <%
    	String pattern ="당신의 OS는 \"%s\"입니다.";
    	String agent = request.getHeader("User-Agent");
        agent = agent.toUpperCase();
        String osName =null;
        Map<String, String> osMap = new HashMap<>();
        osMap.put("WINDOWS","윈도우");
        osMap.put("ANDROID","안드로이드");
        osMap.put("IPHONE","아이폰");
        osMap.put("UBUNTU","우분투");
        osMap.put("UNKNOWN","식별불가OS");
        osName =osMap.get("UNKNOWN");
        
        for(String key : osMap.keySet()){
        	osName =osMap.get(key);
        	if(osName!=null)
        		break;
        }
        String message=String.format(pattern,osName);
       
        
    	
    %>
    
    <script>
    	alert('<%=message%>');
    </script>
    </body>
    </html>

    enum 적용

    =>enum도 또다른 클래스임  

    일반 클래스는 변수,메소드 ,상수 다 넣을 수 있어

    enum클래스는 상수의 집합이 들어간다.

    s: static f: final

    이 상수들의 타입은  OsKind 타입의 상수가 5개 선언

    자기 타입의 상수를 가지고 있는것을 enum 


    alert +shift+ s+밑에서 3번째

     

    <OsKind.java>

    package kr.or.ddit.enumpkg;
    
    public enum OsKind {
    	WINDOWS("윈도우"), ANDROID("안드로이드"), IPHONE("아이폰"), UBUNTU("우분투"), UNKNOWN("식별불가 OS");
    	private String osName;
        -alert +shift+ s+밑에서 3번째
    	private OsKind(String osName) {
    		this.osName = osName;
    	}
    	
    	public String getOsName() {
    		return osName;
    	}
    	//변경할 수 없으므로 set은 못함
    	
    	
    }

    =>데이터를 완전히 분리시킴 

    <userAgent.jsp>

    <%@page import="kr.or.ddit.enumpkg.OsKind"%>
    <%@page import="java.util.Map"%>
    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Enumeration"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>05/userAgent.jsp</title>
    </head>
    <body>
    <pre>
    	클라이언트의 시스템을 파악하고,
    	해당 OS에 대한 정보를 alert 창으로 렌더링.
    	(당신의 OS는 "%s"입니다.) 
    </pre>
    <%
    	String pattern ="당신의 OS는 \"%s\"입니다.";
    	String agent = request.getHeader("User-Agent");
        agent = agent.toUpperCase();
        String osName =null;
    //     Map<String, String> osMap = new HashMap<>();
    //     osMap.put("WINDOWS","윈도우");
    //     osMap.put("ANDROID","안드로이드");
    //     osMap.put("IPHONE","아이폰");
    //     osMap.put("UBUNTU","우분투");
    //     osMap.put("UNKNOWN","식별불가OS");
    //      osName =osMap.get("UNKNOWN");
          osName =OsKind.UNKNOWN.getOsName();
        for(OsKind os : OsKind.values()){
        	osName =os.getOsName();
        	if(osName!=null)
        		break;
        }
        String message=String.format(pattern,osName);
       	
    %>
    <%=OsKind.IPHONE %>
    
    <script>
    	alert('<%=message%>');
    </script>
    </body>
    </html>

    OS를 찾아내는 책임이 이넘으로 이동하고 OS에 대한 책임을 jsp가 아니라 다이넘으로 넘기기!!!

    <OsKind.java>

    package kr.or.ddit.enumpkg;
    
    public enum OsKind {
    	WINDOWS("윈도우"), ANDROID("안드로이드"), IPHONE("아이폰"), UBUNTU("우분투"), UNKNOWN("식별불가 OS");
    	private String osName;
    
    	private OsKind(String osName) {
    		this.osName = osName;
    	}
    	
    	public String getOsName() {
    		return osName;
    	}
    	//변경할 수 없으므로 set은 못함
    	
    	public static OsKind findOs(String agent) {
    		
    		  agent = agent.toUpperCase();
    		  OsKind findedOs=OsKind.UNKNOWN;
    //		  String osName =null;
    //		  osName =OsKind.UNKNOWN.getOsName();
    		  
    		  for(OsKind os : OsKind.values()){
    			    if(agent.contains(os.name())){
    			    	findedOs=os;
    			    	break;
    			    }
    		    	
    		    }
    		  return findedOs;
    	}
    	public static String findOsName(String agent) {
    		OsKind findedOs = findOs(agent);
    		return findedOs.getOsName();
    	}
    	
    }

    <userAgent.jsp>

    <%@page import="kr.or.ddit.enumpkg.OsKind"%>
    <%@page import="java.util.Map"%>
    <%@page import="java.util.HashMap"%>
    <%@page import="java.util.Enumeration"%>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>05/userAgent.jsp</title>
    </head>
    <body>
    <pre>
    	클라이언트의 시스템을 파악하고,
    	해당 OS에 대한 정보를 alert 창으로 렌더링.
    	(당신의 OS는 "%s"입니다.) 
    </pre>
    <%
    	String pattern ="당신의 OS는 \"%s\"입니다.";
    	String agent = request.getHeader("User-Agent");
      	String osName =OsKind.findOsName(agent);
        String message=String.format(pattern,osName);
       	
    %>
    <%=OsKind.IPHONE %>
    
    <script>
    	alert('<%=message%>');
    </script>
    </body>
    </html>

    => jsp는 건들일 필요 없고 enum만 수정하면 됨

     여기서 배울점 책임을 어떻게 분리하느냐에 따라 달라진다는것이다. 더나은과정을 찾는것이다.

     

    728x90

    '웹프로그래밍' 카테고리의 다른 글

    Maven 설정환경-22.06.14  (0) 2022.06.14
    인코딩, 학생 등록하기 예제 -22.06.10  (0) 2022.06.10
    request, header - 22.06.09  (0) 2022.06.10
    JQuery 보강-22.06.07  (0) 2022.06.07
    모델1, 모델2 방식의 JSP -22.06.03  (0) 2022.06.03
Designed by Tistory.