使用Spring RestTemplate将查询参数添加到每个REST请求

时间:2018-03-20 21:28:54

标签: java spring rest spring-boot resttemplate

有没有办法在Spring中为RestTemplate执行的每个HTTP请求添加查询参数?

Atlassian API使用查询参数os_authType来指示身份验证方法,因此我想将?os_authtype=basic附加到每个请求,而不是在我的代码中全部指定。

代码

@Service
public class MyService {

    private RestTemplate restTemplate;

    @Autowired
    public MyService(RestTemplateBuilder restTemplateBuilder, 
            @Value("${api.username}") final String username, @Value("${api.password}") final String password, @Value("${api.url}") final String url ) {
        restTemplate = restTemplateBuilder
                .basicAuthorization(username, password)
                .rootUri(url)
                .build();    
    }

    public ResponseEntity<String> getApplicationData() {            
        ResponseEntity<String> response
          = restTemplate.getForEntity("/demo?os_authType=basic", String.class);

        return response;    
    }
}

2 个答案:

答案 0 :(得分:3)

您可以编写实现ClientHttpRequestInterceptor

的自定义RequestInterceptor
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

public class AtlassianAuthInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(
            HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {

        // logic to check if request has query parameter else add it
        return execution.execute(request, body);
    }
}

现在我们需要配置我们的RestTemplate才能使用它

import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;


@Configuration
public class MyAppConfig {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
        restTemplate.setInterceptors(Collections.singletonList(new AtlassianAuthInterceptor()));
        return restTemplate;
    }
}

答案 1 :(得分:0)

对于那些对逻辑感兴趣的人可以添加查询参数,因为HttpRequest是不可变的,因此需要一个包装器类。

class RequestWrapper {
    private final HttpRequest original;
    private final URI newUriWithParam;

    ...
    public HttpMethod getMethod() { return this.original.method }
    public URI getURI() { return newUriWithParam }

}

然后在您的ClientHttpRequestInterceptor中,您可以执行类似

的操作
public ClientHttpResponse intercept(
        request: HttpRequest,
        body: ByteArray,
        execution: ClientHttpRequestExecution
    ) {
        URI uri = UriComponentsBuilder.fromUri(request.uri).queryParam("new-param", "param value").build().toUri();
        return execution.execute(RequestWrapper(request, uri), body);
    }