【问题标题】:How can you pass an array in a POST with Spring RestTemplate?如何使用 Spring RestTemplate 在 POST 中传递数组?
【发布时间】:2013-11-25 05:46:58
【问题描述】:

我在使用 Spring 的 RestTemplate 在 POST 中传递数组时遇到了困难。以下是我正在使用的代码:

我在这里调用 RestTemplate:

private static void sendEntries() {
    RestTemplate restTemplate = new RestTemplate();
    String uri = "http://localhost:8080/api/log/list.json";

    // Both LogEntry and ExceptionEntry extend Entry
    LogEntry entry1 = new LogEntry();
    ExceptionException entry2 = new ExceptionEntry();

    Entry[] entries = {entry1, entry2};

    entries = restTemplate.postForObject(uri, entries, Entry[].class);

    System.out.println(new Gson().toJson(entries));
}

控制器包含:

@RequestMapping(value = "api/log/list", method = RequestMethod.POST)
public @ResponseBody Entry[] saveList(@RequestBody Entry[] entries) {
    for (Entry entry : entries) {
        entry = save(entry);
    }

    return entries;
}

这会导致:

org.springframework.web.client.HttpClientErrorException: 400 Bad Request

看起来该数组并未添加到请求中。当我不尝试传递数组时,所有其他 POST 请求都有效。我只是不确定我需要做什么才能让数组正确传递。

这是正确的做法吗?是否可以通过 Collection 代替?

【问题讨论】:

标签: java spring api rest resttemplate


【解决方案1】:

如何发布数组:

private String doPOST(String[] array) {
    RestTemplate restTemplate = new RestTemplate(true);

    //add array
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://my_url");
    for (String item : array) {
        builder.queryParam("array", item);
    }

    //another staff
    String result = "";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
            new HttpEntity<>(headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
            builder.build().encode().toUri(),
            HttpMethod.POST,
            requestEntity,
            String.class);

    HttpStatus statusCode = responseEntity.getStatusCode();
    if (statusCode == HttpStatus.ACCEPTED) {
        result = responseEntity.getBody();
    }
    return result;
}

POST 请求将具有下一个结构:

POST https://my_url?array=your_value1&array=your_value2

在服务器端:

public class MyServlet extends HttpServlet {
 @Override
    public void doPost(HttpServletRequest req, HttpServletResponse response) {

        try {
            String[] array = req.getParameterValues("array");
            String result = doStaff(array);
            response.getWriter().write(result);
            response.setStatus(HttpServletResponse.SC_ACCEPTED);

        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        }
    }
}

【讨论】:

    【解决方案2】:

    您可以查看此帖子:How to pass List or String array to getForObject with Spring RestTemplate,该帖子的解决方案是:

    列表或其他类型的对象可以使用 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
    

    【讨论】:

      猜你喜欢
      • 2014-04-25
      • 2011-07-20
      • 2016-11-09
      • 1970-01-01
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多