Как передать массив List или String в getForObject с помощью Spring RestTemplate
Я разрабатываю некоторые успокоительные услуги с Spring. У меня проблемы с передачей / получением массива строк или большой строки в качестве параметров моего сервисного контроллера. Мои примеры кода, как показано ниже;
контроллер:
@RequestMapping(value="/getLocationInformations/{pointList}", method=RequestMethod.GET)
@ResponseBody
public LocationInfoObject getLocationInformations(@PathVariable("pointList") String pointList)
{
// code block
}
Пример списка точек:
String pointList = "37.0433;35.2663,37.0431;35.2663,37.0429;35.2664,37.0428;35.2664,37.0426;35.2665,37.0424;35.2667,37.0422;35.2669,37.042;35.2671,37.0419;35.2673,37.0417;35.2674,37.0415;35.2674,37.0412;35.2672,37.0408;35.267,37.04;35.2667,37.0396;35.2665,37.0391;35.2663,37.0388;35.2662,37.0384;35.266,37.0381;35.2659,37.0379;35.2658,37.0377;35.2657,37.0404;35.2668,37.0377;35.2656,37.0378;35.2652,37.0378;35.2652,37.0381;35.2646,37.0382;35.264,37.0381;35.2635,37.038;35.263,37.0379;35.2627,37.0378;35.2626,37.0376;35.2626,37.0372;35.2627,37.0367;35.2628,37.0363;35.2628,37.036;35.2629,37.0357;35.2629,37.0356;35.2628,37.0356;35.2628,37.0355;35.2626";
Код клиента веб-сервиса:
Map<String, String> vars = new HashMap<String, String>();
vars.put("pointList", pointList);
String apiUrl = "http://api.website.com/service/getLocationInformations/{pointList}";
RestTemplate restTemplate = new RestTemplate();
LocationInfoObject result = restTemplate.getForObject(apiUrl, LocationInfoObject.class, vars);
Когда я запускаю клиентское приложение, оно выдает HttpClientErrorException: 400 Bad Request
Я думаю, что длинная строка информации о местоположении вызывает эту проблему. Итак, как я могу решить эту проблему? Или возможно разместить длинное строковое значение в качестве параметра в веб-сервисе?
Спасибо всем
2 ответа
Список или другой тип объектов можно публиковать с помощью метода postForObject RestTemplate. Мое решение, как показано ниже:
контроллер:
@RequestMapping(value="/getLocationInformations", method=RequestMethod.POST)
@ResponseBody
public LocationInfoObject getLocationInformations(@RequestBody RequestObject requestObject)
{
// code block
}
Создайте объект запроса для публикации в сервисе:
public class RequestObject implements Serializable
{
public List<Point> pointList = null;
}
public class Point
{
public Float latitude = null;
public Float longitude = null;
}
Создайте объект ответа для получения значений из сервиса:
public class ResponseObject implements Serializable
{
public Boolean success = false;
public Integer statusCode = null;
public String status = null;
public LocationInfoObject locationInfo = null;
}
Разместите список точек с объектом запроса и получите объект ответа от сервиса:
String apiUrl = "http://api.website.com/service/getLocationInformations";
RequestObject requestObject = new RequestObject();
// create pointList and add to requestObject
requestObject.setPointList(pointList);
RestTemplate restTemplate = new RestTemplate();
ResponseObject response = restTemplate.postForObject(apiUrl, requestObject, ResponseObject.class);
// response.getSuccess(), response.getStatusCode(), response.getStatus(), response.getLocationInfo() can be used
Вопрос связан с GET
ресурс, а не POST
. По этой причине я считаю, что "принятый ответ" - неправильный.
Поэтому для других гуглеров, которые находят это, я добавлю то, что мне помогает:
GET
ресурсы могут получить список строк через @PathVariable
или @RequestParam
и даже правильно привязать его к List<String>
если вы передадите список, разделенный ,
.
Ваш API может быть:
@RequestMapping(value="/getLocationInformations/{pointList}", method=RequestMethod.GET)
@ResponseBody
public LocationInfoObject getLocationInformations(@PathVariable("pointList") List<String> pointList) {
// code block
}
И ваш звонок будет таким:
List<String> listOfPoints = ...;
String points = String.join(",", listOfPoints);
String apiUrl = "http://api.website.com/service/getLocationInformations/{pointList}";
LocationInfoObject result = restTemplate.getForObject(apiUrl, LocationInfoObject.class, points);
Обратите внимание, что вы должны отправлять списки в API, используя ,
в качестве разделителя, иначе API не сможет распознать его как список. Также вы не можете просто добавить свой список напрямую в качестве параметра, потому что в зависимости от того, как он обрабатывается, сгенерированная строка может быть несовместимой.
Сначала вы передали карту в качестве параметров, но ваш контроллер ожидает их как переменную пути. Все, что вам нужно сделать, это сделать значение 'pointlist' частью URL (без заполнителей в фигурных скобках). например:-
http://api.website.com/service/getLocationInformations/pointList
Затем вы должны убедиться, что у вас настроены конвертеры сообщений, чтобы ваш LocationInfoObject был преобразован в соответствующее представление (например, JSON) и распакован таким же образом.
Для шаблона отдыха:
restTemplate.setMessageConverters(...Google MappingJackson2HttpMessageConverter...);
Для сервера вам просто нужно добавить Джексона в путь к классам (если вам нужно несколько представлений, вам нужно будет настроить каждое из них вручную - Google также будет вашим другом здесь.