Overview:

I have used NetBeans as a go-to Linux stack IDE for a very long time. It does a great job for C, C++, PHP, Java and general bash, Windows and SQL scripting, and has a intuitive git interface. Like Eclipse, NetBeans provides the ability to move back-and-forth between language-specific tools within the same IDE. Even while working a Windows project, I have found myself leaving Visual Studio for a bit to use NetBeans for a particular task or two.

This article describes how to quickly standup a NetBeans SpringBoot development environment, and build an example (but fully functional) enterprise-strength REST micro-service that serves up the current server time. This article is intended to get new-comers familiar with both NetBeans IDE and the SpringBoot framework. SpringBoot is an admitted “opinionated” framework and expects projects to be organized in a particular structure. I find SpringBoot projects run smoothly when you do not deviate too far from their intended path of coding structure, as resistance is futile.

NOTE: NetBeans will refer to SpringBoot projects as “Maven Projects”, as Maven is the build management system that shall be used by NetBeans and SpringBoot to build your micro-service jars.

Prerequisites:

  • Latest Java SDK installed and configured. At the time of this article, that is jdk-8u151-macosx-x64.dmg
    Use the following command to verify java is installed: java -version
  • Ensure that your JAVA_HOME and JRE_HOME environment variables are set.
    Use the following command to verify java is configured: echo $JAVA_HOME
  • Install the latest version of NetBeans. I usually install the entire distribution; however, you could install variants and install need feature “plugins” later. As of the date of this article, NetBeans 8.2 is the current version.
  • See disclaimer

1. NetBeans IDE SpringBoot Configuration Procedure:

  1. If you haven’t already done so, install Netbeans.
    Refer to: https://netbeans.org/kb/articles/mac.html
    Also, get familiar with NetBeans implementation of git
  2. Start up NetBeans.
  3. Click on Help | Check for Updates to get your IDE up to the latest revision.
  4. Click on Tools | Plugins and click on Installed.
  5. Ensure that Java EE Base, Spring Beans and Spring Web MVC are already installed; they should be installed as default items. Install these if necessary.
  6. Search for the NB SpringBoot plugin from Alex Falappa
    (https://github.com/AlexFalappa/nb-springboot)
  7. Install the NB SpringBoot plugin. You will be asked to restart the IDE. When you return to NetBeans, check for updates again to ensure you have the latest revision of the NB SpringBoot plugin and others.

That’s it. You ready to make your first SpringBoot REST Hello-world micro-service

2. SpringBoot Hello World with NetBeans

The Spring provides a kick-starter web service to create SpringBoot projects (https://start.spring.io). You can use this from your browser or have NetBeans access it and do it for you, as follows:

  1. Start NetBeans. Click on File | New Project. Under Maven, select Spring Boot Initializer project (is that misspelled in the GUI, could be).
  2. Click Next. You can keep the Base Project defaults, but I changed them to reflect our “Hello Netbeans” project. Also note the Java “package” directory naming convention; this is basically your domain in reverse as the base, followed by a sub-domain representing the project. This is the standard Java EJB method.
  3. The following screen is derived from the Spring project initializer web service (https://start.spring.io). These are the remote packages and associated dependencies that Maven will install and configure for us. So many goodies …
    All we will select for this project is the single dependency Web Services
  4. Click on Next, and it’s time to set our project folder location. Again, you can keep the defaults, but here is how I set it up:
  5. Let’s click on Finish to create our project stub.
    Don’t worry about what you see next, as this is the best part … NetBeans and Maven did a preliminary assessment of the dependencies you require to build the project and determined that there are things missing.
  6. Click on Close for now, as Maven will get what it needs during the first build.
  7. What you should see now is the SpringBoot POM, which is the Maven Project Object Reference.
  8. Expand the Source Packages tree in the left Projects pane, and you will find the application main class, named [ProjectName]Application
  9. Here is my main HelloNetBeansApplication class. I added lines 6, 7, 12, 18, and 19 to setup our syslog-style audit logger. Yes, that easy to add complete logging framework:
    package com.paulsdevblog.hellonetbeans;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    @SpringBootApplication
    public class HelloNetBeansApplication {
        
        public static final Logger logger = LoggerFactory.getLogger( HelloNetBeansApplication.class );
    
        public static void main(String[] args) {
            
            SpringApplication.run(HelloNetBeansApplication.class, args);
            
            logger.info("--Application Started--");
            logger.info("This is our Hello NetBeans and Hello World Micro-Service!");
        }
    }
    
  10. Time for first build. Right-click on the project and click Build with Dependencies.
    If everything went right, you should be greeted with a “Build Success” method.
    At this point you have a functional REST micro-service … no endpoints yet, but the house is framed. If you ran it, it will do nothing.

3. Now it’s Entity and MVC time!

As linked below, the project is in BitBucket, but the following is a break-down of how to stand up a simple MVC REST endpoint for an entity. In this example, I will make a simple entity that will represent a date-time request.

A “service” object level will be created to be a conduit between the “controller” layer and the entity objects. With more realistic data persistence applications, the service will be the conduit and driver between the “repository” layer accessing the RDBMS/Persistence system and the controller. The controller class will have the SpringBoot magic that serves up the JSON views auto-magically.

During the following, I will create a hierarchical folder structure that SpringBoot likes. This also provides extensibility and consistency among SpringBoot applications.

  1. First, let’s create a package (folder) to hold utility classes
    > com.yourdomain.hellonetbeans.utility
  2. Next, a DateTimeUtil class to get the current date-time in Java.Date, ISO 8601, and Epoch Second. This will feed our entity that we shall create. Note the exception handling that always returns a value, as these methods shall feed a constructor, and we can never have a constructor fail. For good form, I should have instantiated a logger here too, and put the logger.error methods in the catch blocks.
    package com.paulsdevblog.hellonetbeans.utility;
    
    import java.time.format.DateTimeFormatter;
    import java.time.Instant;
    import java.time.ZoneOffset;
    import java.time.ZonedDateTime;
    
    import java.util.Date;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * Simple utility methods to provide current date time
     *
     * @author paulsdevblog
     */
    public class DateTimeUtil {
     
        private static final long serialVersionUID = 1L;
    
        /**
         * Get current Java Date
         * 
         * @return Java Date
         */
        public Date now() {
            return new Date();
        }
        
        /**
         * Get current ISO 8601 date-time string
         * 
         * @return ISO 8601 string
         */
        public String nowISO8601(){
            
            String now_utc_dt = "";
            
            try {
            
                Instant instant = Instant.now();
    
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
    
                now_utc_dt = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).format(formatter);
    
                return now_utc_dt;
            } catch ( Exception ex ){
                return null;
            }
        }
        
        /**
         * Get current Unix Epoch Second
         * 
         * @return Epoch second
         */
        public long nowUnixEpoch(){
            
            long unix_epoch_ts = 0;
            
            try {
            
                Instant instant = Instant.now();
    
                unix_epoch_ts = instant.getEpochSecond();
    
                return unix_epoch_ts;
                
            } catch ( Exception ex ){
                return 0;
            }
        }
        
    }
    
  3. Now it’s time for MVC. Create the following package (folder) structure under Source Packages:
    > com.yourdomain.hellonetbeans.domain
    > com.yourdomain.hellonetbeans.domain.model
    > com.yourdomain.hellonetbeans.domain.controller
    > com.yourdomain.hellonetbeans.domain.service
  4. Right-click on the model package and create a class for the MyTime model. Here is where NetBeans provides some IDE heavy lifting and generates the code based on your structure:
    > Just create the four private properties listed below. The first is for serialization, and gets a @JsonIgnore annotation to tell the controller to ignore and not to publish.
    > Next, right-click in the class and select Insert Code
    > Start with the Getters and Setters, then Constructors, then HashCode/Equals, and end with ToString.
    > Clean up the tabs and formatting to taste.
    package com.paulsdevblog.hellonetbeans.domain.model;
    
    import java.io.Serializable;
    import java.util.Date;
    import java.util.Objects;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    
    
    /**
     * Simple entity example
     * This will hold date-time properties and the getters/setters used by the 
     * REST controller and jackson json libraries to render JSON views.
     *
     * @author www.paulsdevblog.com
     */
    public class MyTime implements Serializable {
    
        @JsonIgnore
        private static final long serialVersionUID = 1L;
        
        private Date currentDate;
        private String currentIso8601Dt;
        private long  currentEpochSecond;
    
        public MyTime(){}
        
        public MyTime(
            Date currentDate,
            String currentIso8601Dt, 
            long currentEpochSecond
        ){
            this.currentDate = currentDate;
            this.currentIso8601Dt = currentIso8601Dt;
            this.currentEpochSecond = currentEpochSecond;
        }
    
        public Date getCurrentDate() {
            return currentDate;
        }
    
        public void setCurrentDate(Date currentDate) {
            this.currentDate = currentDate;
        }
    
        public String getCurrentIso8601Dt() {
            return currentIso8601Dt;
        }
    
        public void setCurrentIso8601Dt(String currentIso8601Dt) {
            this.currentIso8601Dt = currentIso8601Dt;
        }
    
        public long getCurrentEpochSecond() {
            return currentEpochSecond;
        }
    
        public void setCurrentEpochSecond(long currentEpochSecond) {
            this.currentEpochSecond = currentEpochSecond;
        }
    
        @Override
        public int hashCode() {
            int hash = 7;
            hash = 79 * hash + Objects.hashCode(this.currentDate);
            hash = 79 * hash + Objects.hashCode(this.currentIso8601Dt);
            hash = 79 * hash + (int) (this.currentEpochSecond ^ (this.currentEpochSecond >>> 32));
            return hash;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final MyTime other = (MyTime) obj;
            if (this.currentEpochSecond != other.currentEpochSecond) {
                return false;
            }
            if (!Objects.equals(this.currentIso8601Dt, other.currentIso8601Dt)) {
                return false;
            }
            if (!Objects.equals(this.currentDate, other.currentDate)) {
                return false;
            }
            return true;
        }
    
        @Override
        public String toString() {
            return "MyTime{" 
                        + "currentDate=" + currentDate 
                        + ", currentIso8601Dt=" + currentIso8601Dt 
                        + ", currentEpochSecond=" + currentEpochSecond 
                    + '}';
        }
        
        
        
    }
    
  5. Create the service layer classes. We will start with the implementation class (ending in Impl), and then use NetBeans refactoring tool (right-click Refactor …) to generate an interface class in a few clicks.
    > Note how this class instantiates the utility class, then constructs a MyTime object using the utility class methods. The method returns the new object.
    > When you create the implementation class, you don’t need the “implements MyTimeService” and @Overrride annotations, these are added automatically by the NetBeans interface creation refactoring feature.
    > The @Service annotation is similar to the @Component annotation, and both will tell Spring to create a bean and auto-wire objects as needed.
    package com.paulsdevblog.hellonetbeans.domain.service;
    
    import org.springframework.stereotype.Service;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.paulsdevblog.hellonetbeans.domain.model.MyTime;
    import com.paulsdevblog.hellonetbeans.utility.DateTimeUtil;
    
    /**
     * Simple service layer example for MyTime
     *
     * @author paulsdevblog.com
     */
    @Service
    public class MyTimeServiceImpl implements MyTimeService {
        
        private static final Logger LOGGER = LoggerFactory.getLogger( MyTimeServiceImpl.class );
        
        @Override
        public MyTime getMyTime() {
            
            try {
            
                LOGGER.info("getMyTime called");
    
                DateTimeUtil dateTimeUtil = new DateTimeUtil();
    
                MyTime myTime = new MyTime( dateTimeUtil.now(), dateTimeUtil.nowISO8601(), dateTimeUtil.nowUnixEpoch() );
                
                return myTime;
                
            } catch (Exception ex){
                
                LOGGER.error("getMyTime Error: " + String.valueOf(ex.getMessage()));
                
                return null;
                
            }
            
        }
        
    }

4. Bring on the Controller

Now we are going to bring this together with the SpringBoot RestController features. This leverages all of the dependencies we included at the beginning of this article when we checked the “Web Services” box.

  1. Create a the MyTimeController class within your domain.controller package.
  2. There are five critical includes, I mean “imports” (C++ coming out, sorry):
    > org.springframework.beans.factory.annotation.Autowired provides spring IOC magic
    > org.springframework.web.bind.annotation.* provides the RestController, RestMapping and other REST controller functions
    > org.springframework.http.ResponseEntity handles the entity conversion and jackson JSON serialization for us
    > org.springframework.http.MediaType provides the response header (application.json)
    > org.springframework.http.HttpStatus provides our REST HTTP response
  3. The controller method is a simple one, that does not take any parameters, but calls the service method and delivers an entity object back with our current time. The above imports provide the JSON view and serialization.
package com.paulsdevblog.hellonetbeans.domain.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;

import org.springframework.web.bind.annotation.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.paulsdevblog.hellonetbeans.domain.service.MyTimeService;
import com.paulsdevblog.hellonetbeans.domain.model.MyTime;

/**
 * Simple REST controller example that uses MyTimeService
 *
 * @author paulsdevblog.com
 */

@RestController
@RequestMapping("/time")
public class MyTimeController {
    
    private Logger logger = LoggerFactory.getLogger(MyTimeController.class );
    
    @Autowired
    private MyTimeService myTimeService;
    
    @RequestMapping(
        value={"/current" }, 
        method = RequestMethod.GET,
        produces = { MediaType.APPLICATION_JSON_VALUE }
    )
    public ResponseEntity<MyTime> currentTime(){
        
        MyTime currentMyTime = myTimeService.getMyTime();
        
        return new ResponseEntity<MyTime>( currentMyTime, HttpStatus.OK );
        
    }
    
}

5. REST is best served in snake_case

By default, the SpringBoot RestController will call the jackson JSON creator, and generate JSON with the camel-case entity property names (e.g. currentDate, currentIso8601Dt, currentEpochSecond). However, most web service APIs standardize on snake_case. No problem; we tell SpringBoot to do this automatically through a configuration setting in our project’s application.properties file. This is found under the Other Sources folder in our NetBeans project.

#------------REST Field Name JSON spring.jackson-------
spring.jackson.property-naming-strategy=SNAKE_CASE

6. Clean Build and fire this thing up … wooo hooo

The embedded SpringBoot Tomcat will use port 8080 by default. If this is in use, you can use the application.properties file server.port setting to change this.

  1. Clean Build the project
  2. Click on Run
  3. Watch the NetBeans output console and that good syslog output, noting our INFO “Application Started” message we injected in our application’s main method
  4. Fire up your browser and go to localhost:8080/time/current and behold …
    watch the NetBeans output console as you hit refresh. It’s Alive!

Extending this Example

Other articles on this blog can be referenced to further extend and expand this example:

BitBucket Repo and Project Code

This is just a taste of the rapid development possibilities with SpringBoot. In associated articles, we shall grow this sample and take on typical challenges in the enterprise. Thanks and Like/Link.  paulsDevBlog.End();

 

References