RestTemplate使用指南(雾)

lin 1127 字 151 次阅读


一、Get请求

(一)返回目标对象

假设有以下请求,通过示例代码完成请求调用/test?age=12&sex=男

1.无变量参数
无变量参数或者将变量参数拼接成字符串形成无变量url请求字符串

public ResponseEntity<Object> test0(UserDTO userDTO){
    Integer age = userDTO.getAge();
    String sex = userDTO.getSex();
    String url = "http://localhost:8080/test?age="+age+"&sex="+sex;
    User user = restTemplate.getForObject(url, User.class);
    return ResponseEntity.ok(user);
}
此种方法简单易懂,但需要注意拼接字符串引号

2.有变量参数
通过占位符的方式注入变量

public ResponseEntity<Object> test0(UserDTO userDTO){
    String url = "http://localhost:8080/test?age={1}&sex={2}";
    User user = restTemplate.getForObject(url, User.class, userDTO.getAge() ,userDTO.getSex());
    return ResponseEntity.ok(user);
}
占位符的编号从1开始,不是从0开始
使用占位符的方式构造请求字符串的方式比较优雅,建议使用

返回目标对象期望对方服务器总能够返回成功的结果,否则程序在运行时可能出现运行时异常

(2)返回包装对象

如何解决直接返回时可能出现的运行时异常?可以使用返回包装类型,包装类型含有HTTP状态码,通过状态码来解析返回具体值。
使用方法和上述相同,区别是将方法getForObject替换成getForEntity,方法参数使用完全一致。

实际开发中,推荐使用get请求使用getForEntity方法,手动解析返回值

二、Post请求

一般来说,使用POST请求,请求体都会带有参数,无需考虑不带参数的场景。
使用POST请求,主要构造HTTPEntity请求体。

1. 基本POST请求

public ResponseEntity<Object> test2(UserDTO userDTO){
    String url = "http://localhost:8080/user/test";
    HttpEntity<UserDTO> request = new HttpEntity<>(userDTO);
    User user = restTemplate.postForObject(url, request, User.class);
    return ResponseEntity.ok(user);
}

2. 带请求头的POST请求

public ResponseEntity<Object> test3(UserDTO userDTO){
    String url = "http://localhost:8080/user/test";
    
    // 设置请求头
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("Authorization", "Bearer token123");
    
    HttpEntity<UserDTO> request = new HttpEntity<>(userDTO, headers);
    User user = restTemplate.postForObject(url, request, User.class);
    return ResponseEntity.ok(user);
}

3. 使用postForEntity方法

public ResponseEntity<Object> test4(UserDTO userDTO){
    String url = "http://localhost:8080/user/test";
    
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    
    HttpEntity<UserDTO> request = new HttpEntity<>(userDTO, headers);
    ResponseEntity<User> response = restTemplate.postForEntity(url, request, User.class);
    
    if (response.getStatusCode().is2xxSuccessful()) {
        return ResponseEntity.ok(response.getBody());
    } else {
        // 处理错误
        return ResponseEntity.status(response.getStatusCode())
                           .body("创建用户失败");
    }
}

POST请求相较于GET请求稍微复杂点,因为GET请求可以将请求参数方才url字符串中,POST请求需要单独构造请求体。

三、请求头参数

1. 设置通用请求头

@Configuration
public class RestTemplateConfig {
    
    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        
        // 添加拦截器设置通用请求头
        restTemplate.getInterceptors().add((request, body, execution) -> {
            HttpHeaders headers = request.getHeaders();
            headers.set("User-Agent", "MyApp/1.0");
            headers.set("X-Request-ID", UUID.randomUUID().toString());
            return execution.execute(request, body);
        });
        
        return restTemplate;
    }
}

2. 为特定请求设置请求头

public ResponseEntity<Object> testWithHeaders(UserDTO userDTO) {
    String url = "http://localhost:8080/user/test";
    
    // 创建请求头
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("Authorization", "Bearer " + getToken());
    headers.set("X-Client-Version", "1.0.0");
    headers.set("Accept-Language", "zh-CN");
    
    // 创建请求实体
    HttpEntity<UserDTO> request = new HttpEntity<>(userDTO, headers);
    
    // 发送请求
    ResponseEntity<User> response = restTemplate.exchange(
        url, HttpMethod.POST, request, User.class);
    
    return ResponseEntity.ok(response.getBody());
}

3. 使用exchange方法灵活设置HTTP方法

public ResponseEntity<Object> testExchange(UserDTO userDTO) {
    String url = "http://localhost:8080/user/test";
    
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("Authorization", "Bearer token123");
    
    HttpEntity<UserDTO> request = new HttpEntity<>(userDTO, headers);
    
    // 使用exchange方法,可以指定任意HTTP方法
    ResponseEntity<User> response = restTemplate.exchange(
        url, HttpMethod.POST, request, User.class);
    
    return ResponseEntity.ok(response.getBody());
}

4. 处理文件上传的POST请求

public ResponseEntity<Object> uploadFile(MultipartFile file) {
    String url = "http://localhost:8080/upload";
    
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
    body.add("file", new InputStreamResource(file.getInputStream()));
    body.add("filename", file.getOriginalFilename());
    
    HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(body, headers);
    
    ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
    
    return ResponseEntity.ok(response.getBody());
}

四、某些注意事项

1. 异常处理

public ResponseEntity<Object> safeApiCall(UserDTO userDTO) {
    try {
        String url = "http://localhost:8080/user/test";
        HttpEntity<UserDTO> request = new HttpEntity<>(userDTO);
        ResponseEntity<User> response = restTemplate.postForEntity(url, request, User.class);
        
        return ResponseEntity.ok(response.getBody());
        
    } catch (HttpClientErrorException e) {
        // 4xx 错误
        return ResponseEntity.status(e.getStatusCode())
                           .body("客户端错误: " + e.getMessage());
    } catch (HttpServerErrorException e) {
        // 5xx 错误
        return ResponseEntity.status(e.getStatusCode())
                           .body("服务器错误: " + e.getMessage());
    } catch (RestClientException e) {
        // 其他RestTemplate异常
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                           .body("请求失败: " + e.getMessage());
    }
}

2. 超时设置

@Bean
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    
    // 设置超时
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(5000);  // 连接超时5秒
    factory.setReadTimeout(10000);    // 读取超时10秒
    
    restTemplate.setRequestFactory(factory);
    return restTemplate;
}

天下繁华,唯有一心
最后更新于 2025-11-17