How to handle LoRA messages from thethingsnetwork from JavaEE with TTNClientJ2

10 Apr 2019 - tsp
Last update 16 Apr 2019
Reading time 4 mins

Note: The TTNClientJ2 library described herein is in no way associated with thethingsnetwork or their official software. It is my own implementation to handle messages received from them via MQTT.


The basic idea is to include the MQTT client that received messages from thethingsnetwork into the JavaEE application and run the client inside the same servlet container. The primary advantage over an extra application is that one has an self contained application archive that one can deploy via the simple deployment techniques of JavaEE (simply copying the web application archive inside the webapps folder of Apache Tomcat when automatic extraction is enable - as it is by default) to deploy the whole application including the MQTT client. It also allows to keep the configuration for the whole project in a single place. The only externally required component may be a database server although one could even bundle an SQLite database with the web application if one only has to store really small amounts of data.


The usage of TTNClientJ2 is really simple. Just add the JAR files for

to the WebContent/WEB-INF/lib folder (and if using an IDE update your local build path to search these libraries for classes)

Create an Handler that will receive messages from the TTN. The handler has to implement TTNMessageHandler. This interface provides two functions - the main handleTTNMessage function, that is called whenever a message (or an device event) is received, and the an additional initializeHandler function that gets called whenever the JavaEE context gets initialized. The latter function allows one to access the servlet context in case one requires initialization parameters (for example to initialize a database, etc.).

The most basic (test) handler might look like the following:

package at.tspi.examples.ttnclientj2.handler;

import javax.servlet.ServletContextEvent;

import at.tspi.ttnclientj2.client.TTNClient;
import at.tspi.ttnclientj2.client.TTNMessageHandler;
import at.tspi.ttnclientj2.messages.TTNMessage;

public class ExampleHandler implements TTNMessageHandler {
    public ExampleHandler() { }

    public boolean initializeHandler(ServletContextEvent sce) {
            We just signal that we have successfully initialized
        return true;

    public boolean handleTTNMessage(TTNMessage msg, TTNClient cli) {
        System.out.println("Message received: ");

        // To filter only upstream messages (no device events)
        if(msg instanceof TTNMessageUplink) {
            // Really a data containing message
        } else {
            // Device event or downlink status change

        return true;

Then one has to add configuration options to the WebContent/WEB-INF/web.xml configuration file.

The configuration is pretty simple. There are three basic configuration parameters. The first context parameter is ttnconnections. It contains a comma separated list of names of connections that should be automatically established on context initialization (i.e. most of the time this is equivalent to the deployment of the application container).


For every named connection there is an url and handler parameter. The URL parameter contains protocol, application ID and authentication information as well as the region that the client should connect to. To connect to an application in the EU region the URI would look like the following:


The handler specifies which class should be instantiated and invoked whenever a message arrives via this connection. This is the previously generated class:


Now everything is ready and one can simply build and deploy the web application archive.

Message types

The packets received by the TTN are passed as TTNMessage. Various types of messages exist:

This article is tagged:

Data protection policy

Dipl.-Ing. Thomas Spielauer, Wien (

This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support