Spring MVC Request URLs in JSP
Clash Royale CLAN TAG#URR8PPP
Spring MVC Request URLs in JSP
I am writing a web application using Spring MVC. I am using annotations for the controllers, etc. Everything is working fine, except when it comes to actual links in the application (form actions, <a>
tags, etc.) Current, I have this (obviously abbreviated):
<a>
//In the controller
@RequestMapping(value="/admin/listPeople", method=RequestMethod.GET)
//In the JSP
<a href="/admin/listPeople">Go to People List</a>
When I directly enter the URL like "http://localhost:8080/MyApp/admin/listPeople", the page loads correctly. However, the link above does not work. It looses the application name "MyApp".
Does anyone know if there is a way to configure Spring to throw on the application name on there?
Let me know if you need to see any of my Spring configuration. I am using the standard dispatcher servlet with a view resolver, etc.
<a href="<spring:url value="/admin/listPeople"/>">People</a>
7 Answers
7
You need to prepend context path to your links.
// somewhere on the top of your JSP
<c:set var="contextPath" value="$pageContext.request.contextPath"/>
...
<a href="$contextPath/admin/listPeople">Go to People List</a>
+1 Thanks, I thought of this but I'd rather do it with Spring somehow.
– Rachel G.
Aug 7 '11 at 1:29
There is no "Spring" way of doing this :) Only option that saves you from prepending $contextPath to your links is that you deploy your application as root, so that it's context path is "/" (as Kevin has described); but I would not recommend this approach because it will make your application dependent of its deployment.
– craftsman
Aug 7 '11 at 1:33
There's also a way with server.xml if I recall correctly.
– Kevin
Aug 7 '11 at 1:35
I am looking into whether a filter would help accomplish this. Like, using a RequestDispatcher.
– Rachel G.
Aug 7 '11 at 1:39
I don't think so. Your filters reside in your application and they can process only those requests which are sent to your application. If a request does not have the correct context path (MyApp in your case), servlet container will not send it to your application at all.
– craftsman
Aug 7 '11 at 1:44
The c:url
tag will append the context path to your URL. For example:
c:url
<c:url value="/admin/listPeople"/>
Alternately, I prefer to use relative URLs as much as possible in my Spring MVC apps as well. So if the page is at /MyApp/index
, the link <a href="admin/listPeople">
will take me to the listPeople
page.
/MyApp/index
<a href="admin/listPeople">
listPeople
This also works if you are deeper in the URL hierarchy. You can use the ..
to traverse back up a level. So on the page at/MyApp/admin/people/aPerson
, using <a href="../listPeople">
will like back to the list page
..
/MyApp/admin/people/aPerson
<a href="../listPeople">
I prefer to use BASE tag:
<base href="$pageContext.request.scheme://$pageContext.request.serverName:$pageContext.request.serverPort$pageContext.request.contextPath/" />
Then, all your links can be like:
<a href="admin/listPeople">Go to People List</a>
I advise to read this before using the base tag: stackoverflow.com/questions/1889076/…
– Amr Mostafa
Jan 26 '14 at 9:27
As i have just been trying to find the answer to this question and this is the first google result.
This can be done now using the MvcUriComponentsBuilder
This is part of the 4.0 version of Spring MVC
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.html
The method needed is fromMappingName
From the documentation :
Create a URL from the name of a Spring MVC controller method's request mapping.
The configured HandlerMethodMappingNamingStrategy determines the names of controller method request mappings at startup. By default all mappings are assigned a name based on the capital letters of the class name, followed by "#" as separator, and then the method name. For example "PC#getPerson" for a class named PersonController with method getPerson. In case the naming convention does not produce unique results, an explicit name may be assigned through the name attribute of the @RequestMapping annotation.
This is aimed primarily for use in view rendering technologies and EL expressions. The Spring URL tag library registers this method as a function called "mvcUrl".
For example, given this controller:
@RequestMapping("/people")
class PersonController
@RequestMapping("/id")
public HttpEntity getPerson(@PathVariable String id) ...
A JSP can prepare a URL to the controller method as follows:
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<a href="$s:mvcUrl('PC#getPerson').arg(0,"123").build()">Get Person</a>
I usually configure tomcat to use context root of "/" or deploy the war as ROOT.war. Either way the war name does not become part of the URL.
You could use a servletRelativeAction. I'm not sure what versions this is available in (I'm using 4.0.x currently) and I haven't seen much documentation on this, but if you look at the code backing the spring form you can probably guess. Just make sure the path you pass it starts with a "/".
Example:
<form:form class="form-horizontal" name="form" servletRelativeAction="/j_spring_security_check" method="POST">
See org.springframework.web.servlet.tags.form.FormTag:
protected String resolveAction() throws JspException
String action = getAction();
String servletRelativeAction = getServletRelativeAction();
if (StringUtils.hasText(action))
action = getDisplayString(evaluate(ACTION_ATTRIBUTE, action));
return processAction(action);
else if (StringUtils.hasText(servletRelativeAction))
String pathToServlet = getRequestContext().getPathToServlet();
if (servletRelativeAction.startsWith("/") && !servletRelativeAction.startsWith(getRequestContext().getContextPath()))
servletRelativeAction = pathToServlet + servletRelativeAction;
servletRelativeAction = getDisplayString(evaluate(ACTION_ATTRIBUTE, servletRelativeAction));
return processAction(servletRelativeAction);
else
String requestUri = getRequestContext().getRequestUri();
ServletResponse response = this.pageContext.getResponse();
if (response instanceof HttpServletResponse)
requestUri = ((HttpServletResponse) response).encodeURL(requestUri);
String queryString = getRequestContext().getQueryString();
if (StringUtils.hasText(queryString))
requestUri += "?" + HtmlUtils.htmlEscape(queryString);
if (StringUtils.hasText(requestUri))
return processAction(requestUri);
else
throw new IllegalArgumentException("Attribute 'action' is required. " +
"Attempted to resolve against current request URI but request URI was null.");
Since it's been some years I thought I'd chip in for others looking for this. If you are using annotations and have a controller action like this for instance:
@RequestMapping("/new") //<--- relative url
public ModelAndView newConsultant()
ModelAndView mv = new ModelAndView("new_consultant");
try
List<Consultant> list = ConsultantDAO.getConsultants();
mv.addObject("consultants", list);
catch (Exception e)
e.printStackTrace();
return mv;
in your .jsp (view) you add this directive
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
and simply use
<spring:url value="/new" var="url" htmlEscape="true"/>
<a href="$url">Nuevo consultor</a>
where
value
's value should match @RequestMapping
's argument in the controller action and
value
@RequestMapping
var's
value is the name of the variable you use for href
var's
href
HIH
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This is possible in spring 3.0 with
<a href="<spring:url value="/admin/listPeople"/>">People</a>
– tterrace
Oct 18 '12 at 15:02