Как передать массив 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 также будет вашим другом здесь.

Другие вопросы по тегам