Vai al contenuto
Docs

Tutorial

Invia email da Java con l’SDK emailit-java o con Spring Boot e Jakarta Mail via SMTP, e verifica i webhook di Emailit in un controller Spring.

Aggiornato il 1 ott 2026

Questa guida mostra come inviare email da Java con l’SDK ufficiale emailit-java, come usare in alternativa lo starter mail di Spring Boot o Jakarta Mail via SMTP e come verificare i webhook in un controller Spring.

Prerequisiti

  • Java 11 o versioni successive. Gli esempi Spring usano Spring Boot 3, che richiede Java 17.
  • Un dominio di invio verificato, ad esempio acme.com.
  • Una chiave API. Basta una chiave di solo invio limitata al tuo dominio.
  • Finché il workspace non ha l’accesso alla produzione, puoi inviare solo agli indirizzi email degli account dei membri del workspace.

Installa l’SDK

Aggiungi la dipendenza, con l’ultima versione indicata nel repository emailit-java:

pom.xml
<dependency>
  <groupId>com.emailit</groupId>
  <artifactId>emailit-java</artifactId>
  <version>VERSION</version>
</dependency>
build.gradle
implementation 'com.emailit:emailit-java:VERSION'

Configura la chiave API

Fornisci la chiave come variabile d’ambiente:

Terminal
export EMAILIT_API_KEY=secret_••••••••••••••••••••••••••••••••

In Spring Boot, associala a una proprietà per poterla iniettare:

application.properties
emailit.api-key=${EMAILIT_API_KEY}

Invia un’email

SendEmail.java
import com.emailit.*;
import com.emailit.exception.*;
import com.emailit.params.*;
import java.util.List;

public class SendEmail {
    public static void main(String[] args) throws EmailitException {
        EmailitClient emailit = new EmailitClient(System.getenv("EMAILIT_API_KEY"));

        EmailSendParams params = EmailSendParams.builder()
            .setFrom("Acme <hello@acme.com>")
            .setTo(List.of("ada@example.com"))
            .setSubject("Your order has shipped")
            .setHtml("<p>Order #1042 is on its way.</p>")
            .build();

        EmailitObject email = emailit.emails().send(params);
        System.out.println(email.getString("id")); // em_…
    }
}

In Spring Boot, registra il client una sola volta come bean e iniettalo dove invii:

EmailitConfig.java
import com.emailit.EmailitClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class EmailitConfig {
    @Bean
    EmailitClient emailitClient(@Value("${emailit.api-key}") String apiKey) {
        return new EmailitClient(apiKey);
    }
}

Gestisci gli errori

L’SDK lancia eccezioni tipizzate che estendono EmailitException:

Java
try {
    emailit.emails().send(params);
} catch (RateLimitException e) {
    // 429: back off and retry
} catch (AuthenticationException e) {
    // 401: the API key is missing or invalid
} catch (UnprocessableEntityException e) {
    // 422: for example, the from domain isn't verified
} catch (EmailitException e) {
    log.error("Emailit error {}: {}", e.getHttpStatus(), e.getHttpBody());
}

Invia con SMTP

Spring Boot

Aggiungi spring-boot-starter-mail e configura il relay:

application.properties
spring.mail.host=smtp.emailit.com
spring.mail.port=587
spring.mail.username=emailit
spring.mail.password=${EMAILIT_API_KEY}
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

Poi invia con JavaMailSender:

WelcomeMailer.java
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

@Service
public class WelcomeMailer {
    private final JavaMailSender mailSender;

    public WelcomeMailer(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void sendWelcome(String to) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("Acme <hello@acme.com>");
        message.setTo(to);
        message.setSubject("Welcome to Acme");
        message.setText("Thanks for signing up.");
        mailSender.send(message);
    }
}

Usa MimeMessageHelper per HTML e allegati.

Jakarta Mail senza Spring

Jakarta Mail da solo (in passato JavaMail) usa le stesse proprietà mail.smtp.*:

Java
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.emailit.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");

Session session = Session.getInstance(props, new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication("emailit", System.getenv("EMAILIT_API_KEY"));
    }
});

Se la porta 587 è bloccata sulla tua rete, usa la 2525 o la 2587 con le stesse impostazioni. Vedi Impostazioni SMTP.

Ricevi i webhook

Crea un webhook e salva il suo secret di firma in EMAILIT_WEBHOOK_SECRET. Accetta il corpo come String, così verifichi esattamente ciò che Emailit ha firmato:

EmailitWebhookController.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class EmailitWebhookController {
    private final ObjectMapper mapper = new ObjectMapper();
    private final String secret = System.getenv("EMAILIT_WEBHOOK_SECRET");

    @PostMapping("/webhooks/emailit")
    public ResponseEntity<Void> receive(
            @RequestBody String body,
            @RequestHeader(value = "X-Emailit-Signature", defaultValue = "") String signature,
            @RequestHeader(value = "X-Emailit-Timestamp", defaultValue = "0") long timestamp) throws Exception {

        if (Math.abs(System.currentTimeMillis() / 1000 - timestamp) > 300 || !isValid(body, signature, timestamp)) {
            return ResponseEntity.status(401).build();
        }

        // The body is a JSON array of up to 100 events.
        for (JsonNode event : mapper.readTree(body)) {
            if ("email.bounced".equals(event.path("type").asText())) {
                String address = event.path("data").path("object").path("to").asText();
                // Stop emailing this address.
            }
        }
        return ResponseEntity.ok().build();
    }

    private boolean isValid(String body, String signature, long timestamp) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] digest = mac.doFinal((timestamp + "." + body).getBytes(StandardCharsets.UTF_8));
        String expected = HexFormat.of().formatHex(digest);
        return MessageDigest.isEqual(
            expected.getBytes(StandardCharsets.UTF_8),
            signature.getBytes(StandardCharsets.UTF_8));
    }
}

Se Spring Security è attivo, consenti questo percorso ed escludilo dalla protezione CSRF. Restituisci un 2xx entro 30 secondi; le altre risposte vengono ritentate. Vedi Firma delle richieste.

Consigli per la produzione

  • Riutilizza i client. Crea un solo EmailitClient (o affidati all’unico JavaMailSender di Spring) invece di uno per messaggio.
  • Invia in modo asincrono. Per gli invii massivi usa @Async, una coda di messaggi o un job programmato, e limita il throughput per restare entro i limiti di invio (2 email al secondo per impostazione predefinita).
  • Rendi sicuri i nuovi tentativi. Se ritenti dopo un timeout, invia un header Idempotency-Key con java.net.http.HttpClient; vedi Idempotenza.
  • Elimina i webhook duplicati salvando ogni event_id che elabori.

Passaggi successivi

Allegati, programmazione e tracciamento.
Ogni evento e il suo payload.
Correggi gli errori di autenticazione e di connessione.
Tutte le librerie ufficiali.

Questa pagina ti è stata utile?

Grazie del feedback.

Grazie, leggiamo ogni messaggio.