3

I'm having a problem when deploying a Spring Boot application as a WAR file to a standalone Tomcat 7 server. It builds and deploys fine but when the index.html page tries to load other static resources they are missing the context in the url so fail to load (404).

e.g. http://localhost:8080/app/images/springboot.png

should be: http://localhost:8080/spring-boot-war-context-issue/app/images/springboot.png

Image showing issue

It works fine when using the embedded Tomcat

Similar issues:

Seems to be a similar issue to: Spring-Boot war external Tomcat context path

However the suggestions in that question did not seem to solve my issue. I wasn't sure about the Tomcat xml file.

Steps followed:

I created a simple sample application and followed the steps in the Spring Boot docs.

The sample code can be seen in this github repo along with steps to reproduce the problem: https://github.com/jgraham0325/spring-boot-war-context-issue

Things I've tried so far:

  • Set contextPath in application.properties but this only applies to embedded tomcat
  • Tried using a fresh install of Tomcat 7
  • Tried creating a config file in tomcat to force context: apache-tomcat-7.0.72\conf\Catalina\localhost\spring-boot-war-context-issue.xml

Contents of spring-boot-war-context-issue.xml:

    <Context 
    docBase="spring-boot-war-context-issue" 
    path="spring-boot-war-context-issue" 
    reloadable="true" 
    />

Any advice would be much appreciated!

Thanks

Update 23/10/2016:

Alex's answer below about using relative URLs without the slash at the start was perfect solution!

Community
  • 1
  • 1
James
  • 83
  • 2
  • 7

2 Answers2

3

Isn't it simply caused by the way you defined your url in index.html (the url does not include the context root):

<img src="/app/images/springboot.png" />

Use relative uri

You should be able to use a relative uri (without the leading forward slash):

<img src="app/images/springboot.png" />

get the context root

With JSP/JSTL:

<img src="${pageContext.request.contextPath}/app/images/springboot.png" />

Or with Javascript:

function getContextPath() {
   return window.location.pathname.substring(0,  window.location.pathname.indexOf("/",2));
}
...
var img = new Image();
img.src = getContextPath() + "/app/images/springboot.png";
document.getElementById('div').appendChild(img);
Community
  • 1
  • 1
alexbt
  • 16,415
  • 6
  • 78
  • 87
  • Alex, thanks for the detailed response, it explains a lot. I've tried converting the page from a html to a jsp page and using the method above which worked fine locally but is throwing an error when on the tomcat server - most likely just some config issue. Having said that we're planning an angular app so don't think JSPs are an option. Not sure the pure javascript option would be feasible given how many extra lines of code are needed for each link. Maybe best to just put the app in the root directory of Tomcat or is that bad practice? – James Oct 23 '16 at 18:58
  • You could use a relative uri too: . I added it to the answer. Set the path relative to your html page. – alexbt Oct 23 '16 at 19:51
  • That was exactly it! Thanks very much for your help - you're a legend. – James Oct 23 '16 at 21:59
0

If using Thymeleaf, another way is using Context-Relative URLs like below:

<link rel="icon" type="image" th:href="@{/img/favicon.ico}"/>

For more information please refer to: Thymeleaf Documentation

Somebody
  • 2,667
  • 14
  • 60
  • 100