springavatar53586_0Creating Java web applications using Spring Framework has never been easier. If you’re already familiar with Java and have little to no experience creating web applications, or if you’re worried that all the cool kids abandoned Java in favor of Ruby and Node.js, you want to read this.

My intention is to provide here a practical guide to get up and running quickly on creating modern web applications using Java and Spring.

We’ll be using the latest versions of Java, Spring Framework (4.x), Spring Boot (v1.2.x), Spring Security, Spring Data JPA, Thymeleaf and Maven 3 frameworks.

Why using Spring framework

Spring is one of the most wildely adopted open-source Java frameworks.

  • Spring is a mature yet still innovative open-source framework
  • Spring has a very active community
  • Spring is light-weight – can be run from the command line using an embedded container
  • Spring and especially Spring Boot makes you productive – no requirement for XML configuration

Spring is more than a framework…

… it’s a platform that can get you covered on most technologies needed to build web applications:

  • Creating MVC applications
  • Providing authentication and authorization
  • Connecting to RDBMS databases using JDBC, Hibernate and JPA
  • Connecting to NoSQL databases (MongoDB, Neo4J, Redis, Solr, Hadoop, etc.)
  • Handling messages (JMS, AMQP)
  • Caching
  • etc.

Time to Create Some Code

In this tutorial we’ll be creating a sample url-shortener application (the source code is available on github here: https://github.com/davidkiss/yourl) and while this post doesn’t cover all aspects of building a web application, hopefully you’ll find enough useful information to be able to get started and to want to learn more.

The application consist of a single HTML page and it can create a short-url from any url and as you can probably guess, it can also redirect from the short-url to the original url.

To run it execute below command in the command line (assuming you already have Maven v3 installed):

$ mvn spring-boot:run

That will start up the application at http://localhost:8080/.

Yourl - Live Demo

Components

YourlApplication.java

This is the main class of the application that initializes the Spring context including all the Spring components in this project and starts the web application inside an embedded Apache Tomcat (http://tomcat.apache.org) web container.

@SpringBootApplication
public class YourlApplication {

    public static void main(String[] args) {
        SpringApplication.run(YourlApplication.class, args);
    }
}

It’s basically the @SpringBootApplication and the SpringApplication.run() method that does the magic here.

UrlController.java

@Controller
public class UrlController {
    @Autowired
    private IUrlStoreService urlStoreService;

    // ...
}

Following the MVC paradigm, this class serves as the Controller (note the @Controller annotation) that processes HTTP requests. Each method in this class annotated with @RequestMapping maps to a specific HTTP endpoint:

  • showForm(): displays the home screen where users can enter url to be shortened
    @RequestMapping(value="/", method=RequestMethod.GET)
    public String showForm(ShortenUrlRequest request) {
        return "shortener";
    }
  • redirectToUrl(): redirects from shortened url to the original one
        @RequestMapping(value = "/{id}", method = RequestMethod.GET)
        public void redirectToUrl(@PathVariable String id, HttpServletResponse resp) throws Exception {
            final String url = urlStoreService.findUrlById(id);
            if (url != null) {
                resp.addHeader("Location", url);
                resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
            } else {
                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
        }
  • shortenUrl(): as the name suggests it creates a shortened version of the provided url and passes it to the shortener.html to be displayed
    @RequestMapping(value="/", method = RequestMethod.POST)
    public ModelAndView shortenUrl(HttpServletRequest httpRequest,
                                   @Valid ShortenUrlRequest request,
                                   BindingResult bindingResult) {
        String url = request.getUrl();
        if (!isUrlValid(url)) {
            bindingResult.addError(new ObjectError("url", "Invalid url format: " + url));
        }
    
        ModelAndView modelAndView = new ModelAndView("shortener");
        if (!bindingResult.hasErrors()) {
            final String id = Hashing.murmur3_32()
                .hashString(url, StandardCharsets.UTF_8).toString();
            urlStoreService.storeUrl(id, url);
            String requestUrl = httpRequest.getRequestURL().toString();
            String prefix = requestUrl.substring(0, requestUrl.indexOf(httpRequest.getRequestURI(),
                "http://".length()));
    
            modelAndView.addObject("shortenedUrl", prefix + "/" + id);
        }
        return modelAndView;
    }

As you can see, the @RequestMapping annotation takes care of mapping a single url to a Java method. The method can have multiple params:

  • a @PathVariable (ie: id) which comes from the dynamic part of the url (/{id}), or
  • a @RequestParam, or
  • a POJO (Plain Old Java Object) where the fields correspond to request parameters, or
  • a @RequestBody in the case of POST requests, or
  • other predefined beans Spring makes available (for example, HttpServletResponse)

ShortenUrlRequest.java

The shorten url request is mapped into this POJO (Plain Old Java Object) by Spring. Spring also takes care of validating the request, see the the annotations on the url field.

public class ShortenUrlRequest {
    @NotNull
    @Size(min = 5, max = 1024)
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

shortener.html

This is a Thymeleaf-based (http://www.thymeleaf.org/) template that uses Twitter Bootstrap (http://getbootstrap.com/) to render the home screen’s HTML code. It renders the data (Model) provided by the request mappings in the UrlController class.

...
<div class="jumbotron">
  <div class="container">
  <h1>Shorten your url</h1>
    <p>
    <div class="alert alert-success" role="alert" th:if="${shortenedUrl}"
      th:utext="'Link created: &lt;a href=\'' + ${shortenedUrl} + '\'&gt;' + ${shortenedUrl}
       + '&lt;/a&gt;'">
    </div>
    <form class="form-inline" th:action="@{/}" th:object="${shortenUrlRequest}" method="POST">
      <div class="alert alert-danger" role="alert" th:if="${#fields.hasErrors('*')}"
         th:errors="*{url}">Input is incorrect</div>

      <div class="form-group">
        <input type="text" class="form-control" id="url" name="url"
           placeholder="http://www.example.com"
           th:field="*{url}" th:class="${#fields.hasErrors('url')}? fieldError"/>
      </div>
      <button type="submit" class="btn btn-primary">Shorten</button>
    </form>
    </p>
  </div>
</div>
...

InMemoryUrlStoreService.java

The application currently only persists shortened urls into an in-memory persistence layer implemented in this minimalist class. Later on we can improve this by implementating the IUrlStoreService interface to persist data to a database.

@Service
public class InMemoryUrlStoreService implements IUrlStoreService{
    private Map<String, String> urlByIdMap = new ConcurrentHashMap<>();

    @Override
    public String findUrlById(String id) {
        return urlByIdMap.get(id);
    }

    @Override
    public void storeUrl(String id, String url) {
        urlByIdMap.put(id, url);
    }
}

Note the @Service method that tells Spring this is a bean from the Service layer that can be injected to other beans, like the UrlController.

Conclusion

That’s it in a nutshell. We covered all the pieces of this web application. I hope you agree now that building web applications using Java and Spring can be fun. No more boilerplate code and XML configurations, the latest version of Spring takes care all of that for us.

If you’re interested to learn more about Spring framework and Spring Boot, don’t forget to subsribe to my newsletter to get latest updates on Spring. Feel free to leave a comment below, if you have any questions or suggestions.

Would you like to learn more about Spring framework and Spring Boot? I’m working on other tutorials and would love to hear what topics you’d like to learn more about?