2017-01-01 7 views
0

charset을 사용하여 전달 된 값에 대한 URL 디코딩을 수행하는 아래의 메소드가 있습니다.는 재귀 적으로 메소드를 호출하지만 두 번째에만 로그합니까?

value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); 
value = value.replaceAll("\\+", "%2B"); 
value = URLDecoder.decode(value, charset.name()); 

그리고 다시 URLDecoder.decode 라인이 예외를 두 번 발생하면, 그때가를 기록합니다 URLDecoder.decode 라인은 내가 세 줄 아래에 같은 value를 실행하려면 다음 UnsupportedEncodingException 처음 발생하는 경우 이제

public String decodeValue(String value, Charset charset) { 
    if (!Strings.isNullOrEmpty(value)) { 
     try { 
     value = URLDecoder.decode(value, charset.name()); 
     } catch (UnsupportedEncodingException ex) { 
     // log error 
     return null; 
     } 
    } 
    return value; 
    } 

오류가 있지만 두 번째 시간 및 반환 널 값 그렇지 않으면 디코딩 된 값을 반환합니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

+0

이 작업을 수행 할 방법이나 가장 멋진 솔루션을 찾고 있습니까? – shmosel

+0

내가 이미 알고있는 다른 try/catch 블록을 추가 중입니다. 나는 그것이 있으면 더 좋은 방법이나 우아한 방법을 찾고있었습니다. –

+1

거부 ​​된 것으로 보이는 수정 사항을 제안했습니다. 여기서 재귀는 어디입니까? –

답변

1

가장 쉬운 방법은 여분의 플래그가 포함 된 개인 서명의 함수 서명을 만드는 것입니다.

private String decodeValue(String value, Charset charset, boolean isFirstTime) { 
    if (!Strings.isNullOrEmpty(value)) { 
     try { 
     value = URLDecoder.decode(value, charset.name()); 
     } catch (UnsupportedEncodingException ex) { 
     if (isFirstTime) { 
      value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); 
      value = value.replaceAll("\\+", "%2B"); 
      return decodeValue(value, charset.name(), false); 
     } else { 
      // log error 
      return null; 
     } 
     } 
    } 
    return value; 
    } 

그런 다음, 바로 재귀 호출에 true 처음과 false를 전달합니다. 함수 내에서 true이 전달되면 다음 세 행만 실행하십시오.

공용 버전은 true을 전달할 수 있습니다. 여기

public String decodeValue(String value, Charset charset) { 
     decodeValue(value, charset, true); 
    } 
+0

이 서명을 비공개로 만들 것입니다. – shmosel

+0

@ merlin2011이 부울 변수를 사용하여 세 줄을 실행하고 로깅을 수행하는 방법은 무엇입니까? 약간 혼란스러워서 어떻게 작동하는지 예제를 제공해 줄 수 있습니까? –

+0

당신이 내 디코드 메서드와'URLDecoder.decode' 메서드를 알려주는 두 가지 방법이 있습니다. 내 질문을 업데이트하여 메서드 이름을 변경했습니다. 귀하의 경우, 해당 매개 변수를 사용하지 않는 URLDecoder 메서드에 false를 전달하고 있습니다. –

0

당신은 이동 :

public String decode(String value, Charset charset) { 
    if (!Strings.isNullOrEmpty(value)) { 
     try { 
     value = URLDecoder.decode(value, charset.name()); 
     } catch (UnsupportedEncodingException ex) { 
     try { 
     value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); 
     value = value.replaceAll("\\+", "%2B"); 
     value = URLDecoder.decode(value, charset.name()); 
     } catch (UnsupportedEncodingException ex) { 
     // log error 
     return null; 
     } 
     } 
    } 
    return value; 
    } 

희망이 당신의 문제를 해결합니다.

+1

그리고 코드가 중복됩니다. 그것은 대개 좋은 생각이 아닙니다. – GhostCat

+0

서식을 수정하십시오. – shmosel

0

플래그를 추가하면 옵션입니다. 예, 더 쉬운 방법입니다. 많은 사람들은 플래그을 가지고 있다고 간단하게 말합니다 : 나쁜 습관.

당신은 그저 최소화하려고합니다.

다른 말로하면 : 과 다르게 첫 번째 및 후속 호출에 대해을 수행해야하는 메서드가있는 경우; 거기에 두 개의 메서드를 만드는 것을 고려하십시오. 물론, 가능한 한 코드 복제를 피할 수 있지만, 비용이 많이 드는 것이 아닌 한 그런 플래그 인수를 피하는 것도 고려해야합니다.

+0

여기서 두 가지 다른 메서드를 사용할 수있는 방법과 예외가 throw되는 시점에 따라 호출 할 대상을 지정하고이를 정상적으로 호출하는 방법에 대한 예제를 제공 할 수 있습니까? –

1

재귀 적은 아니지만 while 루프와 플래그를 사용할 수 있습니다. 여기

public String decode(String value, Charset charset) { 
    boolean first = true; 
    while(!Strings.isNullOrEmpty(value)) { 
     try { 
      return value = URLDecoder.decode(value, charset); 
     } catch (UnsupportedEncodingException e) { 
      if(first == false) { 
       // Log error. 
       return null; 
      } 
      value = value.replaceAll("%(?![0-9a-fA-F]{2})", "%25").replaceAll("\\+", "%2B"); 
     } 
     first = false; 
    } 
    return value; 
} 
0

여분의 플래그없이 버전, 중복 코드, 재귀이며, 루프 : 여기

public String decodeValue(final String value, Charset charset) throws UnsupportedEncodingException { 
    String result; 
    if (!Strings.isNullOrEmpty(value)) { 
     UnsupportedEncodingException[] lastException = new UnsupportedEncodingException[1]; 
     result = Stream.<Function<String, String>>of(
       Function.identity(), 
       s -> { 
        s = s.replaceAll("%(?![0-9a-fA-F]{2})", "%25"); 
        s = s.replaceAll("\\+", "%2B"); 
        return s; 
       }) 
       .map(f -> f.apply(value)) 
       .map(appliedValue -> { 
        try { 
         return URLDecoder.decode(appliedValue, charset.name()); 
        } catch (UnsupportedEncodingException e) { 
         lastException[0] = e; 
         return null; 
        } 
       }) 
       .filter(Objects::nonNull) 
       .findFirst() 
       .orElseThrow(() -> lastException[0]); 
    } 
    return result; 
} 

난 그냥이 개 기능 스트림을 : 정체성과 기능 만들기 문자열 보정을. 그런 다음이 함수를 초기 문자열에 적용하고 디코딩을 시도합니다. 처음 시도가 성공하면 코드는 수정 기능을 적용하지 않고 올바른 결과 만 반환합니다. 값을 수정 한 후에 디코더가 예외를 throw하면 "findFirst"는 값을 찾지 않습니다. 그런 다음 우리는 마지막으로 잡힌 예외를 던집니다.

+0

Java7에서 예제를 제공 할 수 있습니까? 지금 Java 8을 사용할 수 없습니다. 자바 7에서 여분의 플래그, 코드 중복을 피할 수 있다면 좋을 것입니다. 지금까지 나는 그런 대답을 얻지 못했습니다. –

+0

이 경우 Mattew의 솔루션이 바람직합니다. –