Master Spring RestTemplate: Simplify HTTP Calls and File Transfers in Java

This tutorial walks through using Spring's RestTemplate to replace complex HttpURLConnection and Apache HttpClient code, covering environment setup, bean configuration, GET/POST/PUT/DELETE operations, file upload/download, and advanced exchange usage with clear Java examples.

macrozheng
macrozheng
macrozheng
Master Spring RestTemplate: Simplify HTTP Calls and File Transfers in Java

1. Introduction

In modern IT projects, server‑initiated HTTP requests are ubiquitous. Traditionally developers use JDK HttpURLConnection or Apache HttpClient, which are verbose and require manual resource management. Spring provides a convenient template class RestTemplate that abstracts the underlying HTTP client (e.g., JDK, Apache, OkHttp) and offers a simple API to boost development efficiency.

2. Environment Setup

2.1 Using RestTemplate in a non‑Spring project

Add the spring-web dependency to obtain the RestTemplate class:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.2.6.RELEASE</version>
</dependency>

Then you can instantiate RestTemplate directly in your unit tests and call getForObject, postForObject, etc.

2.2 Using RestTemplate in a Spring Boot project

Add the starter dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Configure a bean so that a single RestTemplate instance is injected wherever needed:

@Configuration
public class RestTemplateConfig {
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

You can also replace the default client with Apache HttpClient or OkHttp by providing a custom ClientHttpRequestFactory:

@Configuration
public class RestTemplateConfig {
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate(getClientHttpRequestFactory());
    }
    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        int timeout = 5000;
        RequestConfig config = RequestConfig.custom()
            .setConnectTimeout(timeout)
            .setConnectionRequestTimeout(timeout)
            .setSocketTimeout(timeout)
            .build();
        CloseableHttpClient client = HttpClientBuilder.create()
            .setDefaultRequestConfig(config)
            .build();
        return new HttpComponentsClientHttpRequestFactory(client);
    }
}

Or use OkHttp:

private ClientHttpRequestFactory getClientHttpRequestFactory() {
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .connectTimeout(5, TimeUnit.SECONDS)
        .writeTimeout(5, TimeUnit.SECONDS)
        .readTimeout(5, TimeUnit.SECONDS)
        .build();
    return new OkHttp3ClientHttpRequestFactory(okHttpClient);
}

3. API Practice

RestTemplate

wraps various HTTP methods, dramatically simplifying client code. Below are typical usage patterns.

3.1 GET requests

Two common methods:

getForObject()

getForEntity() getForObject() returns the response body directly, while getForEntity() returns a ResponseEntity that also contains status code, headers, and content type.

@Test
public void simpleTest() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://jsonplaceholder.typicode.com/posts/1";
    String str = restTemplate.getForObject(url, String.class);
    System.out.println(str);
}

Example of a controller and a unit test using getForObject with path variables and request parameters are provided in the source.

3.2 POST requests

Similar to GET, postForObject() returns the response body, while postForEntity() returns the full ResponseEntity. The tutorial shows form‑encoded, object‑based, and JSON POST examples, including header configuration and HttpEntity construction.

@Test
public void testPostByForm() {
    String url = "http://localhost:8080/testPostByForm";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
    map.add("userName", "唐三藏");
    map.add("userPwd", "123456");
    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
    ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
    System.out.println(responseBean);
}

3.3 PUT requests

Use restTemplate.put(url, requestObject) to send a JSON payload for resource updates.

@Test
public void testPutByJson() {
    String url = "http://localhost:8080/testPutByJson";
    RequestBean request = new RequestBean();
    request.setUserName("唐三藏");
    request.setUserPwd("123456789");
    restTemplate.put(url, request);
}

3.4 DELETE requests

@Test
public void testDeleteByJson() {
    String url = "http://localhost:8080/testDeleteByJson";
    restTemplate.delete(url);
}

3.5 exchange method

When the standard methods are insufficient, restTemplate.exchange(...) supports all HTTP verbs (GET, POST, PUT, DELETE, OPTIONS, PATCH, etc.) and allows full control over request headers, body, and response handling.

3.6 File upload and download

File upload uses multipart/form-data with HttpHeaders and MultiValueMap. The controller stores files under a user‑specific directory and returns a ResponseBean indicating success.

@RestController
public class FileUploadController {
    private static final String UPLOAD_PATH = "/springboot-frame-example/springboot-example-resttemplate/";
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public ResponseBean upload(@RequestParam("uploadFile") MultipartFile uploadFile,
                              @RequestParam("userName") String userName) {
        File folder = new File(UPLOAD_PATH + userName);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf('.'));
        ResponseBean result = new ResponseBean();
        try {
            uploadFile.transferTo(new File(folder, newName));
            result.setCode("200");
            result.setMsg("File uploaded successfully: " + newName);
        } catch (IOException e) {
            e.printStackTrace();
            result.setCode("500");
            result.setMsg("File upload failed: " + oldName);
        }
        return result;
    }
}

Client side:

@Test
public void upload() {
    String filePath = "/Users/panzhi/Desktop/Jietu20220205-194655.jpg";
    String url = "http://localhost:8080/upload";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    param.add("uploadFile", new FileSystemResource(new File(filePath)));
    param.add("userName", "张三");
    HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
    ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
    System.out.println(responseBean);
}

File download is implemented with a @RequestMapping that streams the file content to the HTTP response. For small files you can use restTemplate.getForEntity(..., byte[].class) and write the bytes to disk. For large files, use

restTemplate.execute(..., RequestCallback, ResponseExtractor)

with APPLICATION_OCTET_STREAM to stream directly to a file, avoiding memory pressure.

@Test
public void downloadBigFile() throws IOException {
    String userName = "张三";
    String fileName = "c98b677c-0948-46ef-84d2-3742a2b821b0.jpg";
    String url = "http://localhost:8080/downloadFile/{1}/{2}";
    RequestCallback requestCallback = request ->
        request.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
    String targetPath = "/Users/panzhi/Desktop/" + fileName;
    restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
        Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
        return null;
    }, userName, fileName);
}

4. Summary

After this guide, readers should have a solid understanding of how to use RestTemplate for convenient access to RESTful APIs, including GET, POST, PUT, DELETE, file transfers, and advanced customizations. The tool is powerful, and this tutorial only scratches the surface.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaspringHTTPAPITutorial
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.