I have a RestTemplate
that I build it with RestTemplateBuilder
. I set the rootUri for builder. In below method (updateState1) sometimes I got the "URI is not absolute" error. For example when I called this method concurrently for 2 times I often got 1 error.
EDIT and Solution: I use this RestTemplate
in service task of camunda process. I launch this project in kubernetes container that has different timezone with the oracle database. When I add timezone variable every things work fine.
Spring boot version: 2.1.1.RELEASE
Here is my code:
@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);
}
}
cuase (stacktrace):
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
Remove /
in root:
private static final String root = "http://localhost:8080/test/api";
RestTemplate accepts uriTemplate as long as they start with /
so your root should be without it. if it doesn't start with /
it will consider it as a full URL
I try with the same code. I do not get this error. Spring boot version: 1.5.0.RELEASE
Instead of POST, I tried with a GET API with same URL pattern. The /
at the end of the path does not matter.
@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);
}
}
}
I added a dummy controller with the same path:
@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);
}
}
To test, I added another controller:
@RestController
@RequestMapping("/client")
public class CoreServiceClientController {
@Autowired
private CoreServiceClient client;
@GetMapping
public ResponseEntity<String> goGet() {
client.updateState("1001");
return new ResponseEntity<>("HELLO", HttpStatus.OK);
}
}
Everything works fine for me.
Log:
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