복붙노트

[SPRING] 애플리케이션 / json에서 Spring 디코딩 + (더하기 문자)가 요청을받는 이유는 무엇입니까? 어떻게해야합니까?

SPRING

애플리케이션 / json에서 Spring 디코딩 + (더하기 문자)가 요청을받는 이유는 무엇입니까? 어떻게해야합니까?

http : // localhost / foo? email=foo+bar@example.com과 같은 요청을받는 Spring 응용 프로그램이 있습니다. 이것은 대략 다음과 같은 컨트롤러를 트리거합니다.

@RestController
@RequestMapping("/foo")
public class FooController extends Controller {
    @GetMapping
    public void foo(@RequestParam("email") String email) {
       System.out.println(email)
    }
}

이메일에 액세스 할 수있게되면 원래 foo+bar@example.com 대신 foo bar@example.com으로 변환되었습니다. 공백을 플러스 (+) 또는 % 20으로 인코딩하는시기에 따르면? 이는 컨텐츠가 application / x-www-form-urlencoded 인 요청에서만 발생합니다. 내 요청에는 application / json의 콘텐츠 유형이 있습니다. 요청의 전체 MIME 헤더는 다음과 같습니다.

=== MimeHeaders ===
accept = application/json
content-type = application/json
user-agent = Dashman Configurator/0.0.0-dev
content-length = 0
host = localhost:8080
connection = keep-alive

왜 Spring이 플러스를 공백으로 디코딩합니까? 이것이 이것이 작동하는 방식이라면 왜 요청을 할 때 인코딩 플러스가 % 2B로 표시되지 않습니까?

나는이 버그 보고서를 발견했다 : https://jira.spring.io/browse/SPR-6291 이것은 버전 3.0.5에서 수정되었으며 Spring> 5.0.0을 사용하고 있음을 암시 할 수 있습니다. 버그 보고서에 대해 잘못 해석했을 수 있습니다.

또한 이러한 값의 RestTemplate 처리에 대한이 토론을 찾았습니다.

내 질문은 왜 Spring이 이것을하고 있습니까? 어떻게 비활성화합니까? 요청이 json 인 경우에도 비활성화해야합니까, 아니면 클라이언트에서 플러스를 인코딩해야합니까?

명확히하기 위해, 나는 여기 어디에도 HTML이나 JavaScript를 사용하지 않습니다. 스프링 레스트 컨트롤러가 있으며 클라이언트는 UriTemplate 또는 UriComponentsBuilder가 포함 된 Spring의 RestTemplate입니다. 둘 중 어느 것도 Spring이 디코딩하는 방식으로 더하기 부호를 인코딩하지 않습니다.

해결법

  1. ==============================

    1.원래 답변

    원래 답변

    요청의 본문에서 +는 헤더에 application / x-www-form-urlencoded가있을 때 공백을 의미하는 두 가지를 혼합합니다. 요청의 본문 또는 내용은 헤더에 의존하지만 요청에는 URL과 헤더가없고 본문이 없을 수 있습니다.

    따라서 URI 인코딩은 헤더로 제어 할 수 없습니다

    https://en.wikipedia.org/wiki/Query_string의 URL 인코딩 섹션을 참조하십시오.

    그리고 아래 스크린 샷에서 google.com과 동일한 동작을 볼 수 있습니다

    또한 다른 프레임 워크에서도 동일한 동작을 볼 수 있습니다. 아래는 Python Flask의 예입니다

    그래서 당신이보고있는 것이 맞습니다, 당신은 URL이 아닌 요청의 본문 내용을 참조하는 문서와 비교하고 있습니다.

    편집 -1 : 5 월 22 일

    디버깅 후 봄에는 디코딩이 발생하지 않는 것 같습니다. 패키지 org.apache.tomcat.util.buf에서 발생합니다. 그리고 UDecode 클래스

    /**
     * URLDecode, will modify the source.
     * @param mb The URL encoded bytes
     * @param query <code>true</code> if this is a query string
     * @throws IOException Invalid %xx URL encoding
     */
    public void convert( ByteChunk mb, boolean query )
        throws IOException
    {
        int start=mb.getOffset();
    

    아래는 변환 작업이 실제로 발생하는 위치입니다.

        if( buff[ j ] == '+' && query) {
            buff[idx]= (byte)' ' ;
        } else if( buff[ j ] != '%' ) {
    

    이것은이 번역을 수행하는 내장형 Tomcat 서버이며 스프링은 이것에도 참여하지 않는다는 것을 의미합니다. 클래스 코드에서 볼 수 있듯이이 동작을 변경하는 구성은 없습니다. 그래서 당신은 그것으로 살아야합니다

  2. ==============================

    2.SPR-6291은 v3.0.5에서이 문제를 해결했지만 SPR-11047과 같은 일부 다른 경우에는 여전히 해결되지 않은 상태로 남아 있습니다. SPR-6291의 우선 순위는 주이지만 SPR-11047의 우선 순위는 부입니다.

    SPR-6291은 v3.0.5에서이 문제를 해결했지만 SPR-11047과 같은 일부 다른 경우에는 여전히 해결되지 않은 상태로 남아 있습니다. SPR-6291의 우선 순위는 주이지만 SPR-11047의 우선 순위는 부입니다.

    작년에 지난 봄에 REST API를 작업 할 때이 문제에 직면했습니다. 스프링 컨트롤러에서 데이터를 얻는 방법에는 여러 가지가 있습니다. 둘 중 하나는 @RequestParam 또는 @PathVariable 주석을 통해 이루어집니다

    다른 사람들이 언급했듯이 스프링의 내부 문제라고 생각하며 POST 요청을 통해 데이터를 전송했기 때문에 URL 인코딩에 속하지 않지만 다소 인코딩 문제입니다. 그러나 URL에 문제가 남아 있으므로 다른 사람들도 동의합니다.

    그래서 내가 아는 두 가지 해결책이 있습니다.

    귀하의 경우 JS를 통해 필드를 가져오고 요청을 보내기 전에 더하기 부호를 이스케이프 처리 할 수 ​​있습니다. 이 같은:

    var email = document.getElementById("emailField").value;
    email = email.replace('+', '%2B');
    
  3. ==============================

    3.이 요청이있는 경우 :

    이 요청이있는 경우 :

    http://localhost/foo?email=foo+bar@example.com
    

    원본은 foo bar@example.com입니다. 원본이 foo+bar@example.com이어야한다면 요청은 다음과 같아야합니다.

    http://localhost/foo?email=foo%2Bbar@example.com
    

    그래서 Spring은 예상대로 작동합니다. 클라이언트에서는 URI가 올바르게 인코딩되어 있는지 확인해야합니다. 클라이언트 측 URL 인코딩은 올바른 HTTP 요청을 작성합니다.

    JavaScript에서 요청을 생성하는 경우 encodeURI ()를 참조하고 Spring에서 요청을 생성하는 경우 uriToString ()을 참조하십시오.

    foo+bar@email.com과 같은 인코딩되지 않은 값을 사용하여 인코딩없이 요청 문자열 (? 뒤에 나오는 부분)을 빌드하고 실제로는 GET에서 실제로 사용하기 전에 클라이언트 플랫폼. POST를 사용하려면 선택한 MIME 유형에 따라 POST를 인코딩해야합니다.

  4. from https://stackoverflow.com/questions/50270372/why-is-spring-de-coding-the-plus-character-on-application-json-get-requests by cc-by-sa and MIT license