我与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

最佳答案

在卷曲请求中,您使用的是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注入您的类中。

关于java - Spring Boot RestTemplate交换400错误的请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52830530/

10-14 15:06
查看更多