Spring Boot RestTemplate交换400错误的请求

时间:2018-10-16 07:55:32

标签: java spring rest http spring-boot

我在Spring Boot RestTemplate交换中遇到问题。

我有以下代码:

@RequestMapping(path = "/add")
public @ResponseBody String addFromTo () {
    String apikey = "";
    String baseurl = "http://demowebshop.webshop8.dk/admin/WEBAPI/v2/orders?start=2018-10-05T20%3A49%3A41.745Z&end=2018-10-15T20%3A49%3A41.745Z&api_key=" + apikey;

    RestTemplate restTemplate = new RestTemplate();

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    headers.setBasicAuth("", apikey);

    HttpEntity<String> request = new HttpEntity<String>(" ", headers);
    ResponseEntity<OrderResponse> response = restTemplate.exchange(baseurl, HttpMethod.GET, request, OrderResponse.class);

    return "Some text.";
}

我想要的就是:

curl -X GET --header 'Accept: application/json' --header 'Authorization: Basic {encodedapikey}' 'http://demowebshop.webshop8.dk/admin/WEBAPI/v2/orders?start=2018-10-06T06%3A43%3A40.926Z&end=2018-10-16T06%3A43%3A40.926Z&api_key={apikey}'

我尝试使用具有完全相同的URL的Postman,并使用apikey和'Accept:application / json'标头添加Basic Auth,并且效果很好,但是当我运行此代码时,出现错误讯息:

There was an unexpected error (type=Internal Server Error, status=500).
400 Bad Request

编辑: Pastebin链接到程序抛出的异常: https://pastebin.com/jdYJ2nv7

2 个答案:

答案 0 :(得分:1)

在卷曲请求中,您正在使用apikeyencodedapikey。而在您的Java代码中却没有。除此之外,您还将传递编码的URL作为要使用的URL。这将导致再次对编码的URL进行编码。所以不要那样做。而是使用带有占位符的URL并为其提供值。

@RequestMapping(path = "/add")
public @ResponseBody String addFromTo () {

    String apikey = "";
    String baseurl = "http://demowebshop.webshop8.dk/admin/WEBAPI/v2/orders?start={start}&end={end}&api_key={apikey}";

    Map<String, Object> parameters = new HashMap<>();
    parameters.put("start", "2018-10-05T20:49:41.745Z");
    parameters.put("end", "2018-10-16T06:43:40.926Z");
    parameters.put("apikey", apikey);

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
    headers.setBasicAuth("", apikey);

    ResponseEntity<OrderResponse> response = restTemplate.getForEntity(baseurl, OrderResponse.class, parameters);

    return "Some text.";
}

上面的代码使用正确的参数化URL以及包含占位符值的映射。请注意,这些未编码,将由Spring!处理。最后,您可以简单地使用getForEntity方法而不是exchange方法来获取结果。

最后的建议是,Spring Boot已经配置了一个RestTemplate,您可以(重新)使用它。您无需每次都需要创建一个RestTemplate(创建起来很繁琐,创建后它是线程安全的,因此拥有一个实例就足够了)。

public YourClassCOnstructor(RestTemplateBuilder builder) {
    this.restTemplate = builder.basicAuthorization("", apikey).build();
}

当然,您也可以将其放入@Bean方法中,并将特定的RestTemplate注入您的班级。

答案 1 :(得分:0)

HttpHeaders.setBasicAuth(String, String)仅用于用户名和密码,而不用于基本令牌。 如果要使用基本令牌,请尝试使用headers.add(“ Authorization”,“ Basic” + apiKey)之类的东西,而不是headers.setBasicAuth(...)