seo spring logo

SEO: Friendly URL construction with Spring MVC

What is a friendly URL?

Since I started to really use the internet, about 13 years ago, I liked to bookmark useful and interesting links for later access. Of course my bookmarks list has been growing steadily ever since and it’s become difficult to just LOOK for some bookmark on a topic I remember I might have added to the list. So I do it the Google-way, I search for it by typing some relevant words. Besides tags and good titles, URLs that contain some of the words I look for, land at the top of the search results. The same is valid for search engines, who favour friendly or well constructed URLs.

Octocat Source code for this post is available on Github - is an open source project.

But what is a “friendly” URL? I would say it’s

  • constructed logically so that is most intelligible to humans (when possible, readable words rather than long ID numbers). For example I find that a URL link like is much more appealing than something like this For one you can figure out just from the URL it’s about a podcast, and briefly what the podcast might be about.
  • not too complex and not cryptic – visitors may be intimidated by extremely long and cryptic URLs that contain few recognizable words. Some users might link to your page using the URL of that page as the anchor text. If your URL contains relevant words, this provides users and search engines with more information about the page than an ID or oddly named parameter would
  • flexible – allow for the possibility of a part of the URL being removed. For example, instead of using the breadcrumb links on the page, a user might drop off a part of the URL in the hopes of finding more general content – if the user tipped, he or she would get redirected to a list of all the podcasts available on Or what if the user might be visiting, but then enter just into the browser’s address bar. Should she get a 404 or also the right page?
  • makint use of hyphens (-) – there’s a reason why Google recommends it – it’s easier to read in comparison with underscore (_) or white spaces which get encoded to %20.

Lastly, remember that the URL to a document is displayed as part of a search result in Google, below the document’s title and snippet. Like the title and snippet, words in the URL on the search result appear in bold if they appear in the user’s query:

goole search results page highlighted

highlight of keywords in URLs

Friendly URL construction with Spring MVC

On, the URLs for podcast and episode pages are “friendly”-built. These are the core pages of the website and therefore should be highly optimized for search engines and easy to bookmark.

Podcast URLs samples:

Episode URLs samples:

In the following sections I will present how an episode URL is constructed, as it is more complex:

Episode URL construction

Episode URL construction

The podcast URL construction resembles the same process.


As you’ve seen, the following elements are present in the URL of the episode:

  • podcast id
  • podcast title
  • episode id
  • episode title

Among other things, these are java bean properties of the Episode domain class. Object of this class type will get loaded in the model, and the via the controller be presented in the view:

The two properties titleInUrl and podcastTitleInUrl hold the “transformed” episode’s and respectively, the podcast’s title. In the transformation process, the spaces between words are replaced with hyphens (-) and if the length exceeds a certain limit (TITLE_IN_URL_MAX_LENGTH = 100), it will be shortened:


Let’s consider a use case, for example when searching for episodes, you get a list of results. This list of Episode objects is loaded in the Model via MyBatis (see my post Integrate MyBatis with Spring for that), and then via the Controller are presented in the View, which in this case is a JSP file. The user has the possibility to see the details of a specific episode by clicking on the episode’s URL, that is constructed in the following manner:


This is perhaps the most interesting part in the “friendly” URL construction. Let’s have a look at the EpisodeController, which handles episode “friendly” URLs:

The @RequestMapping annotation is used for mapping web requests onto specific handler classes and/or handler methods. A @RequestMapping on the class level is not required. Without it, all paths are simply absolute, and not relative. The @PathVariable indicates that the annotated method argument is bound to the URI template variable specified by the value in parenthesis.

So if you add the values of the @RequestMapping at the class level (line 16) – /podcasts – and the @RequestMapping annotation at the method level (line=32) – {podcastId}/*/episodes/{episodeId}/* – you get /podcasts/{podcastId}/*/episodes/{episodeId}/*, which reproduce exactly the “friendly” episode URLs as mentioned before. The star (*) in the URL structure means it can be filled with any text. I chose to fill that with the titles of the podcast and of the episode respectively.

Note: The SitePreference part (lines 44-49) routes the visitor to the desktop or mobile version, depending on her device or selected preferences. See my post Going mobile with Spring mobile and responsive web design for more details.

Well, you see it’s pretty easy to build friendly URLs with Spring MVC 3.x. This is just one measure to improve your website visibility for search engines. But stay tuned, more posts on this topic will follow.

Octocat Source code for this post is available on Github - is an open source project.


  1. Google Webmaster Tools – URL Structure
  2. Search-engine-optimization-starter-guide
Podcastpedia image

Adrian Matei

Creator of and, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy - but these are just outside labels and not that important, deep inside we are all just consciousness, right?

Adrian’s favorite Spring and Java books

About Adrian Matei

Creator of and, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy.

  • Spook SEO

    Hello Adrian!

    I believe that a “friendly” URL makes use of hyphens rather that underscores. I guess Google would love to have an URL wilth hyphens. As we can also observe, URLs with hyphens are much easier to read compared to URLs with underscores.

    • Hello Spook :),
      You are totally right, and that’s why the links on, as presented here, use hyphens…

      Thank you for emphasizing that point

  • Ender Tunç

    What about “friendly”-url with some parameters like search/advanced_search/results?numberResultsPerPage=50&searchTarget=podcasts&categId=21&searchMode=natural&currentPage=1. As you can notice it is taken from your website and I try to figure out how it works. In my project I construct such URLs with s and @RequestParam and in this case my function needs to take 4 argument but I in your code I did not see this kind of a function. How this friendly-URL-with-parameter done easily?

    • Hi Ender,

      Honestly I really don’t want Google indexing these kind of pages (e.g. search results), because eventually they are duplicates to the podcasts and episodes friendly URLs I mentioned that I want them indexed. To do that I create my own sitemaps and submit them to Google – see

      See also recommendation from Google at

      If you still want to do URLs with parameters I suggest using names for them that are easily to understand by humans, not like Google does it for its search results 🙂

      Hope this helps,

      • Ender Tunç

        Hi Adrian,
        Thank you for your answer but it was not the answer I expect 🙂 What I am trying to find out is that where such a URLs (search/advanced_search/results?numberResultsPerPage=50&searchTarget=podcasts&categId=21&searchMode=natural¤tPage=1) produced in code? How are they produced? How can I add new a parameter to URL? For example year=2014? (What needs to be edited in JSP or controller?)

        I hope I explained myself. Greetings.

        • Hi Ender,

          This is produced by Spring and are the properties of the SearchData class – @ModelAttribute("advancedSearchData") SearchData advancedSearchData

          Hope this helps.