RestTemplate使用@LoadBalanced报错:Request URI does not contain a valid hostname以及中文乱码问题

问题描述 :

在项目中调用restTemplate.postForObject发送异步通知给远程IP时,抛出异常:java.lang.IllegalStateException: Request URI does not contain a valid hostname,具体异常如下:

java.lang.IllegalStateException: Request URI does not contain a valid hostname: 
    at org.springframework.util.Assert.state(Assert.java:70)
    at org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor.intercept(RetryLoadBalancerInterceptor.java:102)
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:88)
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:72)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:388)
    at com.hengfupay.payment.task.NotifyTask.notifyResult(NotifyTask.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
    at java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

 问题所在:

发现在RestTemplate注册的时候,开启了客户端负载均衡功能,开启负载均衡很简单,只需要在RestTemplate的bean上再添加一个@LoadBalanced注解即可。代码如下:

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

但是开启负载均和后,RestTemplate不能对远程IP发起请求。

问题解决:

所以在注册的时候可以注册两个不同的RestTemplate,比如:

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public RestTemplate commRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }

restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));这行代码是为了防止restTemplate在请求中出现中文乱码,把编码格式设置为UTF-8格式。

之后在对外部远程IP地址发起请求的时候,可以注入commRestTemplate:

    @Autowired
    private RestTemplate commRestTemplate;

再用commRestTemplate来发起请求,问题解决。

你可能感兴趣的:(Java,微服务)