A modern and lightweight library for working with email addresses in Java

Overview

JMail

Maven Central Javadoc Coverage Status

A modern, fast, zero-dependency library for working with email addresses and performing email address validation in Java.

Built for Java 8 and up.

Try out the algorithm online!

Why JMail?InstallationUsageIP ValidationContributing

Why JMail?

JMail was built mainly because I wanted to tackle the complex problem of email address validation without using Regex. Along the way, JMail became a much better choice than other Java email validation libraries (such as Apache Commons Validator or Jakarta (Javax) Mail Validation) for the following reasons:

  1. JMail is more correct than other libraries. For example, both Apache Commons and Jakarta Mail consider first@[email protected] as a valid email address! It clearly is not, as it has two @ characters. JMail correctly considers this address invalid. You can see a full comparison of correctness and try it out for yourself online.

  2. JMail is faster than other libraries by, on average, at least 2x, thanks in part to lack of regex.

  3. JMail has zero dependencies and is very lightweight.

  4. JMail is modern. It is built for Java 8+, and provides many useful methods and data accessors.

Click here for a full report of the differences in correctness and speed between JMail and other libraries.

While JMail is more correct than other libraries, I cannot guarantee that it is 100% correct. Email RFCs are long and complex, and I have likely missed some specific details. Please open an issue if you find an incorrect validation result for a specific email (or even better, a pull request with a fix).

I also highly recommend that you send verification emails to user-provided email addresses. This is the only way to ensure that the email address exists and that the recipient wants that email address to be used.

Installation

Add this library as a dependency in your pom.xml:

<dependency>
  <groupId>com.sanctionco.jmail</groupId>
  <artifactId>jmail</artifactId>
  <version>1.2.2</version>
</dependency>

Usage

Standard Email Validation

To perform standard email validation, use the static methods available in JMail. For example, to test validation:

String email = "[email protected]";

if (JMail.isValid(email)) {
  // Work with your email string
}

Or to enforce validation, throwing an InvalidEmailException on failure:

String email = "[email protected]";

try {
  JMail.enforceValid(email);
  
  // Work with your email string
} catch (InvalidEmailException) {
  // Handle invalid email
}

Custom Email Validation

JMail also provides an EmailValidator class that allows for much more customization of what constitutes a valid email address. You can require additional common validation rules, or supply your own. For example:

// In general, you should use JMail.strictValidator()
EmailValidator validator = JMail.strictValidator()
    // Require that the top-level-domain is ".com"
    .requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM)
    // Require that the local-part starts with "allowed"
    .withRule(email -> email.localPart().startsWith("allowed"));

boolean valid = validator.isValid("[email protected]");
boolean invalidWithoutTld = validator.isValid("allowed@test");
boolean invalidWithoutDotCom = validator.isValid("[email protected]");
boolean invalidWithoutAllowed = validator.isValid("[email protected]");

The Email Object

JMail also includes an Email object that makes working with email addresses easier. The Email object has the following properties:

Property getter Description Example using test(hello)@(world)example.one.com
localPart() The local-part of the email address test(hello)
localPartWithoutComments() The local-part of the email address without comments test
domain() The domain of the email address (world)example.one.com
domainWithoutComments() The domain of the email address without comments example.one.com
domainParts() A list of the parts of the domain [example, one, com]
identifier() The identifier of the email address, if it has one. null
(For Admin <[email protected]>, it would be Admin)
comments() A list of the comments in the email address [hello, world]
explicitSourceRoutes() A list of explicit source routes in the address, if present []
(For @1st.relay,@2nd.relay:[email protected], it would be [1st.relay, 2nd.relay])
isIpAddress() Whether or not the domain is an IP address false
hasIdentifier() Whether or not the address has an identifier false
topLevelDomain() The TopLevelDomain of the email address, or TopLevelDomain.OTHER if it is unknown TopLevelDomain.DOT_COM

To create a new instance of Email from a string, use the tryParse(String email) method, either the default version or on your own EmailValidator instance:

Optional<Email> parsed = JMail.tryParse("[email protected]");

Optional<Email> parsed = JMail.validator()
    .disallowIpDomain()
    .tryParse("[email protected]");

Since tryParse(String email) returns an Optional<Email>, you can do some cool things, such as:

Use a default email address

String email = JMail.tryParse("invalidEmailString")
    .map(Email::toString)
    .orElse("[email protected]");

Send an email if the address is valid

JMail.tryParse("[email protected]")
    .ifPresentOrElse(
        email -> myEmailService.sendTo(email.toString()),
        () -> log.error("Could not send email to invalid email"));

Additional Validation Rules

Disallow IP Address Domain

Although an email with an IP address in the domain is valid, these email addresses are often rejected from mail servers or only used for spam. You can require that your EmailValidator reject all emails with an IP address in the domain:

JMail.validator().disallowIpDomain();

Note: JMail.strictValidator() includes this rule automatically.

Require a Top Level Domain

Although an email address can be a local domain name with no TLD, ICANN highly discourages dotless email addresses. You can require that your EmailValidator reject all emails without a TLD:

JMail.validator().requireTopLevelDomain();

Note: JMail.strictValidator() includes this rule automatically.

Disallow Explicit Source Routing

Explicit source routing has been deprecated as of RFC 5321 and you SHOULD NOT use explicit source routing except under unusual circumstances.

JMail.validator().disallowExplicitSourceRouting();

Note: JMail.strictValidator() includes this rule automatically.

Disallow Reserved Domains

As specified in RFC 2606, some domains are reserved and should not be resolvable. Mail addressed to mailboxes in those reserved domains (and their subdomains) should be non-deliverable. You can require that your EmailValidator reject all emails that have a reserved domain:

JMail.validator().disallowReservedDomains();

Disallow Quoted Identifiers

If you want email addresses to only be the raw email address, use this rule. Adding this will invalidate addresses of the form John Smith <[email protected]>.

JMail.validator().disallowQuotedIdentifiers();

Require a specific common Top Level Domain

You can require that your EmailValidator reject all emails that have a top-level domain other than the ones you specify:

JMail.validator().requireOnlyTopLevelDomains(TopLevelDomain.DOT_COM);
JMail.validator().requireOnlyTopLevelDomains(
    TopLevelDomain.DOT_NET, TopLevelDomain.DOT_EDU);

Bonus: IP Address Validation

Since validating email addresses requires validation of IP addresses, these IP address validation methods are exposed for your convenience!

Determine if an IP Address is Valid

String ipv4 = "12.34.56.78";

if (InternetProtocolAddress.isValid(ipv4)) {
  // Use address
}
String ipv6 = "IPv6:2001:db8::1234:5678";

if (InternetProtocolAddress.isValid(ipv6)) {
  // Use address
}

Enforce an IP Address to be Valid

String ipv4 = "12.34.56.78";

try {
  InternetProtocolAddress.enforceValid(ipv4);
} catch (InvalidAddressException e) {
  // Failure
}
String ipv6 = "IPv6:2001:db8::1234:5678";

try {
  InternetProtocolAddress.enforceValid(ipv6);
} catch (InvalidAddressException e) {
  // Failure
}

Validate and return the IP

String ipv4 = "12.34.56.78";

Optional<String> validated = InternetProtocolAddress.validate(ipv4);

// The validate() method allows for convenience such as:
String ip = InternetProtocolAddress
    .validate("notvalid")
    .orElse("0.0.0.0");
String ipv6 = "IPv6:2001:db8::1234:5678";

Optional<String> validated = InternetProtocolAddress.validate(ipv6);

// The validate() method allows for convenience such as:
String ip = InternetProtocolAddress
    .validate("notvalid")
    .orElse("IPv6:2001:db8::1234:5678");

Contributing

All contributions are welcome! Open issues for bug reports or feature requests. Pull requests with fixes or enhancements are encouraged.

Comments
  • Don't use an enum for TopLevelDomain.

    Don't use an enum for TopLevelDomain.

    Why?

    Currently there is no way to build a validator that only matches, say, emails with the .dev TLD. Given the huge list of TLDs that are available it probably makes sense to let users write in a custom TLD and not lose that information.

    In this context, an enum isn't good enough since there is no way to attach a variable string to the OTHER case.

    Open questions

    • Now that fromString can accept any string, should we be doing validation on the TLDs? There seem to be rules about what can be a valid TLD that could be asserted at the time of creation.
    • What to do in the case that a tld is created like TopLevelDomain.fromString("test") that is potentially invalid but still well formed.
    • Should the result of fromString be guaranteed to == another call to fromString? In this implementation TopLevelDomain.fromString("com") will equal TopLevelDomain.DOT_COM with .equals, but not with ==. Its likely okay to make that be true now, but if you wanted to add all the known TLDs as constants doing the lookup could be a performance hit.
    opened by bowbahdoe 7
  • IllegalArgumentException when validating email address ending with

    IllegalArgumentException when validating email address ending with "High Octet Preset" control character

    Using JMail 1.3.2 to validate an email address ending with a "High Octet Preset" control character, e.g. JMail.isValid("[email protected]\u0081"); fails with:

    java.lang.IllegalArgumentException: java.text.ParseException: A prohibited code point was found in the inputcom
    	at java.base/java.net.IDN.toASCIIInternal(IDN.java:275)
    	at java.base/java.net.IDN.toASCII(IDN.java:123)
    	at com.sanctionco.jmail.JMail.isValidIdn(JMail.java:512)
    	at com.sanctionco.jmail.JMail.lambda$tryParse$0(JMail.java:119)
    	at java.base/java.util.Optional.filter(Optional.java:218)
    	at com.sanctionco.jmail.JMail.tryParse(JMail.java:119)
    	at com.sanctionco.jmail.JMail.isValid(JMail.java:67)
    Caused by: java.text.ParseException: A prohibited code point was found in the inputcom
    	at java.base/jdk.internal.icu.text.StringPrep.prepare(StringPrep.java:448)
    	at java.base/java.net.IDN.toASCIIInternal(IDN.java:273)
    	... 74 more
    

    I guess that is not the expected behavior, or am I wrong?

    By the way: Thank you very much for developing JMail! It is the best Java E-Mail validation library.

    bug 
    opened by PascalSchumacher 5
  • Add ValidationRule to disallow whitespace in the local-part and domain

    Add ValidationRule to disallow whitespace in the local-part and domain

    Using JMail 1.4.0 this test passes:

    @Test
    void test() {
        assertTrue(JMail.isValid("a@b .com"));
        assertTrue(JMail.isValid("a. [email protected]"));
    }
    

    Are these valid email addresses?

    The first one lead to a javax.mail.internet.AddressException: Domain contains control or whitespace in string ''a@b .com'' when I try to use it with java mail.

    By the way: Thank you very much for providing JMail. It is the best java libary to validate e-mail adresses! 👍

    enhancement 
    opened by PascalSchumacher 3
  • Feature request: some sort of email normalization?

    Feature request: some sort of email normalization?

    Given the quite loose definition of the email standard forms, it could be useful to provide some sort of normalization of the Email object, to render it in a way that most people commonly recognize as a plain and bare email address. That would be equivalent to stripping comments, optional parts, etc.: email.localPartWithoutComments() + "@" + email.domainWithoutComments(). This feature could be useful for example when we not only want to validate the address as a mail recipient, but use it as some sort of identifier (for example in login systems).

    enhancement question 
    opened by psimonazzi 3
  • invalid address returning true

    invalid address returning true

    Is this bug report about an incorrectly validated email address?

    • [x] Yes
    • [ ] No

    If yes, what is the email address? agadgf@fsaf

    • [ ] Valid
    • [x] Invalid

    If no, please describe the bug This returns true but should return false ret = JMail.isValid("agadgf@fsaf");

    Additional context

    bug 
    opened by goodale 2
  • StringIndexOutOfBoundsException

    StringIndexOutOfBoundsException

    E Error ABC.DEF@GHI. (MNO) index 0,length 0 java.lang.StringIndexOutOfBoundsException: index 0,length 0 at java.base/java.lang.String.checkIndex(String.java:3278) at java.base/java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:307) at java.base/java.lang.StringBuilder.charAt(StringBuilder.java:85) at com.sanctionco.jmail.JMail.internalTryParse(JMail.java:374) at com.sanctionco.jmail.JMail.tryParse(JMail.java:100) at com.sanctionco.jmail.JMail.isValid(JMail.java:67) at de.fk.email.TestJMail1.isValid(TestJMail1.java:20) at de.fk.email.TestJMail1.main(TestJMail1.java:10)

    E Error [email protected] .
    index 0,length 0 java.lang.StringIndexOutOfBoundsException: index 0,length 0 at java.base/java.lang.String.checkIndex(String.java:3278) at java.base/java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:307) at java.base/java.lang.StringBuilder.charAt(StringBuilder.java:85) at com.sanctionco.jmail.JMail.internalTryParse(JMail.java:374) at com.sanctionco.jmail.JMail.tryParse(JMail.java:100) at com.sanctionco.jmail.JMail.isValid(JMail.java:67) at de.fk.email.TestJMail1.isValid(TestJMail1.java:20) at de.fk.email.TestJMail1.main(TestJMail1.java:11)

    public class TestJMail1 { public static void main( String[] args ) { isValid( "[email protected] (MNO)" ); isValid( "ABC.DEF@GHI. (MNO)" ); isValid( "[email protected] . " );

    System.exit( 0 );
    

    }

    private static boolean isValid( String pInput ) { try { if ( JMail.isValid( pInput ) ) { System.out.println( "+ eMail " + pInput + " is valid" );

        return true;
      }
    
      System.out.println( "- eMail " + pInput + " is not valid" );
    }
    catch ( Exception err_inst )
    {
      System.out.println( "\n\nE Error " + pInput );
    
      System.out.println( err_inst.getMessage() );
    
      err_inst.printStackTrace( System.out );
    
      System.out.println( "\n" );
    }
    
    return false;
    

    } }

    opened by ea234 2
  • Bump assertj-core from 3.20.0 to 3.20.1

    Bump assertj-core from 3.20.0 to 3.20.1

    Bumps assertj-core from 3.20.0 to 3.20.1.

    Commits
    • fc6c3b5 [maven-release-plugin] prepare release assertj-core-3.20.1
    • f3398db Fix array comparison with null values (#2261)
    • 8e33c97 Bump assertj-parent-pom from 2.2.10 to 2.2.13 (#2260)
    • ddff1fc Bump org.eclipse.osgi from 3.16.200 to 3.16.300 (#2259)
    • c4cee17 Move pitest-github-maven-plugin declaration to POM plugin management
    • b19af7b Bump assertj-core version under OSGi configuration
    • 57c18a1 [maven-release-plugin] prepare for next development iteration
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies java 
    opened by dependabot[bot] 2
  • Addressess with explicit source routing are not valid

    Addressess with explicit source routing are not valid

    Is this bug report about an incorrectly validated email address?

    • [x] Yes
    • [ ] No

    If yes, what is the email address?

    @1st.relay,@2nd.relay:[email protected]

    • [x] Valid
    • [ ] Invalid

    If no, please describe the bug

    Address syntax https://datatracker.ietf.org/doc/html/rfc822#section-6.1 Example of such address with explicit routes https://datatracker.ietf.org/doc/html/rfc1711#section-7

    Additional context

    Not sure if this was superseded by newer RFCs

    bug 
    opened by XakepSDK 2
  • Bump junit.version from 5.9.0 to 5.9.1

    Bump junit.version from 5.9.0 to 5.9.1

    ⚠️ Dependabot is rebasing this PR ⚠️

    Rebasing might not happen immediately, so don't worry if this takes some time.

    Note: if you make any changes to this PR yourself, they will take precedence over the rebase.


    Bumps junit.version from 5.9.0 to 5.9.1. Updates junit-jupiter-engine from 5.9.0 to 5.9.1

    Release notes

    Sourced from junit-jupiter-engine's releases.

    JUnit 5.9.1 = Platform 1.9.1 + Jupiter 5.9.1 + Vintage 5.9.1

    See Release Notes.

    Commits
    • 732a540 Release 5.9.1
    • 88bf48d Prepare release notes for 5.9.1
    • d75e34d Update scope for 5.9.1
    • 9823f73 Link to all 5.9 milestone pages
    • 76719bb Increase timeout for GraalVM test
    • 2a80984 Install GraalVM for main CI build on Linux
    • 79f47f5 Refactor OpenTestReportGeneratingListener to work in native images
    • 7229385 Add failing integration test for execution on GraalVM native image
    • 343170f Fix running tests in documentation from IntelliJ IDEA
    • 352d06b Attempt to stabilize test on Windows
    • Additional commits viewable in compare view

    Updates junit-jupiter-params from 5.9.0 to 5.9.1

    Release notes

    Sourced from junit-jupiter-params's releases.

    JUnit 5.9.1 = Platform 1.9.1 + Jupiter 5.9.1 + Vintage 5.9.1

    See Release Notes.

    Commits
    • 732a540 Release 5.9.1
    • 88bf48d Prepare release notes for 5.9.1
    • d75e34d Update scope for 5.9.1
    • 9823f73 Link to all 5.9 milestone pages
    • 76719bb Increase timeout for GraalVM test
    • 2a80984 Install GraalVM for main CI build on Linux
    • 79f47f5 Refactor OpenTestReportGeneratingListener to work in native images
    • 7229385 Add failing integration test for execution on GraalVM native image
    • 343170f Fix running tests in documentation from IntelliJ IDEA
    • 352d06b Attempt to stabilize test on Windows
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies java 
    opened by dependabot[bot] 1
  • Bump junit.version from 5.8.2 to 5.9.0

    Bump junit.version from 5.8.2 to 5.9.0

    Bumps junit.version from 5.8.2 to 5.9.0. Updates junit-jupiter-engine from 5.8.2 to 5.9.0

    Release notes

    Sourced from junit-jupiter-engine's releases.

    JUnit 5.9.0 = Platform 1.9.0 + Jupiter 5.9.0 + Vintage 5.9.0

    See Release Notes.

    JUnit 5.9.0-RC1 = Platform 1.9.0-RC1 + Jupiter 5.9.0-RC1 + Vintage 5.9.0-RC1

    See Release Notes.

    JUnit 5.9.0-M1 = Platform 1.9.0-M1 + Jupiter 5.9.0-M1 + Vintage 5.9.0-M1

    See Release Notes.

    Commits

    Updates junit-jupiter-params from 5.8.2 to 5.9.0

    Release notes

    Sourced from junit-jupiter-params's releases.

    JUnit 5.9.0 = Platform 1.9.0 + Jupiter 5.9.0 + Vintage 5.9.0

    See Release Notes.

    JUnit 5.9.0-RC1 = Platform 1.9.0-RC1 + Jupiter 5.9.0-RC1 + Vintage 5.9.0-RC1

    See Release Notes.

    JUnit 5.9.0-M1 = Platform 1.9.0-M1 + Jupiter 5.9.0-M1 + Vintage 5.9.0-M1

    See Release Notes.

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies java 
    opened by dependabot[bot] 1
  • Bump assertj-core from 3.23.0 to 3.23.1

    Bump assertj-core from 3.23.0 to 3.23.1

    Bumps assertj-core from 3.23.0 to 3.23.1.

    Commits
    • 0256688 [maven-release-plugin] prepare release assertj-core-3.23.1
    • 6529933 Downgrade junit-jupiter from 5.9.0-M1 to 5.8.2
    • d9cd2da [maven-release-plugin] prepare for next development iteration
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies java 
    opened by dependabot[bot] 1
  • When validation fails, provide a reason to the caller

    When validation fails, provide a reason to the caller

    [An enhancement, not a bug]

    Whenever an email fails to pass validation, no information is provided to the caller about what the problem was. Was there an invalid character in the domain? Were there multiple "@" characters? Was the "@" character missing? Was there no ending domain (part after the last dot?). Something else?

    I recommend adding some way for the caller to get back a string that describes the problem. These descriptions are mostly available in the code in the form of comments ("email cannot be more than 320 chars", "email cannot start with '.'", "email cannot end with '.' or '-'", etc.) but not available to the caller. Ideally the descriptions would be understandable to a naive end user.

    In comparison, https://github.com/lite2073/email-validator does a MUCH better job of providing a description of the exact cause of the problem, but that project is getting a bit stale.

    enhancement 
    opened by bobharner 1
  • Add documentation for all default validation rules

    Add documentation for all default validation rules

    This library is great! I would very much like to use it in a project I'm working on but I can't find any documentation that spells out each of the validation rules that it enforces. Do you have a list somewhere that I just missed?

    documentation 
    opened by scott-abernethy66 1
  • Option to validate MX record associated with email domains

    Option to validate MX record associated with email domains

    What a nice library you made, congratulations! I was wondering, what about adding an option to check that email domains have a valid MX record: at least one DNS record with an IP address?

    enhancement 
    opened by lpellegr 4
  • Improve website to describe what makes an email valid

    Improve website to describe what makes an email valid

    Based on a suggestion from Reddit:

    This is actually cool stuff, if you add more logic to it and explanations - why an address is invalid. Needs more work but could be turn into a pretty great site/service.

    documentation 
    opened by RohanNagar 0
Releases(v1.4.1)
  • v1.4.1(Feb 3, 2022)

    • Add new ValidationRule disallowObsoleteWhitespace() to consider email addresses with obsolete whitespace as invalid. (Thanks @PascalSchumacher for suggesting!)
    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Jan 19, 2022)

    • Add new normalized() method on the Email class to provide a way to get a "normalized" version of an email address (the address without any comments or optional parts).
    Source code(tar.gz)
    Source code(zip)
  • v1.3.3(Nov 16, 2021)

    • Fix bug where invalid characters in the domain could result in an IllegalArgumentException instead of returning false. (Thanks @PascalSchumacher for reporting!)
    Source code(tar.gz)
    Source code(zip)
  • v1.3.2(Oct 20, 2021)

  • v1.3.1(Sep 16, 2021)

  • v1.3.0(Sep 9, 2021)

    • InternetProtocolAddress.validate(String ip) now validates IPv6 addresses without requiring the IPv6: prefix.
    • Add new JMail.isInvalid(String email) and EmailValidator#isInvalid(String email) methods as a convenience for testing if an email address is invalid.
    Source code(tar.gz)
    Source code(zip)
  • v1.2.3(Sep 3, 2021)

    • Add toString() method on EmailValidator
    • Add withRules(Collection<Predicate<Email>> rules) method on EmailValidator to create a new EmailValidator from the collection of rules provided
    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Jun 29, 2021)

    • Fix bug where an exception would be thrown on invalid email addresses with whitespace or comments after a trailing . character. For example, abc.def@ghi. (comment) is invalid, and before this version JMail would throw an exception instead of return invalid. (Thanks @ea234 for reporting!)
    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(Jun 3, 2021)

  • v1.2.0(May 28, 2021)

    • Switch TopLevelDomain from an enum to a class, allowing for creation of any valid top level domain (Thanks @bowbahdoe!)
    • Add module-info.java so projects on JDK 9+ can use this library as a Java module
    • Bugfix: Addresses with empty quoted strings (""@test.org) are now correctly considered valid
    • Bugfix: Addresses with explicit source routing (@1st.relay,@2nd.relay:[email protected]) are now considered valid. However, explicit source routing is deprecated since RFC 5321. JMail.strictValidator() disallows explicit source routing by default
    • Bugfix: Addresses with quoted identifiers (John Smith <[email protected]>) are now correctly considered valid
    • New properties on the Email object:
      • identifier()
      • hasIdentifier()
      • explicitSourceRoutes()
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(May 22, 2021)

    • Disallow construction of utility classes and prevent classes from being subclassed (Thanks @bowbahdoe!)
    • Fix bug where email addresses that have a dotless domain or top level domain starting with the - character would be incorrectly classified as valid. For example, test@-foo and [email protected] should both be invalid.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.4(May 22, 2021)

  • v1.0.3(May 21, 2021)

  • v1.0.2(May 20, 2021)

  • v1.0.1(May 20, 2021)

  • v1.0.0(May 20, 2021)

Owner
Rohan Nagar
Developer at @box
Rohan Nagar
100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL

RuleBook » A Simple & Intuitive Rules Abstraction for Java 100% Java · Lambda Enabled · Simple, Intuitive DSL · Lightweight Why RuleBook? RuleBook rul

Delivered Technologies Labs 666 Dec 21, 2022
A low-level lightweight JSON Database for java

Simple JsonDB JsonDB is a fast, light-weight JSON key-value storage engine for Java What is key-value storage? Installation Pre-Requisites: Java 1.8 M

Alexandru Stan 5 Nov 27, 2022
A Java serialization/deserialization library to convert Java Objects into JSON and back

Gson Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to a

Google 21.7k Jan 8, 2023
A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back

A universal types-preserving Java serialization library that can convert arbitrary Java Objects into JSON and back, with a transparent support of any kind of self-references and with a full Java 9 compatibility.

Andrey Mogilev 9 Dec 30, 2021
Java with functions is a small java tools and utils library.

Java with functions is a small java tools and utils library.

null 4 Oct 14, 2022
Android processing and secured library for managing SharedPreferences as key-value elements efficiently and structurally.

Memo Android processing and secured library for managing SharedPreferences as key-value elements efficiently and structurally. 1. Depend on our librar

ZeoFlow 18 Jun 30, 2022
A JSON Transmission Protocol and an ORM Library for automatically providing APIs and Docs.

?? 零代码、热更新、全自动 ORM 库,后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构。 ?? A JSON Transmission Protocol and an ORM Library for automatically providing APIs and Docs.

Tencent 14.4k Dec 31, 2022
Screaming fast JSON parsing and serialization library for Android.

#LoganSquare The fastest JSON parsing and serializing library available for Android. Based on Jackson's streaming API, LoganSquare is able to consiste

BlueLine Labs 3.2k Dec 18, 2022
Jakarta money is a helpful library for a better developer experience when combining Money-API with Jakarta and MicroProfile API.

jakarta-money Jakarta money is a helpful library for a better developer experience when combining Money-API with Jakarta and MicroProfile API. The dep

Money and Currency API | JavaMoney 19 Aug 12, 2022
JSON to JSON transformation library written in Java.

Jolt JSON to JSON transformation library written in Java where the "specification" for the transform is itself a JSON document. Useful For Transformin

Bazaarvoice 1.3k Dec 30, 2022
Sawmill is a JSON transformation Java library

Update: June 25, 2020 The 2.0 release of Sawmill introduces a breaking change to the GeoIpProcessor to comply with the updated license of the MaxMind

Logz.io 100 Jan 1, 2023
Genson a fast & modular Java <> Json library

Genson Genson is a complete json <-> java conversion library, providing full databinding, streaming and much more. Gensons main strengths? Easy to use

null 212 Jan 3, 2023
Lean JSON Library for Java, with a compact, elegant API.

mJson is an extremely lightweight Java JSON library with a very concise API. The source code is a single Java file. The license is Apache 2.0. Because

Borislav Iordanov 77 Dec 25, 2022
A wayfast raycast java library.

NOTE: Rayfast is still in development and is not completely stable api-wise. GridCasting likely will not change, however Area3d's may have some improv

EmortalMC 19 Dec 20, 2022
Simple, efficient Excel to POJO library for Java

ZeroCell ZeroCell provides a simple API for loading data from Excel sheets into Plain Old Java Objects (POJOs) using annotations to map columns from a

Credit Data CRB 68 Dec 8, 2022
Java library to represent monetary amounts.

Joda-Money Joda-Money provides a library of classes to store amounts of money. Joda-Money does not provide, nor is it intended to provide, monetary al

Joda.org 599 Jan 4, 2023
Elide is a Java library that lets you stand up a GraphQL/JSON-API web service with minimal effort.

Elide Opinionated APIs for web & mobile applications. Read this in other languages: 中文. Table of Contents Background Documentation Install Usage Secur

Yahoo 921 Jan 3, 2023
JSON Library for Java with a focus on providing a clean DSL

JSON Library for Java with a focus on providing a clean DSL

Vaishnav Anil 0 Jul 11, 2022
High performance JVM JSON library

DSL-JSON library Fastest JVM (Java/Android/Scala/Kotlin) JSON library with advanced compile-time databinding support. Compatible with DSL Platform. Ja

New Generation Software Ltd 835 Jan 2, 2023