Practical Guide to Sending and Receiving HTTP/HTTPS Requests

Introduction

In daily projects, we often encounter the integration of third-party systems, and HTTP requests are a common method of integration. This article provides a brief introduction and usage.

Core Concepts of HTTP/HTTPS

1. Basics of HTTP Protocol

Definition: HyperText Transfer Protocol (HTTP), used for communication between clients and servers.Core Features:

  • Stateless Protocol: Each request is independent and does not retain session information (requires Cookie/Session to maintain state)
  • Request-Response Model: Client initiates a request → Server returns a response
  • Default Port: 80

2. Enhanced Security of HTTPS

Definition: HTTP + SSL/TLS encryption layer, preventing data eavesdropping and tamperingEncryption Principles:

1. Request HTTPS connection

2. Send SSL digital certificate

3. Validate certificate

4. Generate symmetric key

5. Encrypt key with public key

6. Decrypt with private key

7. Encrypt communication with symmetric key

Client
Server

Default Port: 443

3. Composition of HTTP Request/Response

  • • Request Structure
POST /api/users HTTP/1.1                ← Start line (Method + Path + Protocol Version)
Host: api.example.com                   ← Request header (Key-Value format)
Content-Type: application/json
Authorization: Bearer xxxxxx

{"name":"John","age":30}                ← Request body (optional)
  • • Response Structure
HTTP/1.1 200 OK                         ← Status line (Protocol + Status Code)
Content-Type: application/json          ← Response header
Content-Length: 45

{"id":101,"status":"created"}           ← Response body

Core Functions of RestTemplate

1. What is RestTemplate?

A synchronous HTTP client provided by Spring for consuming RESTful services.Core Advantages:

  • • Simplifies HTTP request sending/response handling
  • • Built-in object-JSON/XML conversion (via HttpMessageConverter)
  • • Integrates with Spring ecosystem (e.g., dependency injection, exception handling)

2. Core Structure

Component Function Example Class
RestTemplate Main entry for HTTP operations Itself
HttpMethod Request method enumeration GET, POST, PUT, DELETE
HttpHeaders Request/Response header operations setContentType(), add()
HttpEntity Request/Response wrapper (header + body) new HttpEntity<>(body, headers)
ResponseEntity Response wrapper (status + header + body) ResponseEntity
ClientHttpRequestFactory Underlying connection factory SimpleClientHttpRequestFactory
ResponseErrorHandler Error handler DefaultResponseErrorHandler
UriComponentsBuilder URI construction tool fromPath().queryParam()

Practical Guide to RestTemplate

  • • 1. Add Dependency:
<!-- Spring Boot Starter Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • • 2. Create RestTemplate Instance
// Simplest way
RestTemplate restTemplate = new RestTemplate();

// Recommended way: Configure Bean (supports dependency injection)
@Configuration
public class AppConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
  • • 3. Send GET RequestBasic Usage:
String url = "https://www.baidu.com.cn/users/{username}";
User user = restTemplate.getForObject(url, User.class, "spring-projects");

With Query Parameters:

String url = "https://www.baidu.com.cn/search?q={keyword}";
ResponseEntity<String> response = restTemplate.getForEntity(
    url, 
    String.class, 
    "resttemplate"
);
System.out.println(response.getStatusCode()); // 200
System.out.println(response.getBody());       // JSON string
  • • 4. Send POST RequestSubmit Form Data:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("username", "john");
body.add("password", "123456");

HttpEntity<MultiValueMap<String, String>> request = 
    new HttpEntity<>(body, headers);

ResponseEntity<LoginResponse> response = restTemplate.postForEntity(
    "https://api.example.com/login", 
    request, 
    LoginResponse.class
);

Submit JSON Data:

User newUser = new User("John", "[email protected]");
HttpEntity<User> request = new HttpEntity<>(newUser);

User createdUser = restTemplate.postForObject(
    "https://api.example.com/users",
    request,
    User.class
);
  • • 5. Send PUT/DELETE Requests
// PUT update resource
restTemplate.put(
    "https://api.example.com/users/{id}",
    updatedUser,  // Request body object
    101           // Path parameter
);

// DELETE delete resource
restTemplate.delete("https://api.example.com/users/{id}", 101);
  • • 6. Handle HTTPS (SSL Configuration)Ignore Certificate Validation (Not Recommended for Production):
@Bean
public RestTemplate restTemplate() throws Exception {
    // Create factory to bypass SSL validation
    SSLContext sslContext = new SSLContextBuilder()
        .loadTrustMaterial(null, (cert, authType) -> true)
        .build();

    HttpClient client = HttpClients.custom()
        .setSSLContext(sslContext)
        .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
        .build();

    return new RestTemplate(new HttpComponentsClientHttpRequestFactory(client));
}

Load Trusted Certificates (Recommended for Production):1. Import CA Certificate

# Export certificate from server
keytool -export -alias server -file server.cer -keystore server.jks

# Import into client trust store
keytool -import -alias server -file server.cer -keystore client-truststore.jks  
  1. 2. Configure RestTemplate with Trusted Certificates
@Bean
public RestTemplate restTemplate() throws Exception {
    // Load certificate from classpath
    Resource certFile = new ClassPathResource("server.crt");
    Certificate certificate = CertificateFactory.getInstance("X.509")
        .generateCertificate(certFile.getInputStream());

    // Create trust store
    KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
    trustStore.load(null, null);
    trustStore.setCertificateEntry("server", certificate);

    // Create SSL context
    SSLContext sslContext = SSLContexts.custom()
        .loadTrustMaterial(trustStore, null)
        .build();

    HttpClient client = HttpClients.custom()
        .setSSLContext(sslContext)
        .build();

    return new RestTemplate(new HttpComponentsClientHttpRequestFactory(client));
}

Advanced Techniques and Best Practices

1. Custom Message Converters

@Bean
public RestTemplate restTemplate() {
    RestTemplate template = new RestTemplate();
    
    // Replace default converters (e.g., use Gson instead of Jackson)
    template.getMessageConverters().clear();
    template.getMessageConverters().add(new GsonHttpMessageConverter());
    
    return template;
}

2. Set Timeout

@Bean
public RestTemplate restTemplate() {
    HttpComponentsClientHttpRequestFactory factory = 
        new HttpComponentsClientHttpRequestFactory();
    
    // Connection timeout (milliseconds)
    factory.setConnectTimeout(5000);  
    // Read timeout
    factory.setReadTimeout(10000);      
    
    return new RestTemplate(factory);
}

3. Add Global Request Headers

@Bean
public RestTemplate restTemplate() {
    RestTemplate template = new RestTemplate();
    
    template.getInterceptors().add((request, body, execution) -> {
        request.getHeaders().add("Authorization", "Bearer xxx");
        return execution.execute(request, body);
    });
    
    return template;
}

4. Unified Exception Handling

try {
    return restTemplate.getForObject(url, User.class);
} catch (HttpClientErrorException e) {
    // Handle 4xx errors
    if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
        throw new UserNotFoundException();
    }
} catch (HttpServerErrorException e) {
    // Handle 5xx errors
    log.error("Server error", e);
    throw new ServiceUnavailableException();
}

Conclusion

  • HTTPS is essential in production environments: Use certificate validation or trust store.
  • Set reasonable timeouts: Avoid thread blocking (recommended: 5s for connection / 10s for read).
  • Use ResponseEntity: Get complete response metadata.
  • Inject rather than create: Manage RestTemplate instances through Spring.
  • Exception handling: Distinguish between client errors (4xx) and server errors (5xx).

In high-concurrency scenarios (e.g., >1000 QPS), it is recommended to use WebClient or AsyncRestTemplate to avoid thread pool exhaustion.

Leave a Comment