Я пытаюсь с тем же кодом. Я не получаю эту ошибку. Spring boot version: 1.5.0.RELEASE
Вместо POST я попробовал использовать GET API с тем же шаблоном URL. /
в конце пути не имеет значения.
@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);
}
}
У меня все отлично работает. [1110 ]
Журнал:
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
Звоните ToArray
дополнительный метод на IEnumerable<T>
, это делает почти то же как ниже, выполняя сниффинг типа и некоторую другую оптимизацию.
Вообще говоря, использование a List<T>
который будет инициализирован с IEnumerable<T>
и затем вызов ToArray
вероятно, самый легкий способ сделать это.
Конструктор для List<T>
проверит IEnumerable<T>
видеть, реализует ли это ICollection<T>
заставить количество объектов правильно инициализировать способность списка. В противном случае это расширится как нормальное.
Конечно, Вы могли бы закончить тем, что создали много List<T>
экземпляры только в целях преобразования IEnumerable<T>
кому: T[]
. С этой целью можно записать собственный метод, но Вы действительно просто копировали бы код, который существует в List<T>
уже.
При выполнении небольшого Отражателя.NET, на который это похоже, метод расширения Linq ToArray в основном делает то же самое как передачу IEnumerable через Список <>. Буферный класс является внутренним, но поведение кажется очень похожим на Список <>.
public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
Buffer<TSource> buffer = new Buffer<TSource>(source);
return buffer.ToArray();
}
Если нет никакого способа определить длину массива, то это - лучший способ.
Нет ничего в IEnumerable, который позволит Вам определить длину, но возможно Ваш код имеет способ узнать иначе. Если так, используйте это для построения массива.