4

I am not new to Spring MVC, but always wonder how can I use correct URLs (context name aware) inside JavaScript. Something like c:url or spring:url, but for JS:

E.g. if I have a webapp that is deployed as context in Tomcat. It has a page: http://localhost:8080/context/some/directory/search and API at http://localhost:8080/context/api. If page calls API, I face problems:

// This works wrong:
$http.get('/api/users', function(data){}) // will call http://localhost:8080/api/users - the context is lost!
$http.get('api/users', function(data){}) // will call http://localhost:8080/context/some/directory/api/users - wrong URL!

I wish some way of filtering exists:

$http.get('${url:api/users}', function(data){}) // will call http://localhost:8080/context/api/users

I saw something similar in C# and Ruby, and Python. Is there any ready-to-use solution for Java / Spring?

2
  • You should probably get the context name (using ServletContext#getServletContextName()) into your javascript namespace. You can do this by including a <script> in the html file where the javascript is loaded. Then you could form the URLs with this context. Btw, how did you do this in C#/Ruby/Python? Commented May 21, 2014 at 16:39
  • I'm not sure, but I saw something like @url or :url in Ruby. I understand that the problem is default servlet which does not filter JS, and in Ruby JS is served dynamically, but I hope some beauty way exists. Commented May 21, 2014 at 16:44

2 Answers 2

3

As implied by @Vikdor's comment, you'll have to get your server to process the JS files somehow. I've used each of these approaches in the past:

  • Use interpreted pages to deliver your resources. A JSP perfectly happy delivering JS, JSON, CSS, HTML, PDF or any other Content-Type, as long as you use the appropriate @page directive to do so. Then, you can use JSTL libraries just like you were writing an HTML page. If resource names are important to you, you'll have to either write a controller to interpret requests for foo.css to be delivered by the view foo.css.jsp, or some similar translation. Also, IDEs get confused, bless 'em, so you may have to override syntax coloring and auto complete to get the most out of those features.

  • Write a static content filter to parse resources for interesting tokens (like ${url}) and replace them with appropriate values before delivering. It adds some overhead to resource delivery, but was performant enough for our particular use case.

In either of those cases, make sure you keep in mind your app's ability to deliver these resources with appropriate cache headers, so your server isn't doing extra work delivering duplicate resources.

  • Insert a launch/deployment step to convert URL paths, usually with a simple search/replace, with values appropriate to your deployment environment, before deploying the modified static resources to their final location. This has the benefit of allowing you to craft the resources to be served locally as-is, without requiring deployment, and then mutating the URLs only when you push them to a non-local environment.
Sign up to request clarification or add additional context in comments.

1 Comment

Actualy, I am using JSP approach exactly as you stated. I serve this JSP as application/javascript and it has url function: function url(path){return '<spring:url value="/">' + path}. Well, if nothing better invented, I am happy with this!
1

For those, who find this question via Google, I'll add the gist:

<%@ page
    language="java"
    contentType="application/javascript; charset=UTF-8"
    trimDirectiveWhitespaces="true"
    pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/fragments/taglibs.jsp" %>

/**
 * Returns servlet context aware URL, ready to use for AJAX calls and resource
 * loading from JS.
 * 
 * This script must be included before any other JS sources that want to use
 * `url()`.
 * 
 * @param {string}
 *            path a servlet context unaware path of URL, like `api/users`
 * @returns {string} servlet context aware URL
 * @author madhead
 */
function url(path){
    return '<spring:url value="/" />' + path;
}

Usage:

<script src="<spring:url value='/js/hsps/url.jsp' />"></script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.