ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • maven2, 마셜링 -22.06.15
    웹프로그래밍 2022. 6. 15. 21:30
    728x90

    <maven 자세히 살펴보기>

    세부적인 단계 하나하나  phase 이것들이 모은것을 bulid 

    ▶maven이 Plugins를 사용 

    ▶install은 jar로 플러그인을 지원함

    ▶1,2번 문제를 해결함 

    ▶dependency로 api를 끌어다가 씀  중앙저장소안에 있는 라이브러리 찾아서 dependency넣으면된다.

    ▶로컬 레파지토리


    저 밑줄은 어디가 있을까?

    groupId에다가 써주기 

    특정파일 찾아가기 위한 방법을 표현하고 있음 

    +부가 설명

     


    프로젝트를 관리하기 위해서 프로젝트 하나의 객체로 관리

    - POM(Project Object model) : 프로젝트를 객체화 -> 메이븐은 자바언어로 객체지향으로 프로젝트도 객체로 관리


    =>잘 만들어진 템플릿을 받아서 사용하겠다라는 의미 

    중앙저장소에서 받아올때 비 정상적인 템플릿이 존재할 수 도있기에 체크를 해줘야함

     

    =>배포경로 설정 

    Group Id:제품을 찾기위한 제품이름

    jar : stand alone
    war: web,웹용

     

    1. main영역 : 배포할때 사용하는곳,실제 개발 하는곳

    2: test영역 : 테스트 할때 사용, 배포할때 버림

    =>메이븐이 맨위처럼 보여주고 있는것임 

    =>test-classes는 classes를 사용할 수 있지만,

    test classes는 사라지기 때문에(배포하면) classes는 test-classes를 사용할 수 없다.


    <JUnit>

    자바 프로그래밍 언어용 단위 테스트 도구로 보이지 않고 숨겨진 단위 테스트를 끌어내어 정형화시켜 
    단위 테스트를 쉽게 해주는 테스트용 Framework

     

     

    =>단위테스트 프레임워크 /객체의 메소드 하나를 단위로

    =>아무이름이나 넣고 하려고 하니 

    Junit이 없다고 나온다

    추가하러가보자!!

    --

    빌드스크립트라고하며 이것을 복붙

    <scope></scope> :생략하게 되면 디폴트 값은 컴파일이며 모든 영역에서 자르파일을 쓸 수 있다.

    <scope>test</scope> :test에서만 사용가능 junit  mian에서 사용불가

    =>여기에 추가된것을 확인할 수 있다.

    여기에서 컨트롤+n => JUnit => JUnit Test 누르기

    => 이렇게 뜰것이다.

    package kr.or.ddit;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    
    public class SampleDAOTest {
    	SampleDAO dao = new SampleDAO();
    	@Test
    	public void testSelectData() {
    		fail("Not yet implemented");
    
    	}
    
    }

    => 실패한것임

    <SampleDao.java>

    package kr.or.ddit;
    
    public class SampleDAO {
    	public String selectData() {
    		
    		return "DATA";
    	}
    }

    <SampleDAOTest>

    package kr.or.ddit;
    
    import static org.junit.Assert.*;
    
    import org.junit.Test;
    
    public class SampleDAOTest {
    	SampleDAO dao = new SampleDAO();
    	@Test
    	public void testSelectData() {
    		String result =dao.selectData();
    		assertEquals("DATA", result);
    	}
    
    }

    JUnit사용하는 이유

    1.로직 정상적으로 동작하는지  확인

    2.퍼포먼스 시간 확인

    => 반대로  main 에서는 test에 있는것은 사용하지 못한다.

    ( 아마도...? test에 있는것들은 배포하면 사라질것이니...)

     


    1.5 이므로 새로나온 문법 사용할 수 없어 complie단계에서 바꿔야하며 complier플러그인 사용

    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.1</version>
    </dependency>

     

    ${ } :프로퍼티 플레이스 오더 :버전이 변경되면 프로퍼티만 수정하면 된다.

    수정하고 반드시 업데이트!!!

    =>바뀐것을 확인할 수 있음

    target폴더는 메이븐만 사용

    =>새로 만들어냄


    1.메이븐 웹용 프로젝트 만들기

    2. 컴파일러 버전은 1.8

    3. JUnit프로젝트 사용해보기

    => dummyWebMVN이름으로 만들기 

    2.5버전도 추후 고쳐줘야함

    주개발영역과 테스트영역 분리

     

    =>지금 서블릿 개발 못함

    servlet-api검색

    Java Servlet API선택

    jsp-api검색

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>kr.or.ddit</groupId>
      <artifactId>dummyWebMVN</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      <dependencies>
      	<dependency>
    	  	<groupId>javax.servlet</groupId>
    	    <artifactId>javax.servlet-api</artifactId>
    	    <version>3.1.0</version>
    	    <scope>provided</scope>
      	</dependency>
      	<dependency>
    	    <groupId>javax.servlet.jsp</groupId>
    	    <artifactId>javax.servlet.jsp-api</artifactId>
    	    <version>2.2.1</version>
    	    <scope>provided</scope>
    	</dependency>
      	
      </dependencies>
    </project>

    provided: 컴파일할때 사용하고 배포할떄 버림,Runtime 시점에 JDK 혹은 컨테이너가 제공한다.

     

     

    에러잡자

    => web.xml만들어주기 

     

    컨트롤 쉬프트 f

     

     프로젝트 누르고 Alt+Enter

    =>그런데 3.1로 고쳐주려고 하는데 1.7버전이라 되지 않는다. 

    pom.xml부터 고치자

    =>Local Repositiries 내가 전에 이용했던거 사용했던거 이용할 수 있음...

    로컬에 저장된것을 이용하는것임

    => 로컬 디렉토리에 이미 올라와 있는 라이브러리는 add dependency, add plugin으로 쉽
    게 추가할 수 있다.

    => maven compiler검색 

    => 이부분이 자동으로 생김

     

    jre 1.8로 바꿔주고 Java facets에서 버전 바꿔 준 후, web.xml을 지웠다가 다시 생성한
    다.
    서블릿 버전이 3.1로 바뀌어있는지 확인한다.

    ctrl+shift+f누르면 확인할 수 있음

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>kr.or.ddit</groupId>
      <artifactId>dummyWebMVN</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>war</packaging>
      	  <properties>
      	<java-version>1.8</java-version>
      </properties>
      <build>
      	<plugins>
      	 <plugin>
      	 	<groupId>org.apache.maven.plugins</groupId>
      	 	<artifactId>maven-compiler-plugin</artifactId>
      	 	<version>3.10.1</version>
      	 	<configuration>
      	 		<source>${java-version}</source>
      	 		<target>${java-version}</target>
      	 	</configuration>
      	 </plugin>
      	</plugins>
      </build>
      <dependencies>
      	<dependency>
    	  	<groupId>javax.servlet</groupId>
    	    <artifactId>javax.servlet-api</artifactId>
    	    <version>3.1.0</version>
    	    <scope>provided</scope>
      	</dependency>
      	<dependency>
    	    <groupId>javax.servlet.jsp</groupId>
    	    <artifactId>javax.servlet.jsp-api</artifactId>
    	    <version>2.2.1</version>
    	    <scope>provided</scope>
    	</dependency>
      	
      </dependencies>
    </project>

    <마셜링하기>

    json방식으로 마셜링할때

    마셜링할때 사용

    xml 방식으로 마셜링할때

    =>두개다 2.13.3버전누르기 

     

    pom.xml

     

    <HelloMVNServlet>

    package kr.or.ddit;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    @WebServlet("/test.do")
    public class HelloMVNServlet extends HttpServlet {
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		Map<String, Object> target =new HashMap<>();
    		target.put("prop1", "TEXT_VALUE");
    		target.put("prop2", 23);
    		target.put("prop3", false);
    		target.put("prop4", new String[] {"a","b"});
    		
    		//1. Json marshalling
    		ObjectMapper jsonMapper = new ObjectMapper();
    		String json = jsonMapper.writeValueAsString(target);
    		resp.setContentType("application/json;charset=UTF-8");
    		PrintWriter out =resp.getWriter();
    		out.println(json);  //serialization
    		
    //		req.getRequestDispatcher("/01/test.jsp").forward(req, resp);
    	}
    }

    JUnit없어서에러가 나고 있음   add dependency에서 찾아오기 

    => 아까 사용했으므로 로컬에 남아있을거야  프로젝트 우클릭 Maven -> add찾으면됨

    <test용으로 만든 마셜링/직렬화>

    -JSONMarshallingTest.java

    package kr.or.ddit;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import com.fasterxml.jackson.core.exc.StreamReadException;
    import com.fasterxml.jackson.databind.DatabindException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class JSONMarshallingTest {
    	static ObjectMapper mapper;
    	
    	@BeforeClass  //딱한번 사용
    	public static void setUpClass(){
    		mapper =new ObjectMapper();
    	}
    	
    	Map<String, Object> target =new HashMap<>();
    	@Before   //먼저 사용
    	public void setUp() {
    		target.put("prop1", "TEXT_VALUE");
    		target.put("prop2", 23);
    		target.put("prop3", false);
    		target.put("prop4", new String[] {"a","b"});
    	}
    	//java-> json
    	@Test
    	public void testMarshalling(){
    		try {
    			mapper.writerWithDefaultPrettyPrinter().writeValue(System.out, target); //마셜링 부터 직렬화 까지 다함
    		} catch (IOException e) {
    			throw new RuntimeException(e);  //Junit프레임웍이 가져가게됨
    			
    		}  
    		
    	}
    	//json -> java
    	@Test
    	public void testUnmarshalling() throws StreamReadException, DatabindException, IOException {
    		InputStream is = JSONMarshallingTest.class.getResourceAsStream("sample.json");
    		//역직렬화 -> unmarshalling
    		Map<String, Object> result =mapper.readValue(is, HashMap.class);
    		System.out.println(result);  
    	}
    }

    1. 마셜링하고 직렬화 까지 해줌

    2, 마셜링 까지만

    .

     


    폴더의 계층은 .이아니라 /이다.

     

    <XMLMarshallingTest.java>

    package kr.or.ddit;
    
    import static org.junit.Assert.*;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    import com.fasterxml.jackson.core.exc.StreamReadException;
    import com.fasterxml.jackson.core.exc.StreamWriteException;
    import com.fasterxml.jackson.databind.DatabindException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.dataformat.xml.XmlMapper;
    
    public class XMLMarshallingTest {
    	static ObjectMapper mapper;
    	@BeforeClass  //딱한번 실행
    	public static void setUpClass() {
    		mapper = new XmlMapper();
    	}
    	Map<String, Object> target = new HashMap<>();
    	@Before   //먼저 사용
    	public void setUp() {
    		target.put("prop1", "TEXT_VALUE");
    		target.put("prop2", 23);
    		target.put("prop3", false);
    		target.put("prop4", new String[] {"a","b"});
    	}
    	@Test
    	public void test() throws StreamWriteException, DatabindException, IOException {
    		mapper.writerWithDefaultPrettyPrinter()
    		.withRootName("root")
    		.writeValue(System.out, target);
    	}
    	@Test
    	public void testUnmarshalling() throws StreamReadException, DatabindException, IOException {
    		InputStream is =XMLMarshallingTest.class.getResourceAsStream("sample.xml");
    		Map<String, Object> result =mapper.readValue(is, HashMap.class);
    		System.out.println(result);
    	}
    
    }

    마셜링과 언마셜링 쉽게 젝슨라이브러리? 사용

     

     


    새로운 프로젝트 만들어보자 + 이관작업

    kr통채로 옮기기!! src->mian안에 java , res-> resources에 

    lib지우기 maven하면서 필요없어짐...

    서블릿6패키지의 에러를 잡아보자

    <pom.xml >

    <project xmlns="http://maven.apache.org/POM/4.0.0"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>kr.or.ddit</groupId>
    	<artifactId>WebStudy02_MVN</artifactId>
    	<version>1.0</version>
    	<packaging>war</packaging>
    	<properties>
    		<java-version>1.8</java-version>
    		<com.fasterxml.jackson-version>2.13.3</com.fasterxml.jackson-version>
    	</properties>
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.10.1</version>
    				<configuration>
    					<source>${java-version}</source>
    					<target>${java-version}</target>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    
    	<dependencies>
    		<!-- servlet api 용 의존성 -->
    		<dependency>
    			<groupId>javax.servlet</groupId>
    			<artifactId>javax.servlet-api</artifactId>
    			<version>3.1.0</version>
    			<scope>provided</scope>
    		</dependency>
    		<dependency>
    			<groupId>javax.servlet.jsp</groupId>
    			<artifactId>javax.servlet.jsp-api</artifactId>
    			<version>2.2.1</version>
    			<scope>provided</scope>
    		</dependency>
    		<!-- apache commons 계열 -->
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>commons-lang3</artifactId>
    			<version>3.12.0</version>
    		</dependency>
    		<!-- reflection 지원용 -->
    		<dependency>
    			<groupId>commons-beanutils</groupId>
    			<artifactId>commons-beanutils</artifactId>
    			<version>1.9.4</version>
    		</dependency>
    		<!-- Marshalling 지원용 -->
    		<dependency>
    			<groupId>com.fasterxml.jackson.core</groupId>
    			<artifactId>jackson-databind</artifactId>
    			<!-- property placeholder ${property_name} -->
    			<version>${com.fasterxml.jackson-version}</version>
    		</dependency>
    		<dependency>
    			<groupId>com.fasterxml.jackson.dataformat</groupId>
    			<artifactId>jackson-dataformat-xml</artifactId>
    			<version>${com.fasterxml.jackson-version}</version>
    		</dependency>
    	</dependencies>
    </project>

     

    <깨진거 확인하기>

    깨진사람 이거 삭제하고 업데이트 다시 하기 

     

    컨트롤 쉬프트  r :프로젝트 찾기

     


    json, html, xml마셜링 작업 

    <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 service(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()) {
    			String key = (String) attrNames.nextElement();
    			Object value = req.getAttribute(key);
    			json.append(String.format(jsonPtrn, key, value));
    		}
    		int lastIndex = json.lastIndexOf(",");
    		if(lastIndex >= 0 ) {
    			json.deleteCharAt(lastIndex);
    		}
    		json.append("}");
    		PrintWriter out = resp.getWriter();
    		out.println(json); // Serialize : 데이터를 전송 혹은 저장하기 위해 바이트 배열의 형태로 변환하는 작업.
    	}
    }
    package kr.or.ddit.commons;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    @WebServlet("/jsonView.do")
    public class JsonMarshallingViewServlet extends HttpServlet{
    	@Override
    	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		resp.setContentType("application/json;charset=UTF-8");
    		//1.마셜링의 타켓 : scope
    		Enumeration<String> attrNames =req.getAttributeNames();
    		Map<String, Object> target = new HashMap<>();
    		while(attrNames.hasMoreElements()) {
    			String attName = (String)attrNames.nextElement(); //key
    			Object value = req.getAttribute(attName); //value
    			target.put(attName,value);
    		}
    		//2.마샬링
    		//3.직혈화
    		ObjectMapper mapper = new ObjectMapper();
    //		try~with~resource 문법 구조(1.7)
    		try(
    				//closable 객체 생성 코드 -> 자동 close됨.
    				PrintWriter out = resp.getWriter();		
    		){	
    			mapper.writeValue(out, target);
    		}
    		 
    	}
    }
    ObjectMapper :json객체를 다루는 라이브러리객체
    {
    "key":"value",
    "key2":"value2"
    }
    
    mapper.writeValue(out, target);  : map 에들어있는것들 json형태로 출력해라

     

    <XMLMarshallingViewServlet.java>

    package kr.or.ddit.commons;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.dataformat.xml.XmlMapper;
    
    @WebServlet("/xmlView.do")
    public class XMLMarshallingViewServlet extends HttpServlet{
    	@Override
    	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		resp.setContentType("application/xml;charset=UTF-8");
    		//1.마셜링의 타켓 : scope
    		Enumeration<String> attrNames =req.getAttributeNames();
    		Map<String, Object> target = new HashMap<>();
    		while(attrNames.hasMoreElements()) {
    			String attName = (String)attrNames.nextElement(); //key
    			Object value = req.getAttribute(attName); //value
    			target.put(attName,value);
    		}
    		//2.마샬링
    		//3.직혈화
    		ObjectMapper mapper = new XmlMapper();
    //		try~with~resource 문법 구조(1.7)
    		try(
    				//closable 객체 생성 코드 -> 자동 close됨.
    				PrintWriter out = resp.getWriter();		
    		){	
    			mapper.writeValue(out, target);
    		}
    		 
    	}
    }

    <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>Factorial 연산 처리</h4>
    <!-- 1. Model1 -> Model2 -> ajax -> XML/JSON(Marshalling) -->
    2! -> 2*1 = 2, 3! -> 3*2*1 =  6
    10! 
    스크립틀릿 기호만으로 반복 곱하기연산 수행.
    <!-- <form action="명령어_요청URL" method="파리미터 전송 방법 & 요청의 목적" enctype="요청 데이터의 표현 방식"> -->
    <input type="radio"  name="datatype" value="html"/>HTML 
    <input type="radio"  name="datatype" value="json"/>JSON
    <input type="radio"  name="datatype" value="xml"/>XML
    
    <form action="<%=request.getContextPath() %>/04/factorial.do" name="facForm" method="">
    <input type="number" name="number" min="0" value=""/>
    <input type="text" name="dummy" value="adfsasdfa" />
    <input type="submit" value="=" />
    </form>
    
    <div id="resultArea">
    
    </div>
    
    <script type="text/javascript">
    	let resultArea = $("#resultArea");
    	let successMap = {
    		json:function(resp){
    			resultArea.html(resp.expression);
    		},	
    		xml:function(resp){
    			console.log("==========XML=============");
    			console.log(resp);
    			let expr = $(resp).find("expression");
    			resultArea.html(expr);
    		},	
    		html:function(resp){
    			resultArea.html(resp);
    		}	
    	}
    	let facForm = $("form[name]").on("submit", function(event){
    		event.preventDefault();
    		// form 의 submit 이벤트의 기본 특성은 동기 요청.
    		console.log(event.target);
    		console.log(this);
    // 		$(this) -> jQuery 객체화
    // 		XMLHttpRequest 객체 활용한 비동기 요청.
    		let action = this.action; // $(this).attr("action");
    		let method = this.method;
    		let data = $(this).serialize(); // Query String 생성 ex) param1=value1&param2=value2
    		console.log(data);
    		let settings = {
    				url : action,
    				method : method,
    				data : data,
    				error : function(jqXHR, status, error) {
    					console.log(jqXHR);
    					console.log(status);
    					console.log(error);
    				}
    			}
    		settings.dataType = $("[name='datatype']:checked").val();
    		console.log("datatype : "+settings.dataType);
    		settings.success=successMap[settings.dataType];
    		$.ajax(settings);
    		return false;
    	});
    	console.log(facForm);
    </script>
    </body>
    </html>

     

    1.보고서에 maven 구축환경

    2. 사칙연산 과제 

    728x90

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

    로그인,기본객체 -22.06.16~06.17  (0) 2022.06.17
    Reponse -0616  (0) 2022.06.16
    Maven 설정환경-22.06.14  (0) 2022.06.14
    인코딩, 학생 등록하기 예제 -22.06.10  (0) 2022.06.10
    request, header - 22.06.09  (0) 2022.06.10
Designed by Tistory.