java-How to send mail by using mailgun http api in java ?

In this article , I would demo how to send email via mailgun’s REST API in java applications. I would use the apache http client to do this job.

Environment

  • jdk1.8.0_40
  • SpringBoot 1.2.5

Maven dependencies

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.12</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.12</version>
    <scope>compile</scope>
</dependency>

Step #0: Before you begin

You should get your mailgun’s domain and your api key in mailgun.com, just like this( Assuming that your domain name is mg.example.com)

private static final String HTTP_API_KEY = "key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
private static final String HTTP_URL = "https://api.mailgun.net/v3/mg.example.com/messages";

You should change the HTTP_URL with your own domain name.

Step #1: Setup http basic authentication

According to mailgun’s http api documentation, we should add http authentication headers in the http post request, we do like this:

We create a method to build apache httpclient’s HttpClient object like this:

private HttpClient buildHttpClient() {
    if(client!=null) return client;
    client = HttpClientBuilder.create().setDefaultCredentialsProvider(getAuthProvider()).build();
    return client;
}

Then we create a getAuthProvider to build the CredentialsProvider:

private CredentialsProvider getAuthProvider() {
    if(provider!=null) {
        return provider;
    }
    provider = new BasicCredentialsProvider();
    UsernamePasswordCredentials credentials
            = new UsernamePasswordCredentials("api", HTTP_API_KEY);
    provider.setCredentials(AuthScope.ANY, credentials);
    return provider;
}

Step #2: Build the post form with fields

According to mailgun’s documentation, we should add fields to the http post form, so we create a method to do this job:

public void sendMail(String subject,String body,String recipients) {
    try {
        List<NameValuePair> form = new ArrayList<>();
        form.add(new BasicNameValuePair("from", "Example User<[email protected]>"));
        form.add(new BasicNameValuePair("to", recipients));
        form.add(new BasicNameValuePair("subject", subject));
        form.add(new BasicNameValuePair("text", body));
        postMessage(HTTP_URL,form);
    }
    catch (Exception e) {
        log.error("",e);
    }
}

Then we do the http post job with apache http client:

private String postMessage(String URL,List<NameValuePair> form) throws Exception {
    if(form==null||URL==null||URL.trim().length()==0) return "";
    StringBuilder stringBuilder = new StringBuilder();

    org.apache.http.client.HttpClient client = buildHttpClient();
    HttpPost httpPost = new HttpPost(URL);
    HttpResponse response = null;
    try {
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form, Consts.UTF_8);
        httpPost.setEntity(entity);
        httpPost.setHeader("Accept", "application/json");
        response = client.execute(httpPost);
        stringBuilder.append(getBody(response.getEntity().getContent()));
        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();
        if (statusCode == 200) {
            log.info("post mailgun messages ok:"+URL);
        } else {
            log.warn("Failed to post mailgun,status=" + statusCode);
            throw new RuntimeException("post failed:"+URL);
        }
    } catch (Exception e) {
        log.error( e.getMessage(), e);
        throw e;
    }finally {
        if(response!=null&&response.getEntity()!=null) {
            response.getEntity().consumeContent();
        }
    }
    return stringBuilder.toString();
}

The getBody method is as follows:

private String getBody(InputStream inputStream) {
    String result = "";
    try {
        BufferedReader in = new BufferedReader(new InputStreamReader(
                inputStream));
        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            result += inputLine;
            result += "\n";
        }
        in.close();
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    return result;
}

Step #3: Test

Then we can test the methods with this :

public static void main(String[] args) {
    try {
        EmailHttp http = new EmailHttp();
        for(int i=0;i<1;i++) {
            http.sendMail("This is a test mail","Hello world from mailgun, by using httpclient of apache","[email protected]");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

If you get this message, you win:

16:47:07.152 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "  "id": "<[email protected]>",[\n]"
16:47:07.152 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "  "message": "Queued. Thank you."[\n]"
16:47:07.152 [main] DEBUG org.apache.http.wire - http-outgoing-0 << "}"