eyesofkhepri
03-3. x-www-form-urlencoded 본문
x-www-form-urlencoded
웹 설계 당시에 웹을 설계 하는 사람들은 각 운영체제의 차이점을 처리해야 하는 과제에 직면 했다. 왜냐하면 이 문제는 URL을 사용함에 있어서 문제를 발생시키고 있었기 때문이다. 예를 들자면 몇몇 운영체제는 파일 이름에 공백이 허용되지만 어떤건 되지 않았고, 어떤 운영체제는 파일이름에 # 기호가 허용되지만 URL에서 #은 부위 지정자 역할을 하고 있었으며 웹이 처음에 만들어 졌을때는 유니코드가 널리 사용되지 않았기에 한글, 한자, 중국어 등등의 문자를 처리할 수 없었기 때문이였다.
이러한 문제를 해결하고자 URL에서 사용될 문자들은 다음과 같이 정해진 일부 아스키 문자 집합으로 표현되어야 했다.
- 대문자 A-Z
- 소문자 a-z
- 숫자 0~9
- 문장부호 문자 - _ . ! ~ * ' ,
만약 / & ? @ # ; $ + = %같은 특수 한 목적의 문자나 한글, 한자, 중국어 같은 문자를 처리하고 하는 경우는 어떻게 해야할 것인가? 현재는 각각을 모두 인코딩해서 사용하고 있다.
이런식으로 인코딩된 형식을 x-www-form-urlencoded 형식이라 한다.
인코딩은 간단하게 이루어진다. 위에 명시한 4개의 문자 집합을 제외한 나머지 문자들은 모두 Byte로 변환되고 변환된 바이트들은 %기호와 두개의 16진수로 표기된다. 스페이스 경우는 자주 사용되기 때문에 %20으로 고정이 되어있다. 또한 +기호도 %2B로 인코딩 된다. / # = & ? 문자는 URL요소를 구분하는 용도의외에 쿼리문자열로 사용되는 경우는 동일하게 인코딩된다.
Java에서는 이런 인코딩을 해주는 URLEncoder와 디코딩을 해주는 URLDecoder를 지원해준다.
1. URLEncoder
URLEncoder를 통해서 인코딩을 할 수 있다.
public static void main(String[] args) { /** * String encode(String s, String enc) : 비아스키 문자를 enc로 인코딩 하며 '/','&','=',':'등의 문자를 퍼센트인코딩 하며 띄어쓰기는 '+'로 인코딩한 결과를 리턴한다. */ try { System.out.println(URLEncoder.encode("Encode String*Test%One+Two/Three\"Four:Five~Six(Teen)Seven.Eight=Nine&Ten킹", "UTF-8")); } catch (UnsupportedEncodingException e) { System.err.println(e); } }
하지만 encode()메소드는 URL의 각 구성 요소를 구분하지 않고 모두 인코딩 해버린다. 결국 한 URL을 통으로 인코딩하면 안되며 각 구성요소를 찾아서 그 각 요소를 인코딩 해줘야 한다. 보통 GET 메소드를 통해서 서버 측 프로그램과 통신을 위한 쿼리 문자열을 만드는데 URLEncoder를 많이 사용하므로 잘 알아 두어야 한다.
public class GenQueryString { private final String ENCODE = "UTF-8"; private StringBuilder query = new StringBuilder(); public GenQueryString() {} public synchronized void add(String name, String value) { query.append('&'); encode(name, value); } private synchronized void encode(String name, String value) { try { query.append(URLEncoder.encode(name, ENCODE)); query.append('='); query.append(URLEncoder.encode(value, ENCODE)); } catch (UnsupportedEncodingException e) { System.err.println(e); } } public synchronized String getQuery() { return query.toString(); } @Override public String toString() { return getQuery(); } public static void main(String[] args) { //https://www.youtube.com/watch?v=UhC7M8KF7AE&list=RDpIw7RAfYgI8&index=2&line=I/O 변환 GenQueryString qs = new GenQueryString(); qs.add("v", "UhC7M8KF7AE"); qs.add("list", "RDpIw7RAfYgI8"); qs.add("index", "2"); qs.add("line", "I/O"); String url = "https://www.youtube.com/watch?" + qs; System.out.println(url); } }
2. URLDecoder
URLDecoder는 x-www-form-url-encoded 형식으로 인코딩된 문자열을 디코딩하는 decode()메소드를 제공해준다. decode()는 인코딩 되지 않은 문자들은 디코드 해주지 않기때문에 URLEncode.encode()와는 다르게 모든 통 URL을 한번에 전달해서 처리 할 수 있다.
public static void main(String[] args) { /** * String decode(String s, String enc) : encode된 string을 decode해서 결과를 리턴한다. +는 스페이스로, %16진수는 원래 값으로 디코드 한다. */ try { String encodeUrl = "https://www.youtube.com/watch?&v=UhC7M8KF7AE&list=RDpIw7RAfYgI8&index=2&line=I%2FO"; String decodeUrl = URLDecoder.decode(encodeUrl, "UTF-8"); System.out.println("decodeUrl is " + decodeUrl); } catch (UnsupportedEncodingException e) { System.err.println(e); } }