【问题标题】:How to pass List or String array to getForObject with Spring RestTemplate如何使用 Spring RestTemplate 将 List 或 String 数组传递给 getForObject
【发布时间】:2014-04-25 18:32:46
【问题描述】:

我正在使用 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";

Web 服务客户端代码:

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,我认为长的位置信息字符串会导致这个问题。那么,我该如何解决这个问题呢?或者是否可以将长字符串值作为参数发布到 Web 服务?

谢谢大家

【问题讨论】:

    标签: java spring web-services resttemplate


    【解决方案1】:

    列表或其他类型的对象可以使用 RestTemplate 的 postForObject 方法发布。我的解决方案如下:

    控制器:

    @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
    

    【讨论】:

      【解决方案2】:

      问题与GET 资源有关,而不是POST。因此,我认为“接受的答案”不是正确的。

      所以对于像我这样的其他 google 人发现这个,我会添加对我有帮助的内容:

      GET 资源可以通过@PathVariable@RequestParam 接收字符串列表,如果您确实传递了由, 分隔的列表,甚至可以正确地将其绑定到List&lt;String&gt;

      您的 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 无法将其识别为列表。此外,您不能直接将列表添加为参数,因为根据它的编组方式,生成的字符串可能不兼容。

      【讨论】:

        【解决方案3】:

        首先,您已将地图作为参数传递,但您的控制器希望这些作为路径变量。您需要做的就是将“pointlist”值作为 URL 的一部分(没有大括号占位符)。例如:-

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

        接下来,您需要确保已设置消息转换器,以便将 LocationInfoObject 编组为适当的表示(建议 JSON)并以相同的方式解组。

        对于其余模板:

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

        对于服务器,您只需将 Jackson 添加到类路径中(如果您想要多个表示,您需要手动配置每个 - Google 也将成为您的朋友。

        【讨论】:

          猜你喜欢
          • 2020-07-23
          • 2012-12-02
          • 2015-11-20
          • 2018-01-16
          • 2015-07-02
          • 2014-04-06
          • 1970-01-01
          • 2013-11-25
          • 2019-12-21
          相关资源
          最近更新 更多