Весна 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 отладил его, похоже, что параметры запроса не отправляются.
когда я делаю обмен с сообщением, используя тело запроса и без запроса параметры он работает просто отлично.
у кого-нибудь есть идеи?
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 переменные шаблона, либо какStringvararg, или как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);если вы посмотрите на документация на
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}¶m2={param2}вместо
http://my-url/action?param1=XXXX¶m2=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