Enterprise Java

Building modern web applications using Java and Spring

springavatar53586_0-150x150 Creating 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 here) 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

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.

David Kiss

David is a passionate software engineer specializing in building scalable web-applications using Java, Spring, Hibernate and Apache Camel. He is based in Toronto, Canada and is the founder of David Andras Consulting Ltd.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
shikhar srivastava
shikhar srivastava
9 years ago

Thanks for an amazing post. Just had one query though! configured the whole project as is into my system but it is not responding to localhost:8080/yourl/ and sending me to 404 page! Am I missing something here? Please help!

David Kiss
9 years ago

You don’t need /yourl in the context path as the application is using in the root context. This should work: http://localhost:8080.

Dayan Costa
Dayan Costa
9 years ago

May I get the source code? I’m starting with Spring and Thymeleaf and it can helps me.

Thanks

David Kiss
9 years ago
Reply to  Dayan Costa

Dayan, you’ll find it here on github: https://github.com/davidkiss/yourl. Best of luck with learning Spring and Thymeleaf!

Back to top button