gpt4 book ai didi

java - 为什么 RestTemplate 不对 '+' 符号进行 urlencode,而是对其他所有内容进行 urlencode?

转载 作者:行者123 更新时间:2023-12-02 09:49:23 27 4
gpt4 key购买 nike

我发现了一个奇怪的问题,即 urlencoding 行为不一致。

更新

Spring MVC 4.3 和 5.1 版本之间存在差异:

// FAIL in MVC 4.x 
@Test
public void test2() {
rt.getForObject("http://localhost/expr={expr}", String.class, "x/y");
Assert.assertEquals("http://localhost/expr=x%2Fy", savedUri.toString());
}

// FAIL in MVC 4 or 5
@Test
public void test3() {
rt.getForObject("http://localhost/expr={expr}", String.class, "x+y");
Assert.assertEquals("http://localhost/expr=x%2By", savedUri.toString());
}

// ok in MVC 4.x, FAIL in MVC 5
@Test
public void test4() {
rt.getForObject("http://localhost/expr={expr}", String.class, "x+y");
Assert.assertEquals("http://localhost/expr=x+y", savedUri.toString());
}

这可能是 Spring MVC 更大重构的一部分,因为它也体现在完全不同的地方 here

问题详细信息

以下独立测试可以最好地说明我的问题。不要被 ClientHttpRequestFactory 吓到 - 重要的部分是最后 2 个测试方法。

package com.stackoverflow.questions;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;

import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.io.output.WriterOutputStream;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestTemplate;

public class RestTemplateTest {

StringWriter stringWriter = new StringWriter();

WriterOutputStream writerOutputStream = new WriterOutputStream(stringWriter);

HttpHeaders headers = new HttpHeaders();

URI savedUri;

ClientHttpRequestFactory rf = new ClientHttpRequestFactory() {
@Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
savedUri = uri;
return new ClientHttpRequest() {
@Override
public OutputStream getBody() throws IOException {
return writerOutputStream;
}

@Override
public HttpHeaders getHeaders() {
return headers;
}

@Override
public URI getURI() {
return uri;
}

@Override
public String getMethodValue() {
return httpMethod.name();
}

@Override
public ClientHttpResponse execute() throws IOException {

writerOutputStream.close();

return new ClientHttpResponse() {
@Override
public HttpHeaders getHeaders() {
return new HttpHeaders();
}

@Override
public InputStream getBody() throws IOException {
return new ReaderInputStream(new StringReader("test"));
}

@Override
public String getStatusText() throws IOException {
return "OK";
}

@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}

@Override
public int getRawStatusCode() throws IOException {
return 200;
}

@Override
public void close() {
}
};
}
};
}
};
RestTemplate rt = new RestTemplate(rf);

@Test
public void test1() {
String resp = rt.getForObject("http://whatever", String.class);
Assert.assertEquals("test", resp);
}

@Test
public void test2() {
rt.getForObject("http://localhost/expr={expr}", String.class, "x/y");
Assert.assertEquals("http://localhost/expr=x%2Fy", savedUri.toString());
}

@Test
public void test3() {
rt.getForObject("http://localhost/expr={expr}", String.class, "x+y");
Assert.assertEquals("http://localhost/expr=x%2By", savedUri.toString());
}

}

发生了什么:

  • 除法符号 / 已正确编码为 %2F - test2() 通过

  • 加法符号 + 未编码为 %2B - 它仍然是 + 并且 test3() 失败

应该发生什么:

test3() 应该通过。 + 应编码为 %2B,因为 + 是 URL 中的特殊字符,并且被许多服务器端 Web 框架解释为空格。

这里发生了什么?有通用的修复方法吗?

最佳答案

+ 是否应该编码尚不确定。旧的 RFC 说可以,新的 RFC 说可能。

尝试按如下方式设置编码模式:

  DefaultUriBuilderFactory builderFactory = new DefaultUriBuilderFactory();
builderFactory.setEncodingMode(EncodingMode.VALUES_ONLY);
restTemplate.setUriTemplateHandler(builderFactory);

参见SPR-19394SPR-20750供讨论。

关于java - 为什么 RestTemplate 不对 '+' 符号进行 urlencode,而是对其他所有内容进行 urlencode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56419684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com