具有rootUri返回URI的Spring RestTemplate不是绝对错误

时间:2019-01-15 20:33:09

标签: java spring kubernetes resttemplate camunda

我有一个RestTemplateRestTemplateBuilder构建。我为构建器设置了rootUri。在下面的方法(updateState1)中,有时会出现“ URI不是绝对的”错误。例如,当我同时调用此方法2次时,经常会出现1个错误。

编辑和解决方案: 我在camunda流程的服务任务中使用此RestTemplate。我在与Oracle数据库具有不同时区的kubernetes容器中启动该项目。当我添加时区变量时,一切正常。

春季启动版本:2.1.1.RELEASE

这是我的代码:

@Component
@Slf4j
public class CoreServiceClient {

    private RestTemplate restTemplate;

    private static final String root = "http://localhost:8080/test/api/";

    public CoreServiceClient(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder.rootUri(root).build();
    }


    public void updateState1(UpdateParam updateParam) {
        HttpHeaders headers = generateHeader();
        UpdateRequest updateRequest = new UpdateRequest(updateParam.getState());

        HttpEntity<UpdateRequest> httpEntity = new HttpEntity<>(updateRequest, headers);

        ResponseEntity<String> response = restTemplate.exchange(
                "/food/{id}/state",
                HttpMethod.PUT, httpEntity, String.class, updateParam.getId());

    }
    public void updateState2(String id) {
        HttpHeaders headers = generateHeader();
        UpdateRequest updateRequest = new UpdateRequest("done");

        HttpEntity<UpdateRequest> httpEntity = new HttpEntity<>(updateRequest, headers);

        ResponseEntity<String> response = restTemplate.exchange(
                "/food/{id}/state",
                HttpMethod.PUT, httpEntity, String.class, id);

    }
}

原因(堆栈跟踪):

Caused by: java.lang.IllegalArgumentException: URI is not absolute
    at java.net.URI.toURL(URI.java:1088)
    at org.springframework.http.client.SimpleClientHttpRequestFactory.createRequest(SimpleClientHttpRequestFactory.java:145)
    at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:87)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:730)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:669)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:578)
    at com.test.client.CoreServiceClient.updateState(CoreServiceClient.java:39)
    at sun.reflect.GeneratedMethodAccessor263.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.camunda.bpm.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:479)
    ... 85 more

2 个答案:

答案 0 :(得分:1)

从根目录删除/

private static final String root = "http://localhost:8080/test/api";

RestTemplate接受uriTemplate,只要它们以/开头,因此您的根目录应该没有它。如果它不是以/开头,则会将其视为完整的URL

答案 1 :(得分:1)

我尝试使用相同的代码。我没有得到这个错误。 春季启动版本:1.5.0.RELEASE

我尝试使用具有相同URL模式的GET API而不是POST。 路径末尾的/无关紧要。

@Component
public class CoreServiceClient {
    private RestTemplate restTemplate;

    private static final Logger LOGGER = LoggerFactory.getLogger(CoreServiceClient.class);
    private static final String root = "http://localhost:8080/test/api/";

    public CoreServiceClient(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder.rootUri(root).build();
    }


    public void updateState(String id) {

        try {
            ResponseEntity<String> response =
                    restTemplate.exchange("/food/{id}/state", HttpMethod.GET, null, String.class, id);
            LOGGER.info("Resp: {}", response.getStatusCode());
            LOGGER.info("Resp: {}", response.getBody());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }


    }
}

我添加了一个具有相同路径的虚拟控制器:

@RestController
@RequestMapping("/test/api")
public class FooController {

    @GetMapping("/food/{id}/state")
    public ResponseEntity<String> fooState(@PathVariable String id) {
        return new ResponseEntity<String>("EATING", HttpStatus.OK);
    }
}

为了测试,我添加了另一个控制器:

@RestController
@RequestMapping("/client")
public class CoreServiceClientController {

    @Autowired
    private CoreServiceClient client;

    @GetMapping
    public ResponseEntity<String> goGet() {
        client.updateState("1001");
        return new ResponseEntity<>("HELLO", HttpStatus.OK);
    }
}

一切对我都很好。

日志:

2019-01-15 23:23:19.870  INFO 22570 --- [nio-8080-exec-1] com.example.demo001.CoreServiceClient    : Resp: 200
2019-01-15 23:23:19.871  INFO 22570 --- [nio-8080-exec-1] com.example.demo001.CoreServiceClient    : Resp: EATING