웹프로그래밍

모델1 모델2 책임 분리, JSON, Header-22.06.07~22.06.08

AIN99 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