【问题标题】:How to mimic curl REST call with Spring's RestTemplate?如何使用 Spring 的 RestTemplate 模拟 curl REST 调用?
【发布时间】:2016-02-04 03:00:10
【问题描述】:

有一个外部 Restful Web 服务,如果它有多个输入,则接收 JSON 有效负载,但如果它是一个输入,它只需要该值。

例如,对于多个输入,这是有效的:

curl -H "Content-Type: application/json" -X POST -d '{ "amount": 10000, "interestRate": ".28", "term": "12", "state": "Georgia"}' http://localhost:8080/webservices/REST/sample/loan

返回:

Approved

对于单个输入:

curl -H "Content-Type: application/json" -X POST -d "18" http://localhost:8080/webservices/REST/sample/age

返回:

Approved

使用 Spring Boot,尝试创建一个 JUnit 测试,以查看是否可以使用 Spring 的 RestTemplate API 发布到此外部服务。

public void RestWebServiceTest {

    private RestTemplate restTemplate;
    private HttpHeaders headers;

    @Before
    public void setup() {
        restTemplate = new RestTemplate();
        headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    }

    @Test
    public void validLoan() {
        final String uri = "http://localhost:8080/webservices/REST/sample/Loan";
        Map<String, String> input = new HashMap<>();
        input.put("amount", "10000");
        input.put("interestRate", ".28");
        input.put("term", "12");
        input.put("state", "Georgia");
        String result = restTemplate.postForObject(uri, input, String.class);
        assertEquals("Approved", result);
    }

    @Test
    public void validAge() {
        final String uri = "http://localhost:8080/webservices/REST/sample/age";
        Integer input = 18;
        String result = restTemplate.postForObject(uri, input, String.class);
        assertEquals("Approved", result);
    }

    @Test
    public void validCountry() {
        final String uri = "http://localhost:8080/webservices/REST/sample/country
        String input = "US";
        String result = restTemplate.postForObject(uri, input, String.class);
        assertEquals("Approved", result);
    }
}

除了 validCountry() 测试方法之外,所有这些工作:

org.springframework.web.client.HttpClientErrorException: 415 Unsupported Media Type
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)

这很奇怪,因为这个 curl 命令适用于同一个调用:

curl -H "Content-Type: application/json" -X POST -d 'US' http://localhost:8080/webservices/REST/sample/country

返回:

Approved

问题:

  1. 如何在validCountry() 测试方法中模拟国家/地区的rest 调用(参见上面的curl 命令)?

  2. 是否需要为 HTTP 标头添加或更改不同的值(在 setup() 方法中)?

  3. 不明白validAge 使用Integer 包装类工作,但String 不工作?

  4. 有没有更好的方法使用 Spring 的 RestTemplate API 来做到这一点?

感谢您抽出宝贵时间阅读本文...

【问题讨论】:

  • 我不使用什么 RestTemplate,但如果您收到 415,我会认为它的默认 Content-Type 不是 application/json。尝试将 Content-Type 标头显式设置为 application/json
  • 我在 setup() 方法中确实做到了。
  • 不,您设置了Accept 标头。他们是两个不同的东西

标签: spring rest curl junit resttemplate


【解决方案1】:

您需要将 Content-Type 设置为 application/json。 Content-Type 必须在请求中设置。下面是设置Content-Type的修改代码

@Test
public void validCountry() {
    final String uri = "http://localhost:8080/webservices/REST/sample/country";
    String input = "US";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity<String> request = new HttpEntity<String>(input, headers);
    String result = restTemplate.postForObject(uri, request, String.class);
    assertEquals("Approved", result);
}

在这里,HttpEntity 是使用您的输入(即“US”)和标题构建的。

我认为这回答了你的问题 1,2 和 4。但不是 3。

【讨论】:

  • 对于您的第三个问题,我在这里尝试了一个简单的示例,它适用于字符串和整数。您能否添加您在使用 String 时遇到的错误?
  • 然后请设置 Content-Type 标头并尝试使用 String。但我认为您使用的 REST 服务的编写方式只接受 Integer 而不是 String。
猜你喜欢
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-28
相关资源
最近更新 更多