[java] 매개 변수가있는 Spring RestTemplate GET

REST사용자 지정 헤더와 쿼리 매개 변수가 포함 된 호출을 해야합니다 . 내 설정 HttpEntity단지 헤더 (NO 몸)으로, 그리고 내가 사용하는 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);

이는 클라이언트 측 dispatcher servlet에서 요청을 처리기로 처리 할 수 ​​없어 실패 합니다. 디버깅 한 후 요청 매개 변수가 전송되지 않는 것 같습니다.

POST요청 본문을 사용하고 쿼리 매개 변수를 사용 하지 않고 교환을 수행하면 정상적으로 작동합니다.

누구든지 아이디어가 있습니까?



답변

URL / 경로 / 매개 변수 등을 쉽게 조작하기 위해 Spring의 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)을 참조하십시오. Spring의 버전은 3.1.3입니다.


답변

적어도 봄 3 있기 때문에, 대신에 사용하는 UriComponentsBuilder(조금 자세한 임) URL을 구축, 많은RestTemplate방법은 매개 변수 (단지의 경로에 자리를 수락 exchange).

설명서에서 :

많은 RestTemplate메소드가 URI 템플리트 및 URI 템플리트 변수를 Stringvararg 또는
Map<String,String> .

예를 들어 Stringvararg 를 사용하면

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

또는 Map<String, String>:

Map<String, String> vars = new HashMap<>();
vars.put("hotel", "42");
vars.put("room", "21");

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

참고: https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#rest-resttemplate-uri

JavaDoc 을 보고 RestTemplate“URI 템플리트”를 검색하면 플레이스 홀더를 사용할 수있는 메소드를 확인할 수 있습니다.


답변

좋아, 나는 바보이고 쿼리 매개 변수를 url 매개 변수와 혼동하고 있습니다. 추악한 연결 문자열 대신 쿼리 매개 변수를 채우는 더 좋은 방법이 있기를 바랐지만 거기에 있습니다. 올바른 매개 변수를 사용하여 URL을 작성하는 경우입니다. String 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);


답변

    String uri = http://my-rest-url.org/rest/account/{account};

    Map<String, String> uriParam = new HashMap<>();
    uriParam.put("account", "my_account");

    UriComponents builder = UriComponentsBuilder.fromHttpUrl(uri)
                .queryParam("pageSize","2")
                        .queryParam("page","0")
                        .queryParam("name","my_name").build();

    HttpEntity<String> requestEntity = new HttpEntity<>(null, getHeaders());

    ResponseEntity<String> strResponse = restTemplate.exchange(builder.toUriString(),HttpMethod.GET, requestEntity,
                        String.class,uriParam);

    //final URL: http://my-rest-url.org/rest/account/my_account?pageSize=2&page=0&name=my_name

RestTemplate : UriComponents (URI 변수 및 요청 매개 변수)를 사용하여 동적 URI 빌드


답변

해시 맵을 쿼리 매개 변수 문자열로 변환

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

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
for (Map.Entry<String, String> entry : params.entrySet()) {
    builder.queryParam(entry.getKey(), entry.getValue());
}

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

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