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?

  • Sanchit Gupta

    Good explanation with rational reasons.

    • David Kiss

      Thank you, Sanchit!

    • Nizam

      Sanchit Gupta are you in Toronto area ?

      • Sanchit Gupta

        No Nizam, I am from India.

  • Sanchit Gupta

    Most of the Java developers are not ready to adopt springboot for production as compare to spring framework (xml based configuration). But as far as springboot is concerned, its more easy to setup and configure. So why are not java community is adopting to springboot ?

    Some points in my mind :

    1. Is there any performance issue in springboot due to its auto configurations?
    2. Less documentation
    3. Less support and solutions on stackoverflow
    4. Can not upgrade the legacy application on spring framework
    5. Developers dont want to learn new technologies
    6. No tutorials and training available.

    Please correct me if I am wrong, and conclude it, why developers not moving to springboot ?
    Thanks in advance.

    • David Kiss

      Great question. I think you already touched many points on why developers may not be ready to adopt spring boot, altough I’m at one of Canada’s largest company where I’m seeing more and more greenfield projects adopting it.

      I haven’t experienced any performance issues with Spring Boot, but you’re right on the lack of comprehensive tutorials on Spring. For someone starting with Spring the number of Spring projects and their reference guides can be easily overwhelming. It’s hard to figure out where to start.

      Another reason is that Spring Boot is not considered as ‘sexy’ as other frameworks like Play, Vert.x, etc. Even though I consider Spring Boot as a game changer for Spring, many developers still associate Spring with its earlier versions – they think Spring is still heavy weight, bloated with XML, hard to configure the dependencies, has hard-to-read stacktraces, etc.

      You wrote your first comment around 9 months ago, how’s your personal experience with Spring Boot so far?

      • Sanchit Gupta

        Yes I am using springboot and even the application is on production luckily. I have used it for restful apis. At times being only springboot developer I have to face some issues and have to solve the issues myself. Apart from lack of community and documentation, I did not experienced any performance issue so on and so forth. It would be appreciable is you can share an MVC demo app or your learning in terms of blog for MVC app. I am comfortable with rest apis and recommend you to use springboot.

        • David Kiss

          I’m working on a ‘Spring in 15 minutes’ tutorial and will be publishing it shortly. It’s a step-by-step tutorial on creating a blog application using latest version of Spring. I’d be happy to share with you the draft and get your feedback.

          • Sanchit Gupta

            is that app on Springboot or Spring?

          • David Kiss

            Spring Boot, Spring Data JPA, Spring Data Rest and Spring Security

          • Sanchit Gupta

            Great, I am waiting for that.
            Do let me know, when you will be publish that.

  • Vishal Patel

    Thanks for the information. As you created html page withing spring boot. I m wondering can I separate front-end and backen?? Suppose ill develop same url shortener application and create rest api end point. Then using any front-end technology I’ll call those api and will show result on Web page. Am I thinking in right direction?

    • David Kiss

      Yes, it totally makes sense to separate the frontend and the backend. Most of the projects I worked on recently followed that pattern.

      • Vishal Patel

        ok! thank you 🙂 i m going to develop same shortenUrl application to understand spring more.

      • Vishal Patel

        can you please make tutorial on angular js and spring boot? i tried making simple controller and calling it using angular but i got error. i dont know whats wrong i did.

        • David Kiss

          Thanks for the suggestion. I’ll keep it in mind for one of my next posts