Spring Boot Security and H2 console

The configuration shown below should be used only in a development environment and not in production.

After enabling Spring Security in your Spring Boot application, you will not be able to access the H2 database console anymore.

With its default settings under Spring Boot, Spring Security will block access to H2 database console.

To be able to access to the H2 database console under Spring Security you need to change these four things:

  • Enable h2 console in your application.properties file

  • Allow all access to the URL path /console/*.

  • Disable CRSF (Cross-Site Request Forgery). By default, Spring Security will protect against CRSF attacks.

  • Since the H2 database console runs inside a frame, you need to disable this in Spring Security.

So, the very, very simple security configuration that allows you to access h2-console should look like:

 

After applying these changes and trying to access your h2-console

http://localhost:8080/h2-console/

You should see h2-console login page:

 

Spring Boot Run Dashboard

Intellij Idea Ultimate 2018.03. I thought that Spring Boot dashboard will be visible and I’ll be able to run it after adding devtools dependency to the pom (in my case) file.

But seems that there is a little work involved to be able to run your spring boot applications by Spring Boot Run Dashboard.

In the Run/Debug Configurations Popup, you should have “Spring Boot” and also “Templates”.

So, click on the “+” (Alt+Insert), find Spring Boot on the list and add it.

Now, we can use devtools functionality in Spring Boot Run Dashboard.

Spring – Conditional annotation

Spring 4 has introduced a new annotation @Conditional. It is used to develop an “If-Then-Else” type of conditional checking for bean registration. Let us see how we can use @Conditional annotation to check a property value is dev or prod from environment. For learning we will use Java based configurations in this example.

Create Project Domain class with id, name and duration properties with getters only as shown below.

Create Utility classes to represent in-memory Databases. For simplicity, we are not interacting with Databases. DevDatabaseUtil class represents DEV database and ProductionDatabaseUtil class represents PROD database with some data.

Create a ProjectDAO class to represent DAO Layer.

Now it’s time to implement Conditional checking by using@Conditional annotation. Both condition checking classes implements Spring’s Condition interface matches() method. Both Conditional classes checks for “database.name” from environment. If this values is “dev”, then DevDataSourceCondition’s matches() method returns true. Otherwise false. In the same way, if this property value is “prod”, then ProdDataSourceCondition’s matches() method returns true. Otherwise false.

Create Spring’s Java-based configuration classes

Now it’s time to write JUnits to test Spring’s @Conditional classes.

 

Spring Profiles

A Spring application can be configured to behave differently in different environments using different profiles. For example, you can register beans based on what kind of database you’re running (development, production, test).

You can then configure a deployment to run using zero or more profiles, by providing a spring.profiles.active property. For example, to run the application using production and dev profile, add the following line in application.properties:

To test it, let’s create two classes responsible for database datasource setup and then run our application with datasource configuration setup based on active profile.

To inject our DatasourceConfig interface; depending on the active profile we need to create a ‘test’ class. Spring will injects DevDatasourceConfig or ProductionDatasourceConfig bean:

When the “dev” profile is active spring injects DevDatasourceConfig object, and on call of setup() method following is the output:


To see a list of active profiles you just need to inject Environment and then iterate through a list of active profiles.
When you’ll run our app, tou should get a list of active profiles:

Any bean that does not specify a profile belongs to “default” profile.

Spring also provides a way to set the default profile when no other profile is active – by using the “spring.profiles.default” property.

For testing purposes, to specify what profile is active you need to specify an active profile by using @ActiveProfiles annotation:

The profile names can also be passed in via a JVM system parameter. The profile names passed as the parameter will be activated during application start-up:

DI – Configuring Beans

Component annotations

Spring creates beans for classes with auto component scanning features by using @Component. @Component annotation is not only one you can use for creating beans, there are others more ‘specialized’ annotations.

  • @Controller – Indicates a controller component in the presentation layer
  • @Service – Indicates a Service component in the business layer
  • @Repository – Indicates DAO component in the persistence layer

So, which one to use? It’s really doesn’t matter. Take a look at the source code one of those annotations:

You will notice that all @Repository,@Service or @Controller are annotated with @Component. So, can we use just @Component for all the components for auto scanning? Yes, you can, and Spring will auto scan all your components with @Component annotated.

It’s working fine, but not a good practice, for readability, you should always declare @Repository,@Service or @Controller for a specified layer to make your code more easier to read.

Configuration classes

Let’s assume that our Service classes (SmsService, TweetService, MailService) are part of some third party JAR and we won’t be able to annotate those with @Component. In this case we can use Java configuration classes. To make our application working again we need to create some config class where we will add our service classes to be able to be scanned by Spring.

Annotating a class with the @Configuration indicates that the class can be used by the Spring IoC container as a source of bean definitions. The @Bean annotation tells Spring that a method annotated with @Bean will return an object that should be registered as a bean in the Spring application context. The name of the methods become the names
of the beans by default.

DI – Two beans implementing same inteface

How to inject the right one?

To see what happens lets annotate with @Component our TweetService class.

Trying to run the application you’ll get an error:

Spring, when trying to find a suitable bean for injecting to the messageService variable, finds two beans – the instances of both TweetService and SmsService.

Let’s try to fix it. One of few ways to do it is, to specify a name in @Resource annotation.

Spring will then be able to inject the exact bean without any error.

Another alternative will be to give a name to the bean to match the resource name.

Yet another option to tell Spring which bean to inject is to use @Primary annotation.

The application should still run fine.

A more powerful (it not only works on setters, but on any method, including the constructors) but still very similar to @Resource is @Autowired annotation.

However, @Autowired does not take the name element. Instead, we need to use @Qualifier along with @Autowired.

By default, the qualifier of a bean will be same as its name.

 

Spring also has @Inject , which is synonymous to @Autowired. It’s part of the Java CDI JSR-300 standard, and so Spring thought to support it. What is the difference between @Inject and @Autowired?

The short answer: There is no different and can be used interchangeably.

In more detail @Inject is part of the Java CDI (Contexts and Dependency Injection) standard introduced in Java EE 6 (JSR-300). Spring has chosen to support using @Inject synonymously with their own @Autowired annotation.@Autowired is Spring’s own annotation. In a Spring application, the two annotations works the same way as Spring has decided to support some JSR-300 annotations in addition to their own.

 

DI – Dependency injection by name and type

@Resource by default the name of the bean will be its class name in camelCase. That means, the SmsService instance, which will be put in the application context as a result of being annotated with @Component, will be named as smsService. To change the default name, we can supply a value element to @Component:

This behavior is called dependency injection by name.

Now I show you an example of DI by name:

But, if we remove a name parameter from @Resource annotation and then we’ll try to run our example, everything should work as before. Why?

At the start of application Spring first try to find a bean with messageService name and will fail, next step will be to try to find a bean of the same type, and in our example as SmsService is a subtype of MessageService and as a result of successfully running application, we should get:

Your message was sent

And in the console log:

 

DI – let’s try to understand it – part 2

To continue our series about DI let’s look at our example of MessageController from previous post – DI – part 1.

Unfortunately there is a problem with our solution.

The MessageController class is dependent, has a tight dependency on the EmailService class. There is a hard connection between these two classes. That means, if we ever change our mind to use TweetService or SmsServce instead of EmailService, we’ll need to change the code this way:

private MessageService messageService = EmailServiceTweetService();

But this solution is no different from previous one. We still have both classes tightly coupled. And this is the time when DI comes handy.

First, we need to annotate TweetService class with Spring @Component annotation to tell Spring to keep instance of TweetService in Application Context, it is a place where Spring keeps objects (called Beans) instantiated.

And instantiating Our TweetService using @Resource annotation when Spring application start.

Running our application and typing http://localhost:8080/message in web browser address bar, we should see:

“Your message was sent”

and

Tweet: Very important: – Please read this carefully.

as a output in console.

 

DI – let’s try to understand it – part 1

In my last post we’ve seen how to setup our project to play with Spring and DI – Creating a simple Spring project. Today we’ll try to understand whole idea about DI backed by few examples.

To continue with our project lets create a package di.example.one under com.programmerscuriosity.springforblogdemo and define MessageService interface that includes one method, sendMessage(String subject, String message).

And then let’s create few classes that implement MessageService interface:

To try out the service let’s create a simple controller class:

If you now run the application and visit http://localhost:8080/message, you should see “Very important e-mail was sent” and in the console you should see the standard print output lines:

Mail: Very important e-mail. – Please read this e-mail carefully.

Hello, Programmer’s curiosity

An example of very simple Spring application that will be extended in next posts to demonstrate Spring framework and DI (dependency injection).

For all examples I’ll be using IntelliJ Idea Ultimate, an ide of my choice for at last 3 years, I love it’s features and productivity speedup that comes with it.

Creating a new Spring project

There are many ways to create a new Spring project. You can create it from scratch or use Spring Initializr plugin for IntelliJ Idea or do it via web Spring Initializr (it creates a zip file, which you can download, unzip and import in your IDE).

SpringInitializr

Next step is to enter few metadata for our project:

Name
It’s the name of the project, e.g. spring-for-blog-demo
Type
It’s the build tool selection to help us compile and package our project. There are a couple of options: Maven and Gradle. I prefer to go with Maven, because of its wide adoption, unless there is a specific need for Gradle.
Packaging
You’ll find two options here – JAR and WAR.
The executable of our application. That JAR or WAR can run standalone, with the standard java -jar command.
Choose JAR packaging here, unless you are using JSP, which needs WAR packaging.
Java version
Our choice is 1.8 here.
Group and Artifact
Group and Artifact uniquely identify a project. Group will identify your project uniquely across all projects, what means that has to be at least as a domain name you control (no problem if you don’t own a domain – just use some name which you feel will be unique), and you can create as many subgroups as you want, e.g. com.programmerscuriosityArtifact uniquely identifies the project inside the group. It is the name of the jar without version. You can choose whatever name you want with lowercase letters and no strange symbols e.g. springforblogdemo.
Version
If you distribute it then you can choose any typical version with numbers and dots (1.0, 1.1, 1.0.1, …). Don’t use dates as they are usually associated with SNAPSHOT (nightly) builds. For our purpose just leave it untouched.
Description
This is a one line description of the project.
Package
This will be the name of the root package of your application. The common practice for naming it is to join the group and the artifact in some way, e.g. com.programmerscuriosity.springblogdemo.
Remember that “-” isn’t allowed here.

NewProject_metadata

Boot version
This is the version of Spring Boot to use. Normally we’d choose the latest stable release.
Dependencies
This section asks us to choose the dependencies needed. Whatever we choose here will go into the configuration file of the build tool. The build tool will then automatically fetch the needed JARs and put those in the classpath. So, choose just Web for now, and more dependencies can easily be added into the configuration file later.

NewProject_dependencies

Press Next and Finish to create the project in your workspace.

NewProject_structure_and_pom

Running our application at this stage won’t show any results apart from getting an error page (not even defined by us).

WhiteLabelPage

So, lets create a simple controller class and try to display at least simple Hello message.

Create a new package, e.g. com.programmerscuriosity.springforblogdemo.controllers. Inside that package, create a new class, HelloController:

Start your server and type http://localhost:8080/hello in your browser.

hello_programmers_curiosity

And that’s it. We’ve got our base project for further posts about Spring DI ready and running.