【问题标题】:sending List<String> in rest api request but receiving wrongly在 rest api 请求中发送 List<String> 但接收错误
【发布时间】:2021-08-31 21:07:24
【问题描述】:

我的代码如下,我从这里调用 REST API

 List<String> a =  [b]
MultiValueMap<String, Object> requestParam = new LinkedValueMap<>();
requestParam.add('a', a);
restTemplate.postForObject(URL, requestparam,String.class);

接收端代码为

ResponseEntity<Object> functionName(
@Requestparam(value='a', required=true) List<String> a
){
for(int i = 0; i < a.size(); i++){
Sysout(a.get(i));
}


}

它打印为 ["b"] 并且在查询参数中用作 ["b"] 而它应该是 b

【问题讨论】:

  • 您的请求是curl --location --request POST 'localhost:8080/so/2987755?a=b,c,d' \ --header 'Content-Type: application/json'类型的吗?

标签: java spring-boot resttemplate rest


【解决方案1】:

您的问题存在多个问题

  1. ''是java中的字符,""是String
  2. 没有提到请求类型GET/POST,从postForObject推断
  3. 如果您使用 POST 调用,那么您可以将其作为 BodyParam 传递给提及 here,而不是作为 RequestParam 传递,但 RequestParam 仍然可以与 POST 调用一起使用。

解决方案 1:考虑使用 @RequestBody 进行 POST 调用

控制器:

@PostMapping(value = "/so/2987755", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<List<String>> functionName(@RequestBody List<String> a){
    for(int i = 0; i < a.size(); i++){
        System.out.println(a.get(i));
    }
    return new ResponseEntity<>(a, HttpStatus.OK);
}

客户:

List<String> a = Collections.singletonList("b");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

final HttpEntity<String> request = new HttpEntity<String>(objectMapper.writeValueAsString(a), headers);
return restTemplate.postForObject("http://localhost:8080/so/2987755", request,String.class);

解决方案 2:使用 @RequestParam 进行 POST 调用

控制器:

@PostMapping(value = "/so/2987755", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<List<String>> functionName(@RequestParam(value = "a") List<String> a){
    for(int i = 0; i < a.size(); i++){
        System.out.println(a.get(i));
    }
    return new ResponseEntity<>(a, HttpStatus.OK);
}

客户端 1:

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;


Map<String, String> requestParam = new HashMap<>();
final String requestParamKey = "a";
requestParam.put(requestParamKey, "b,c,d");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

final HttpEntity<String> request = new HttpEntity<String>(headers);
return restTemplate.postForObject("http://localhost:8080/so/2987755?a={" + requestParamKey + "}", request, String.class, requestParam);

客户端 2:使用 UriComponentsBuilder 的另一种客户端风格

MultiValueMap<String, String> requestParam = new LinkedMultiValueMap<>();
final String requestParamKey = "a";
List<String> a = Arrays.asList("b", "c", "d");
requestParam.put(requestParamKey, a);

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/so/2987755");
builder.queryParams(requestParam);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(headers);

return restTemplate.postForObject(builder.build().encode().toUri(), request, String.class);

这两个客户端调用都在控制器上打印

b
c
d

RequestParam 打印为 ["b"] 的原因是因为您在 LinkedValueMap 中使用了 List&lt;String&gt;,而不是如果您仅使用 MultiValueMap&lt;String, String&gt;,事情将按您的预期工作。
您观察到的是,在反序列化 List 时,它将变为 ["b"],但如果您使用 UriComponentsBuilder,您将不会遇到此类问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2021-09-19
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    相关资源
    最近更新 更多