How do I use logical expression in Spring EL?

In the previous example you have learnt How do I compare values in Spring EL?. Where you saw how to compare two simple values for equality, less-than or greater-than, etc. In practice, you might need to combine one or more of this comparison into a more complex logical expressions.

Spring EL also provides several operators that can be used to do this kind of logical operations. These operators are shown in the following table.

Operator Description
and A logical AND operation; the result will be true of both sides are true.
or A logical OR operation; the result will be true if at least on side is true.
not or ! A logical NOT operation; it will negates the expression value.

Here is an example using the logical and operator in the spring configuration file:

<property name="largeGlass" value="#{smallGlass.maxVolume ge 20 and smallGlass.maxVolume le 30}"/>

The configuration above will set the largeGlass property above to true if the glass maxVolume is greater-that-or-equal to 20 and less-than-or-equal to 30. It will only be considered as a large glass if the volume is between 20 and 30. So we use the logical and operator in that expression to evaluate the value for the largeGlass property. Now let’s see the complete example.

First let’s define the MyOtherGlass pojo.

package org.kodejava.spring.core.el;

public class MyOtherGlass {
    private boolean empty;
    private boolean halfEmpty;
    private int volume;
    private int maxVolume;
    private boolean largeGlass;

    public MyOtherGlass() {
    }

    public MyOtherGlass(int volume, int maxVolume) {
        this.volume = volume;
        this.maxVolume = maxVolume;
    }

    public boolean isEmpty() {
        return empty;
    }

    public void setEmpty(boolean empty) {
        this.empty = empty;
    }

    public boolean isHalfEmpty() {
        return halfEmpty;
    }

    public void setHalfEmpty(boolean halfEmpty) {
        this.halfEmpty = halfEmpty;
    }

    public int getVolume() {
        return volume;
    }

    public void setVolume(int volume) {
        this.volume = volume;
    }

    public int getMaxVolume() {
        return maxVolume;
    }

    public void setMaxVolume(int maxVolume) {
        this.maxVolume = maxVolume;
    }

    public boolean isLargeGlass() {
        return largeGlass;
    }

    public void setLargeGlass(boolean largeGlass) {
        this.largeGlass = largeGlass;
    }
}

After creating the pojo, let’s now create our spring configuration file where we define the smallGlass bean and the largeGlass bean.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="smallGlass" class="org.kodejava.spring.core.el.MyOtherGlass">
        <constructor-arg name="volume" value="5" />
        <constructor-arg name="maxVolume" value="10" />
        <property name="largeGlass" value="#{smallGlass.maxVolume ge 20 and smallGlass.maxVolume le 30}" />
    </bean>
    <bean id="largeGlass" class="org.kodejava.spring.core.el.MyOtherGlass">
        <constructor-arg name="volume" value="5" />
        <constructor-arg name="maxVolume" value="30" />
        <property name="largeGlass" value="#{largeGlass.maxVolume ge 20 and largeGlass.maxVolume le 30}" />
    </bean>

</beans>

And finally let’s create a class to run this configuration file in the console:

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELLogicalExpression {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spel-logical-expression.xml")) {

            MyOtherGlass smallGlass =
                    (MyOtherGlass) context.getBean("smallGlass");
            MyOtherGlass largeGlass =
                    (MyOtherGlass) context.getBean("largeGlass");

            System.out.println("smallGlass.isLargeGlass() = " + smallGlass.isLargeGlass());
            System.out.println("largeGlass.isLargeGlass() = " + largeGlass.isLargeGlass());
        }
    }
}

This code will give you the following output when executed:

smallGlass.isLargeGlass() = false
largeGlass.isLargeGlass() = true

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I compare values in Spring EL?

In Spring EL you can compare two values to know if they are equals, is greater or smaller than the other value. For these kinds of comparison, below are the list of operators supported by Spring EL, as expected it supports the same operators as in the Java programming language.

The Spring Expression Language comparison operators includes:

Symbol Textual Description
== eq Double-equal operator to compare two values for equality.
< lt Less-than operator to compare if a value is smaller than the other value.
> gt Greater-than operator to compare if a value is greater than the other value.
<= le Less-than-or-equal operator to compare if a value is smaller or equals to another value.
>= ge Greater-than-or-equal operator to compare if a value is greater or equals to another value.

For example, you can use the double-equal operator like the following XML configuration:

<property name="empty" value="#{myGlass.volume == 0}"/>

It means that we are going to set the empty property to be either a boolean true or false if the value of myGlass.volume is equal to 0 or not. The double-equal symbol is not a problem when use in the XML document. But you will understand right away that you can’t use the less-than (<) or greater-than (>) symbol in XML, because the characters is used to define the XML document itself.

To make it work we must use the textual version of these operators. For example, you will use the lt instead of < symbol or gt instead of the > symbol as can be seen in the table above. Now let’s see an example in the spring configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myGlass" class="org.kodejava.spring.core.el.MyGlass">
        <constructor-arg name="volume" value="5" />
        <constructor-arg name="maxVolume" value="10" />
        <property name="empty" value="#{myGlass.volume == 0}" />
        <property name="halfEmpty" value="#{(myGlass.maxVolume / 2) le myGlass.volume}" />
    </bean>

</beans>

In the above configuration we have a bean called myGlass. We instantiate it with two constructor values, the volume was set to 5 and the maxVolume was set to 10. To set the value of the empty and halfEmpty property we use the double-equal and less-than-equal operator to check the value of the volume and maxVolume properties.

After you have the spring configuration, let’s create the MyGlass bean and an application to run the configuration file. The bean is just a simple class with some properties and a collections of getters and setters.

package org.kodejava.spring.core.el;

public class MyGlass {
    private boolean empty;
    private boolean halfEmpty;
    private int volume;
    private int maxVolume;

    public MyGlass() {
    }

    public MyGlass(int volume, int maxVolume) {
        this.volume = volume;
        this.maxVolume = maxVolume;
    }

    public boolean isEmpty() {
        return empty;
    }

    public void setEmpty(boolean empty) {
        this.empty = empty;
    }

    public boolean isHalfEmpty() {
        return halfEmpty;
    }

    public void setHalfEmpty(boolean halfEmpty) {
        this.halfEmpty = halfEmpty;
    }

    public int getVolume() {
        return volume;
    }

    public void setVolume(int volume) {
        this.volume = volume;
    }

    public int getMaxVolume() {
        return maxVolume;
    }

    public void setMaxVolume(int maxVolume) {
        this.maxVolume = maxVolume;
    }
}

To run the spring configuration above you can create the SpELCompareValue class below.

package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELCompareValue {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context = new
                ClassPathXmlApplicationContext("spel-compare-value.xml")) {
            MyGlass glass = (MyGlass) context.getBean("myGlass");
            System.out.println("glass.getVolume()   = " + glass.getVolume());
            System.out.println("glass.isEmpty()     = " + glass.isEmpty());
            System.out.println("glass.isHalfEmpty() = " + glass.isHalfEmpty());
        }
    }
}

And when you executed the code above you will get the following output:

glass.getVolume()   = 5
glass.isEmpty()     = false
glass.isHalfEmpty() = true

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I access static methods or constants in Spring EL?

In this example you will learn how to access class-scoped methods or constants using Spring Expression Language. To access a class-scoped methods or constants you will need to use the T() operator of the Spring EL, for example T(java.lang.Math). This operator will give us the access to static methods and constants on a given class. As an example we can access the Math.PI in Spring EL like T(java.lang.Math).PI.

Just like accessing the static constants we can also access a static method in the same way. For example, we can call the Math.random() method in Spring EL like this T(java.lang.Math).random().

Now let’s see how we do these inside a spring configuration file. In this configuration we create a bean called myBean that have properties such as randomNumber, pi and name.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myBean" class="org.kodejava.spring.core.el.MyOtherBean">
        <property name="randomNumber" value="#{T(java.lang.Math).random()}" />
        <property name="pi" value="#{T(java.lang.Math).PI}" />
        <property name="name" value="#{T(org.kodejava.spring.core.el.MyOtherBean).BEAN_NAME}" />
    </bean>

</beans>

Here are our bean class and an application class that run the spring configuration for the demo.

package org.kodejava.spring.core.el;

public class MyOtherBean {
    public static final String BEAN_NAME = "MyOtherBean";

    private String randomNumber;
    private String pi;
    private String name;

    public String getRandomNumber() {
        return randomNumber;
    }

    public void setRandomNumber(String randomNumber) {
        this.randomNumber = randomNumber;
    }

    public String getPi() {
        return pi;
    }

    public void setPi(String pi) {
        this.pi = pi;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package org.kodejava.spring.core.el;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpELStaticDemo {
    public static void main(String[] args) {
        try (ClassPathXmlApplicationContext context =
                     new ClassPathXmlApplicationContext("spring-spel-static.xml")) {
            MyOtherBean bean = (MyOtherBean) context.getBean("myBean");
            System.out.println("bean.getRandomNumber() = " + bean.getRandomNumber());
            System.out.println("bean.getPi()           = " + bean.getPi());
            System.out.println("bean.getName()         = " + bean.getName());
        }
    }
}

When executing the program you will get the following result as the output:

bean.getRandomNumber() = 0.7173165965231882
bean.getPi()           = 3.141592653589793
bean.getName()         = MyOtherBean

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>5.3.23</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.23</version>
    </dependency>
</dependencies>

Maven Central Maven Central Maven Central

How do I receive mail using POP3?

In this example you will learn how to receive email using POP3. We are going to connect to Gmail server and read the messages in the INBOX folder. There are some steps that you need to do to download this email. Here are the steps:

  1. Setup properties for the mail session.
  2. Creates a javax.mail.Authenticator object.
  3. Creating mail session.
  4. Get the POP3 store provider and connect to the store.
  5. Get folder and open the INBOX folder in the store.
  6. Retrieve the messages from the folder.
  7. Close folder and close store.

These steps can be written as the following code snippet:

package org.kodejava.mail;

import javax.mail.*;
import java.util.Properties;

public class ReadEmail {
    public static final String USERNAME = "kodejava";
    public static final String PASSWORD = "password";

    public static void main(String[] args) throws Exception {
        // 1. Setup properties for the mail session.
        Properties props = new Properties();
        props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.pop3.socketFactory.fallback", "false");
        props.put("mail.pop3.socketFactory.port", "995");
        props.put("mail.pop3.port", "995");
        props.put("mail.pop3.host", "pop.gmail.com");
        props.put("mail.pop3.user", ReadEmail.USERNAME);
        props.put("mail.store.protocol", "pop3");
        props.put("mail.pop3.ssl.protocols", "TLSv1.2");

        // 2. Creates a javax.mail.Authenticator object.
        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(ReadEmail.USERNAME, ReadEmail.PASSWORD);
            }
        };

        // 3. Creating mail session.
        Session session = Session.getDefaultInstance(props, auth);

        // 4. Get the POP3 store provider and connect to the store.
        Store store = session.getStore("pop3");
        store.connect("pop.gmail.com", ReadEmail.USERNAME, ReadEmail.PASSWORD);

        // 5. Get folder and open the INBOX folder in the store.
        Folder inbox = store.getFolder("INBOX");
        inbox.open(Folder.READ_ONLY);

        // 6. Retrieve the messages from the folder.
        Message[] messages = inbox.getMessages();
        for (Message message : messages) {
            message.writeTo(System.out);
        }

        // 7. Close folder and close store.
        inbox.close(false);
        store.close();
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I create a simple mail client program in Swing?

The code snippet below show you how to create a simple Java Swing application that can be used to send an e-mail. The program allows user to supply the from email address, to email address, the subject and the message of the email. User need to select the available SMTP server to connect to and provide the username and password for authentication to the mail server.

Here is the user interface of this simple email client:

Simple E-mail Client

Simple E-mail Client

The main routine for sending the email is in the SendEmailActionListener class, which is an implementation of an ActionListener interface that will handle email sending process when Send E-mail button is pressed.

package org.kodejava.mail;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Properties;

public class SendEmailClient extends JFrame {
    private final JTextField fromField = new JTextField();
    private final JTextField toField = new JTextField();
    private final JTextField subjectField = new JTextField();
    private final JComboBox<String> mailSmtpHostComboBox = new JComboBox<>();
    private final JTextField usernameField = new JTextField();
    private final JPasswordField passwordField = new JPasswordField();
    private final JTextArea contentTextArea = new JTextArea();

    private SendEmailClient() {
        InitializeUI();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SendEmailClient client = new SendEmailClient();
            client.setVisible(true);
        });
    }

    private void InitializeUI() {
        setTitle("Send E-mail Client");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(new Dimension(500, 500));

        getContentPane().setLayout(new BorderLayout());

        // Header Panel
        JPanel headerPanel = new JPanel();
        headerPanel.setLayout(new GridLayout(6, 2));
        headerPanel.add(new JLabel("From:"));
        headerPanel.add(fromField);

        headerPanel.add(new JLabel("To:"));
        headerPanel.add(toField);

        headerPanel.add(new JLabel("Subject:"));
        headerPanel.add(subjectField);

        headerPanel.add(new JLabel("SMTP Server:"));
        headerPanel.add(mailSmtpHostComboBox);
        mailSmtpHostComboBox.addItem("smtp.gmail.com");

        headerPanel.add(new JLabel("Username:"));
        headerPanel.add(usernameField);

        headerPanel.add(new JLabel("Password:"));
        headerPanel.add(passwordField);

        // Body Panel
        JPanel bodyPanel = new JPanel();
        bodyPanel.setLayout(new BorderLayout());
        bodyPanel.add(new JLabel("Message:"), BorderLayout.NORTH);
        bodyPanel.add(contentTextArea, BorderLayout.CENTER);

        JPanel footerPanel = new JPanel();
        footerPanel.setLayout(new BorderLayout());
        JButton sendMailButton = new JButton("Send E-mail");
        sendMailButton.addActionListener(new SendEmailActionListener());

        footerPanel.add(sendMailButton, BorderLayout.SOUTH);

        getContentPane().add(headerPanel, BorderLayout.NORTH);
        getContentPane().add(bodyPanel, BorderLayout.CENTER);
        getContentPane().add(footerPanel, BorderLayout.SOUTH);
    }

    private class SendEmailActionListener implements ActionListener {
        SendEmailActionListener() {
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Properties props = new Properties();
            props.put("mail.smtp.host", mailSmtpHostComboBox.getSelectedItem());
            props.put("mail.transport.protocol", "smtp");
            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.auth", "true");
            props.put("mail.smtp.port", "465");
            props.put("mail.smtp.socketFactory.port", "465");
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.ssl.protocols", "TLSv1.2");

            Session session = Session.getDefaultInstance(props);
            try {
                InternetAddress fromAddress = new InternetAddress(fromField.getText());
                InternetAddress toAddress = new InternetAddress(toField.getText());

                Message message = new MimeMessage(session);
                message.setFrom(fromAddress);
                message.setRecipient(Message.RecipientType.TO, toAddress);
                message.setSubject(subjectField.getText());
                message.setText(contentTextArea.getText());

                Transport.send(message, usernameField.getText(),
                        new String(passwordField.getPassword()));
            } catch (MessagingException ex) {
                ex.printStackTrace();
            }
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>javax.mail-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>
</dependencies>

Maven Central Maven Central