Spring Boot loading static content

We will try to quickly how to go about loading and serving static content using Spring Boot 2. There was a difference in how boot 2.0.0 was loading static resources to 2.1 version now. In this article, we will take a simple web application and load the static resources that are defined in the resource folder.

Here is how the project is setup for this article.

I decoupled the pom as a parent and one for the web project. Spring by default without any config changes loads static content from the path that is defined in ResourceWebHandler. But in the article we are going to overwrite the default path.

We first over-ride the classWebMVCConfigurer. The sample snippet of override is.,

public class BootSamplerWebAppWebConfigurer implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/", "/error/","/images"));
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/")
.setViewName("/main/index.html");
}
}

As we can see, there are the class couple of methods that we override to tell boot where our static resources are located. I don’t like the favicon that comes from spring framework. So here is the code to serve favicon static content. Here is the code to override that.

@Configuration
public class BootSamplerFavIconConfiguration {
@Bean
public SimpleUrlHandlerMapping customFavIconHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
simpleUrlHandlerMapping.setOrder(Integer.MIN_VALUE);
simpleUrlHandlerMapping.setUrlMap(Collections.singletonMap("/favicon.ico", faviconRequestHandler()));
return simpleUrlHandlerMapping;
}

@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler resourceHttpRequestHandler = new ResourceHttpRequestHandler();
ClassPathResource classPathResource = new ClassPathResource("/static/images/favicon.ico");
List<Resource> locations = Arrays.asList(classPathResource);
resourceHttpRequestHandler.setLocations(locations);
return resourceHttpRequestHandler;
}
}

Error pages are from a static content directory, we will have to override the class ErrorrPageRegistar

public class BootSamplerWebAppErrorRegistrar implements ErrorPageRegistrar {

@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.html"));
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400.html"));
}
}

The main method to run the application has some tweaks, here is the code block for that.


@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class})
public class MainApp extends SpringBootServletInitializer {
public static void main(String[] args) {
final SpringApplication springApplication =
new SpringApplication(BootSamplerWebAppErrorRegistrar.class,
BootSamplerWebAppWebConfigurer.class, BootSamplerFavIconConfiguration.class,
MainApp.class);
springApplication.run(args);
}
}

When running the, we should get index.html served from the folder main . The template for this index is from the bootstrap template blackrock digital.

Finally all code for this is in github.

Winter 2019.

This is the coldest day that I have ever seen in my lifetime. The weather was at -27 and the windchill was at -35. I was so bummed with the fact that there is literally nothing you can do except for watch the time pass by. A picture to remember the year and time.

Missed items of this year.

There are several things that I wanted to accomplish this year:

  • Do a blog post regularly No success
  • Complete all the freecodecamp certificates
    • The changes came, and boatload new challenges that got added, unable to complete all the certifications.
    • Finished at least a couple of them.
      Hoping to finish the reminder this year as part of the #100daysofcode
  • Complete Venkat’s concurrency course. That was one heck of a head spinner, but glad was able to watch it and get a little bit of hang of it.
  • Complete the Bealdung’s Spring Rest Course. Done with 53% of it :-). I loved going over this.
    • Start writing technical articles for Baeldung. But I got good feedback from them and was asked to think about writing for them!!
  • Completed certification for a modern era’s PowerBuilder tool called onBase. An impressive suite of tools for doing a lot of business automation, but learning it gave me the feeling that I was back to good old PowerBuilder programming days.
  • Completed the Scrum certification. Yep effective this year am officially a scrum master for next two years until I keep up with CE.
  • Renewed PMI certification with some bootstrap courses.
  • I went to get trained in AWS and Azure. The love of DevOps has multiplied like crazy. Hopefully, I will be able to contribute time to this community.
  • Am yet to submit my iPhone app to the app store. Probably that would be the first thing I will be working this year.

Best podcast for the year

  • Believed If you have not heard this, you should start right away.

Best Binge watched show

Best product that I bought this year

Best app development product I used for the year

Design benchmarks

This is a long-form write-up. The comment that goes something like this.,

Which means that the people who speak louder online, with higher frequency and reach, are not necessarily the ones striving for Independence, Depth, Honesty, or Breadth through the content they create. They are not necessarily the ones equipped with the experience and knowledge required to share thoughts that will provoke change in our industry.

This is such a genuine opinion, beats the odds that, if you are an individual who is an industry trendsetter, then you do not have time to write about the content that you are working on. So anyone who has the power and time to write will have a perspective on how design should be.

 

Effective Java – Third edition​

​​

Effective Java is always a good book to read and this latest edition is no different. Here is the Amazon link to get the book. Here are some code samples and presentation promoting the book. My quick code snippet from the book.

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class StringManipLambda {
public static void main(String args[]){
 List stringArras= Arrays.asList("First","Second","third","fourth","fifth");
 Collections.sort(stringArras,(s1,s2)->Integer.compare(s1.length(),s2.length()));
 stringArras.stream().forEach(System.out::println);
    }
}

This is a simple code block, where we take a list of Strings and sort it based on its length. The book goes in depth of how to read this lambda expression and understand how it works.