restTemplate禁用url编码

restTemplate禁用url编码

在restTemplate调用方法的时候默认对url做了编码处理
  • 如果路径里面带了参数,url?param={"name":"张三","age":22}
  • 这时这处理url的时候就要先对json数据进行编码处理
url?param=%7B%22name%22%3A%22%E5%BC%A0%E4%B8%89%22%EF%BC%8C%22age%22%3A22%7D
  • 这时使用restTemplate调用接口,会对url再次编码成
url%3Fparam%3D%257B%2522name%2522%253A%2522%25E5%25BC%25A0%25E4%25B8%2589%2522%25EF%25BC%258C%2522age%2522%253A22%257D
  • 接口放接收到路径解码后
url?param=%7B%22name%22%3A%22%E5%BC%A0%E4%B8%89%22%EF%BC%8C%22age%22%3A22%7D

并不是url?param={"name":"张三","age":22}

  • 我们想要的结果并不想restTemplate调用的时候二次编码,而是使用我们的url
查询看restTemplate源码
  • postForObject方法
	@Override
	@Nullable
	public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
			Object... uriVariables) throws RestClientException {

		RequestCallback requestCallback = httpEntityCallback(request, responseType);
		HttpMessageConverterExtractor<T> responseExtractor =
				new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
		return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
	}
  • 跟进去到execute方法,可以看到对url做了处理
	@Override
	@Nullable
	public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
			@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {
        // 对url做了处理
		URI expanded = getUriTemplateHandler().expand(url, uriVariables);
		return doExecute(expanded, method, requestCallback, responseExtractor);
	}
  • restTemplate默认的url模版,restTemplate的无参构造函数
	public RestTemplate() {
		this.messageConverters.add(new ByteArrayHttpMessageConverter());
		this.messageConverters.add(new StringHttpMessageConverter());
		this.messageConverters.add(new ResourceHttpMessageConverter(false));
		try {
			this.messageConverters.add(new SourceHttpMessageConverter<>());
		}
		catch (Error err) {
			// Ignore when no TransformerFactory implementation is available
		}
		this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());

		if (romePresent) {
			this.messageConverters.add(new AtomFeedHttpMessageConverter());
			this.messageConverters.add(new RssChannelHttpMessageConverter());
		}

		if (jackson2XmlPresent) {
			this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
		}
		else if (jaxb2Present) {
			this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
		}

		if (jackson2Present) {
			this.messageConverters.add(new MappingJackson2HttpMessageConverter());
		}
		else if (gsonPresent) {
			this.messageConverters.add(new GsonHttpMessageConverter());
		}
		else if (jsonbPresent) {
			this.messageConverters.add(new JsonbHttpMessageConverter());
		}

		if (jackson2SmilePresent) {
			this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
		}
		if (jackson2CborPresent) {
			this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
		}
        // 默认的url处理器
		this.uriTemplateHandler = initUriTemplateHandler();
	}
  • 默认模版
	private static DefaultUriBuilderFactory initUriTemplateHandler() {
		DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();
		uriFactory.setEncodingMode(EncodingMode.URI_COMPONENT);  // for backwards compatibility..
		return uriFactory;
	}
  • URI_COMPONENT 枚举值的解释
		/**
		 * Expand URI variables first, and then encode the resulting URI
		 * component values, replacing <em>only</em> non-ASCII and illegal
		 * (within a given URI component type) characters, but not characters
		 * with reserved meaning.
		 * @see UriComponents#encode()
		 */
		URI_COMPONENT
禁用restTemplate对url编码
    @Bean
    public RestTemplate restTemplateNoEncode(RestTemplateBuilder builder) {
        RestTemplate build = builder.build();
        DefaultUriBuilderFactory defaultUriBuilderFactory = new DefaultUriBuilderFactory();
        // 不对url进行编码
        defaultUriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
        build.setUriTemplateHandler(defaultUriBuilderFactory);
        return build;
    }
在代码中定义多个restTemplate
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        RestTemplate build = builder.build();
        List<HttpMessageConverter<?>> messageConverters = build.getMessageConverters();
        messageConverters.add(new CustomJacksonHttpMessageConverter());
        return build;
    }

    @Bean
    public RestTemplate restTemplateNoEncode(RestTemplateBuilder builder) {
        RestTemplate build = builder.build();
        DefaultUriBuilderFactory defaultUriBuilderFactory = new DefaultUriBuilderFactory();
        defaultUriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);
        List<HttpMessageConverter<?>> messageConverters = build.getMessageConverters();
        messageConverters.add(new CustomJacksonHttpMessageConverter());
        build.setUriTemplateHandler(defaultUriBuilderFactory);
        return build;
    }
}

  • 使用的时候使用@Qualifier指定名称就可以
    @Autowired
    @Qualifier("restTemplateNoEncode")
    private RestTemplate restTemplate;
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值