Как передать массив 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, я думаю, что длинная строка информации о местоположении вызывает эту проблему. Итак, как я могу решить эту проблему? Или можно отправить длинное строковое значение в качестве параметра веб-службы?

Спасибо всем


person vtokmak    schedule 19.03.2014    source источник


Ответы (3)


Список или другие типы объектов могут публиковаться с помощью метода 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
person vtokmak    schedule 27.03.2014

Вопрос относится к ресурсу 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 не сможет распознать их как список. Также вы не можете просто добавить свой список напрямую в качестве параметра, потому что в зависимости от того, как он составлен, сгенерированная строка может быть несовместимой.

person Jouberto Fonseca    schedule 04.06.2020

Сначала вы передали карту как параметры, но ваш контроллер ожидает их как переменную пути. Все, что вам нужно сделать, это сделать значение 'pointlist' частью URL-адреса (без заполнителей фигурных скобок). например.:-

http://api.website.com/service/getLocationInformations/pointList

Затем вам нужно убедиться, что у вас настроены преобразователи сообщений, чтобы ваш объект LocationInfoObject сортировался в соответствующее представление (предлагайте JSON) и демаршалировался таким же образом.

Для шаблона отдыха:

restTemplate.setMessageConverters(...Google MappingJackson2HttpMessageConverter...);

Для сервера вам просто нужно добавить Джексона в путь к классам (если вам нужно несколько представлений, вам нужно будет настроить каждое из них вручную — Google и здесь будет вашим другом.

person user1016765    schedule 24.03.2014