Весна RestTemplate сделать с параметрами



Я должен сделать вызов REST, который включает пользовательские заголовки и параметры запроса. Я установил свой HttpEntity только с заголовками (без тела), и я использую RestTemplate.метод exchange () следующим образом:



HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");

Map<String, String> params = new HashMap<String, String>();
params.put("msisdn", msisdn);
params.put("email", email);
params.put("clientVersion", clientVersion);
params.put("clientType", clientType);
params.put("issuerName", issuerName);
params.put("applicationName", applicationName);

HttpEntity entity = new HttpEntity(headers);

HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, params);


это не удается на клиентском конце с сервлетом диспетчера не удается разрешить запрос к обработчику. Havinf отладил его, похоже, что параметры запроса не отправляются.



когда я делаю обмен с сообщением, используя тело запроса и без запроса параметры он работает просто отлично.



у кого-нибудь есть идеи?

831   8  

8 ответов:

легко манипулировать URL-адреса / путь / параметры / и т. д. вы можете использовать весной UriComponentsBuilder класса. Это чище, что вручную конкатенации строк и он заботится о кодировке URL для вас:

HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
        .queryParam("msisdn", msisdn)
        .queryParam("email", email)
        .queryParam("clientVersion", clientVersion)
        .queryParam("clientType", clientType)
        .queryParam("issuerName", issuerName)
        .queryParam("applicationName", applicationName);

HttpEntity<?> entity = new HttpEntity<>(headers);

HttpEntity<String> response = restTemplate.exchange(
        builder.toUriString(), 
        HttpMethod.GET, 
        entity, 
        String.class);

uriVariables также развернуты в строке запроса. Например, следующий вызов развернет значения как для учетной записи, так и для имени:

restTemplate.exchange("http://my-rest-url.org/rest/account/{account}?name={name}",
    HttpMethod.GET,
    httpEntity,
    clazz,
    "my-account",
    "my-name"
);

таким образом, фактический url-адрес запроса будет

http://my-rest-url.org/rest/account/my-account?name=my-name

посмотрите на HierarchicalUriComponents.expandInternal (UriTemplateVariables) для получения более подробной информации. Версия весны 3.1.3.

ОК, так что я идиот, и я путаю параметры запроса с параметрами url. Я надеялся, что будет более хороший способ заполнить мои параметры запроса, а не уродливую конкатенированную строку, но мы там. Это просто случай построения URL с правильными параметрами. Если вы передадите его как строку Spring также позаботится о кодировке для вас.

Я пытался что-то подобное, и пример RoboSpice помог мне разобраться:

HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");

HttpEntity<String> request = new HttpEntity<>(input, createHeader());

String url = "http://awesomesite.org";
Uri.Builder uriBuilder = Uri.parse(url).buildUpon();
uriBuilder.appendQueryParameter(key, value);
uriBuilder.appendQueryParameter(key, value);
...

String url = uriBuilder.build().toString();

HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request , String.class);

по крайней мере, с весны 3, вместо использования UriComponentsBuilder чтобы построить URL (который немного подробен),много на RestTemplate методы принимают заполнители в пути для параметров (не только exchange).

из документации:

многие RestTemplate методы принимает шаблон URI и URI переменные шаблона, либо как String vararg, или как Map<String,String>.

например String с vararg:

restTemplate.getForObject(
   "http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, "42", "21");

или Map<String, String>:

Map<String, String> vars = Collections.singletonMap("hotel", "42");

restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", 
    String.class, vars);

ссылка: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#rest-resttemplate-uri

если вы посмотрите на документация на RestTemplate и поиск "URI Template", вы можете увидеть, какие методы вы можете использовать заполнители С.

Я беру другой подход, вы можете согласиться или нет, но я хочу контролировать от .вместо свойств файла, скомпилированного Java-кода

внутри приложения.свойства файла

конечной точки.url = https://yourHost/resource?requestParam1={0}&requestParam2={1}

код Java идет здесь, вы можете написать, Если или переключить условие, чтобы узнать, если url конечной точки В.файл свойств имеет @PathVariable (содержит {}) или @RequestParam (yourURL?ключ=значение) и т. д... затем вызовите метод соответственно... таким образом, его динамический и не нужно менять код в будущем одной остановки магазина...

Я пытаюсь дать больше идеи, чем фактический код здесь ...пытаюсь написать универсальный метод для каждого @RequestParam, и @PathVariable и т. д... затем позвоните соответственно, когда это необходимо

  @Value("${endpoint.url}")
  private String endpointURL;
  // you can use variable args feature in Java
  public String requestParamMethodNameHere(String value1, String value2) {
    RestTemplate restTemplate = new RestTemplate();
    restTemplate
           .getMessageConverters()
           .add(new MappingJackson2HttpMessageConverter());

    HttpHeaders headers = new HttpHeaders();
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
    HttpEntity<String> entity = new HttpEntity<>(headers);

    try {
      String formatted_URL = MessageFormat.format(endpointURL, value1, value2);
      ResponseEntity<String> response = restTemplate.exchange(
                    formatted_URL ,
                    HttpMethod.GET,
                    entity,
                    String.class);
     return response.getBody();
    } catch (Exception e) { e.printStackTrace(); }
public static void main(String[] args) {
         HttpHeaders httpHeaders = new HttpHeaders();
         httpHeaders.set("Accept", MediaType.APPLICATION_JSON_VALUE);
         final String url = "https://host:port/contract/{code}";
         Map<String, String> params = new HashMap<String, String>();
         params.put("code", "123456");
         HttpEntity<?> httpEntity  = new HttpEntity<>(httpHeaders); 
         RestTemplate restTemplate  = new RestTemplate();
         restTemplate.exchange(url, HttpMethod.GET, httpEntity,String.class, params);
    }

Если вы передаете непараметризованные параметры для RestTemplate, у вас будет одна метрика для каждого отдельного другого URL-адреса, который вы передаете, учитывая параметры. Вы хотели бы использовать параметризованные url:

http://my-url/action?param1={param1}&param2={param2}

вместо

http://my-url/action?param1=XXXX&param2=YYYY

второй случай-это то, что вы получаете с помощью класса UriComponentsBuilder.

один из способов реализации первого поведения заключается в следующем:

Map<String, Object> params = new HashMap<>();
params.put("param1", "XXXX");
params.put("param2", "YYYY");

String url = "http://my-url/action?%s";

String parametrizedArgs = params.keySet().stream().map(k ->
    String.format("%s={%s}", k, k)
).collect(Collectors.joining("&"));

HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
HttpEntity<String> entity = new HttpEntity<>(headers);

restTemplate.exchange(String.format(url, parametrizedArgs), HttpMethod.GET, entity, String.class, params);

Comments

    Ничего не найдено.