본문 바로가기

Server Oriented/Java & JSP

URLDecoder: Incomplete trailing escape (%) pattern

.jsp 호출시 참여한 파라미터 값에 '%' 문자가 들어갔으면,

request.getParameter() 나 request.getgetParameterNames() 메소드 내부에서

"URLDecoderURLDecoder: Incomplete trailing escape (%) pattern" 예외 처리를 하고,

해당 파라미터 값에 null 을 세팅한다.

 

상기 메소드 외부로 throw Exception 을 하지 않으므로,

try ~ catch 문에도 상기 예외는 잡히지 않으며,

필요에 따라서 적절한 대응 코드를 넣어 주어야 함..

 

상기 예외 내용은 시스템 로그에 찍히지 않게 할 수 없음.

들리는 소문에 의하면 get 이나 post 방식의 차이로 시스템 로그가 찍히지 않게 할 수 있다는데..

이 부분은 잘 모르겠음. 시스템에 따라 약간씩 다른 느낌적인 느낌..?

 

다만, 해당 파라미터에 대한 값이 null 이기 때문에..

이에 대한 대응 처리를 고민해야 합니다.

사용자가 'abc%' 와 같이 % 가 포함된 문자열을 입력한 경우,

해당 파라미터 값은 'abc%' 도 'abc' 도 아닌 null 이 된다는 점을 잊지 말아야 함.

 

 

정말, 괘씸한 로직이네요.

시스템 로그를 찍지 말고, throw 를 하여 외부에서 처리하면 좋을텐데..

자기들 논리는 웹에서 흐르는 파라미터 정보를 예외처리해서

중간에 끊으면 자기들이 욕을 먹으니

이런 일이 있었다는 것을 알리기만 하고 나머지 정보는 그대로 처리한다는 건데.

그럴거면 왜 해당 파라미터 값을 null 로 세팅하는지.. ㅠ.

정보를 지들이 차단하는 건 정보 통제란 거임.

% 값이 들어오는데 분석해서 쓰건 말건 외부 로직이 알아서 해라 이렇게 해야지..

거기에 왜 null 값을 넣는거..

그러니까, 장황하게 설명은 했는데 결론은..

throw 는 하지 않더라도,

파라미터 값 만큼은 정확하게 전달해 달라는거.

 

 


<form name="frmBasic" type="post"><!-- 여기서 세팅한 post 는 $.ajax() 에서 세팅하는 type 에 의해 변경됨 -->

<input name="aa" value="str%">

</form>

 

상기와 같을 때, $.ajax() 호출시 호출하는 쪽은 a.jsp,

호출되는 쪽을 b.jsp 라고 하면..

b에서 request.getParameter() 를 하는 경우,

결과적으로 아래 1과 3/5/6 등에서는 정상적이고,

1번 또는 6번을 추천.

 

 

1. data:$('form[name="frmBasic"]').serialize() 로 하면, 오류 없이 정상적으로 작동.

type:'post' 와 type:'post' 상관없이 b.jsp 에서 getParameter() 값 str%.

a.jsp 에서 console.log(data) 를 찍어 보면 post 나 get 에 상관없이 'aa=str%25'.

인터넷을 통한 스트림에서 '%' 를 '%25' 로 바꾼 것. 익히 알듯이 %20 은 공백.
가장 간단한 방법이기에 추천.

b.jsp 에서 필요로 하는 파라미터 보다 a.jsp 의 form 안에 설정된 파라미터가 더 많다면,

불필요한 파라미터가 전달되어도 좋는지 고민할 필요가 있음.

 

2. data:'aa='+document.frmBasic.aa.value 로 하면,

type:'post' 일 때, 시스템 로그에 예외내용이 찍히고.. 더이상 진행 안 되고 멈춤.

type:'get' 이라면, 로그를 찍고 b.jsp 에서 getParameter() 값 null.

a.jsp 에서 post/get 모두 'aa=str%'. 이래서 에러 나는거.

재미있는 것은, post 일 때는 에러나고 화면이 멈추지만,

get 일 때는 에러가 나도 화면이 멈추지 않는다는 것.

post 일 때의 예외는, java.lang.NumberFormatException: For input string: "%".

get 일 때의 예외는, java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern

 

3. data:{'aa':'str%'} 로 하면,

type:'post' 이든 type:'post' 이든 b.jsp 에서 getParameter() 값 str%

a.jsp 에서 post/get 모두 json object 내용으로 찍는데, '{aa:"str%"}'.

데이타를 json 으로 관리하고 있다면 추천.

 

4. data:JSON.stringify({'aa':'str%'}) 로 하면,

post 일 때는 로그를 찍지 않고 getParameter() 값은 null,

get 일 때는 로그를 찍고 getParameter() 값은 null. 

a.jsp 에서 post/get 모두 문자열 내용으로 찍는데, '{"aa":"str%"}'.

get 일 때의 예외는,

java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: ""}"

 

5. data:'aa='+escape(document.frmBasic.aa.value) 로 하면,

type:'post' 과 type:'get' 모두, 시스템 로그 안 찍고 getParameter() 값 str%.

a.jsp 에서 post/get 모두 'aa=str%25'.

그런데, 파라미터가 여럿이면 일일이 이렇게 세팅하기 힘들어서 비추.

 

6. data:('aa='+document.frmBasic.aa.value).replace(/%/g,'%25') 로 하면,

type:'post' 과 type:'get' 모두, 시스템 로그 안 찍고 getParameter() 값 str%.

a.jsp 에서 post/get 모두 'aa=str%25'.

예전부터 해 오던 방식에, 문자열 변환 로직만 넣으면 되기 때문에 간편.

.serialize().replace(/%/g,'%25') 는 .serialize() 와 동일하므로 사용하지 않아요.

 

 

 

 

.Fine.