restTemplate을 사용하여 인증 헤더와 함께 GET 요청 보내기
RestTemplate을 사용하여 일부 Authorization 헤더와 함께 GET 요청을 보내 내 서버에서 리소스를 검색해야합니다.
문서를 살펴본 후 GET 메서드는 헤더를 매개 변수로 받아들이지 않으며 accept 및 Authorization과 같은 헤더를 보내는 유일한 방법은 exchange 메서드 를 사용하는 것임을 알았습니다 .
그것은 매우 기본적인 행동이기 때문에 내가 뭔가를 놓치고 있는지 궁금해하고 그것을 할 수있는 다른 더 쉬운 방법이 있습니까?
당신은 아무것도 놓치고 있지 않습니다. RestTemplate#exchange(..)
요청 헤더를 설정하는 데 사용하는 적절한 방법입니다.
다음은 예입니다 (POST를 사용하지만 GET으로 변경하고 원하는 엔티티를 사용하십시오).
GET을 사용하면 요청 엔터티에 아무것도 포함 할 필요가 없습니다 (API에서 예상하지 않는 한 HTTP 사양에 위배됩니다). 빈 문자열 일 수 있습니다.
postForObject
와 함께 사용할 수 있습니다 HttpEntity
. 다음과 같이 표시됩니다.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String result = restTemplate.postForObject(url, entity, String.class);
GET 요청에서는 일반적으로 본문을 보내지 않습니다 (허용되지만 목적에 부합하지 않음). RestTemplate을 다르게 연결하지 않고 헤더를 추가하는 방법은 exchange
또는 execute
메서드를 직접 사용하는 것 입니다. get 속기는 헤더 수정을 지원하지 않습니다.
비대칭은 언뜻보기에 약간 이상합니다. 아마도 이것은 Spring의 향후 버전에서 수정 될 것입니다.
다음은 기본 인증, 헤더 및 예외 처리가 포함 된 매우 간단한 예입니다.
private HttpHeaders createHttpHeaders(String user, String password)
{
String notEncoded = user + ":" + password;
String encodedAuth = "Basic " + Base64.getEncoder().encodeToString(notEncoded.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("Authorization", encodedAuth);
return headers;
}
private void doYourThing()
{
String theUrl = "http://blah.blah.com:8080/rest/api/blah";
RestTemplate restTemplate = new RestTemplate();
try {
HttpHeaders headers = createHttpHeaders("fred","1234");
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
}
catch (Exception eek) {
System.out.println("** Exception: "+ eek.getMessage());
}
}
이 모든 답변은 불완전하거나 불완전한 것으로 보입니다. RestTemplate 인터페이스를 살펴보면, 그것이 ClientHttpRequestFactory
주입 되도록 의도 된 것처럼 보이며 , 헤더, 본문 및 요청 매개 변수의 사용자 정의를 포함하여 요청을 생성하는 데 requestFactory가 사용됩니다.
ClientHttpRequestFactory
단일 공유에 삽입 하려면 범용 RestTemplate
이 필요하거나 .NET을 통해 새 템플릿 인스턴스를 가져와야 new RestTemplate(myHttpRequestFactory)
합니다.
불행히도 단일 Authorization 헤더를 설정하려는 경우에도 그러한 팩토리를 만드는 것은 다소 사소 해 보이지 않습니다. 이는 일반적인 요구 사항이 무엇인지 고려할 때 매우 실망 스럽지만 적어도 예를 들어 쉽게 사용할 수 있습니다. , Authorization 헤더는 Spring-Security Authorization
객체에 포함 된 데이터에서 생성 될 수 있으며 , 그런 다음 SecurityContextHolder.getContext().getAuthorization()
적절한 null 검사를 사용하여 헤더 를 수행 하고 채움으로써 모든 요청에 대해 나가는 AuthorizationHeader를 설정하는 팩토리를 생성 할 수 있습니다 . 이제 해당 RestTemplate으로 이루어진 모든 아웃 바운드 나머지 호출에는 올바른 Authorization 헤더가 있습니다.
Without more emphasis placed on the HttpClientFactory mechanism, providing simple-to-overload base classes for common cases like adding a single header to requests, most of the nice convenience methods of RestTemplate
end up being a waste of time, since they can only rarely be used.
I'd like to see something simple like this made available
@Configuration
public class MyConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate(new AbstractHeaderRewritingHttpClientFactory() {
@Override
public HttpHeaders modifyHeaders(HttpHeaders headers) {
headers.addHeader("Authorization", computeAuthString());
return headers;
}
public String computeAuthString() {
// do something better than this, but you get the idea
return SecurityContextHolder.getContext().getAuthorization().getCredential();
}
});
}
}
At the moment, the interface of the available ClientHttpRequestFactory's are harder to interact with than that. Even better would be an abstract wrapper for existing factory implementations which makes them look like a simpler object like AbstractHeaderRewritingRequestFactory for the purposes of replacing just that one piece of functionality. Right now, they are very general purpose such that even writing those wrappers is a complex piece of research.
'Program Tip' 카테고리의 다른 글
maven : 명령 줄 옵션 또는 env 변수를 사용하여 로컬 저장소의 위치를 재정의 할 수 있습니까? (0) | 2020.11.04 |
---|---|
예외가 특정 유형인지 확인하는 방법 (0) | 2020.11.04 |
Ansible은 Hudson / Jenkins와 같은 CI 도구를 대체합니까? (0) | 2020.11.04 |
원자에서`git commit`과`git push`를 어떻게 실행할 수 있습니까? (0) | 2020.11.04 |
단 하나의 명령문으로 Python 목록에서 여러 항목 제거 (0) | 2020.11.04 |