Spring:url not resolving links correctly
Solution 1
It is good practice to put all your links as follows
<a href="${pageContext.servletContext.contextPath}/othersite"> Other site </a>
${pageContext.servletContext.contextPath} always gives your application root, when you are developing use http://localhost:8080/myApp
, then your application root is /myapp, but when you want to place your application in production generally your application root will be /, using ${pageContext.servletContext.contextPath} before links you ensure it will work in both cases
Solution 2
When facing same problem I use c liblary:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<a href="<c:url value="/otherSite"/>"> Other site </a>
Solution 3
This should do the trick:
<spring:url value="/some_link" context="myApp" var="apps_url" />
<a href="${apps_url}">link</a>
apps_url should be equal to: http://localhost:8080/myApp/some_link
Solution 4
Tomcat can have many web apps executing at the same time. Consider the scenario:
- tomcat is running on 8080
- tomcat web apps folder has three apps running in it
- appA.war
- appB.war
- ROOT.war
The URL http://localhost:8080/ will be get the request to tomcat and tomcat must decide which of three apps should service the request since the URL does not identify the app the request will be routed by tomcat to the ROOT.war which is the root web app in tomcat.
When you have a JSP in appA.war with <a href="/otherSite">link</a>
in it then the web browser that parses the output will figure that the request should be submitted to root of the server since the href started with / therefore the browser puts togethec the url http://localhost:8080/otherSite when the request get to tomcat tomcat assumes that /otherSite is refering to a web app called otherSite.war but of course that is not there.
if you use <a href="otherSite">link</a>
the browser will assume this is a relative URL and so it will send the request to http://localhost:8080/appA/otherSite because the page that generate the url was served out of the context http://localhost:8080/appA
So in general you need to make sure that the URLs from a JSP page are relative or that you add the context name to the generated url, this is what <spring:url />
and <c:url />
tags do.
is there any connection between the url on local tomcat server and the url the webapplication will have when its published?
the URL for the context is the same as the name of the war file in the tomcat webapps folder unless you change that in the server.xml or in the context.xml file.
jeyp
Updated on June 26, 2022Comments
-
jeyp almost 2 years
I'm pretty new to the Spring framework and web applications, though I'm experienced with Java. When I run my site on a local tomcat server the URL is:
http://localhost:8080/myApp/
Now a request mapping delegates me to my home page with:
@RequestMapping(value = "/", method = RequestMethod.GET) public String someMethod(Model model) { ... return "index"; }
Now within a file
index.xhtml
I link to another page with<a href="apps/">link</a>
but when I want to link back to the index page I have to use<a href="../index/">link</a>
. I searched for a solution and found:<spring:url value='/apps' var="apps_url" /> <a href="${apps_url}">link</a>
But spring:url always resolves to
http://localhost:8080/myApp/
- the page that I'm currently on. In addition, when I just use a link like this:<a href="/otherSite">link</a>
, it always resolves tohttp://localhost:8080/otherSite
and nothttp://localhost:8080/myApp/otherSite
like I expected. How can I get my link to work? Ishttp://localhost:8080/myApp
implicitly defined as my context or can/should it be changed tohttp://localhost:8080/
?Also, is there any connection between the URL on local tomcat server and the URL the web application will have when it's published?
Here are some of my application files:
servlet-context.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure --> <!-- Enables the Spring MVC @Controller programming model --> <annotation-driven /> <context:component-scan base-package="myApp" /> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- Handles HTTP GET requests for /resources/** and /css/** by efficiently serving up static resources in the ${webappRoot}/resources directory --> <resources mapping="/resources/**" location="/resources/" /> <resources mapping="/css/**" location="/css/" /> <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".xhtml" /> </beans:bean> </beans:beans>
excerpt from web.xml:
<!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>