Chris Irwin
Chris Irwin

Reputation: 41

Spring: Controller @RequestMapping to jsp

Using Spring 3.1.2

How do you reference the Annotated value of the CONTROLLER (not method) RequestMapping from a jsp so I can build URL's relative to the Controller. If the method level request mappings are referenced, it will cause my links to not work, so they cannot be part of the this in any way.

For example (Note that this controller's mapping is "/foo/test"):

@Controller
@RequestMapping("/foo/test")
public class FooController {

    @RequestMapping(value="/this", method=RequestMethod.GET)
    public String getThis() {
        return "test/this";
    }

    @RequestMapping(value="/that", method=RequestMethod.GET)
    public String getThat() {
        return "test/that";
    }

    @RequestMapping(value="/other", method=RequestMethod.GET)
    public String getOther() {
        return "test/other";
    }
}

...and from my this.jsp:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>
<s:url value="${controllerRequestMapping}" var="baseUrl"/>

<a href="${baseUrl}/that">That</a>
<a href="${baseUrl}/other">Other</a>

The reason I need to access the RequestMapping is because my views may be accessed from multiple Controllers. Note that this controller's mapping is "/bar/test"!

@Controller
@RequestMapping("/bar/test")
public class BarController {

    @RequestMapping(value="/this", method=RequestMethod.GET)
    public String getThis() {
        return "test/this";
    }

    @RequestMapping(value="/that", method=RequestMethod.GET)
    public String getThat() {
        return "test/that";
    }

    @RequestMapping(value="/other", method=RequestMethod.GET)
    public String getOther() {
        return "test/other";
    }
}

Some of my Controller level request mappings have path variables too, so getting just the string value of the request mapping will not work. It will have to be resolved:

@Controller
@RequestMapping("/something/{anything}/test/")
public class SomethingController {
...
}

Update

Maybe if there was a way to modify the context path by appending the Controller request mapping to it BEFORE the Spring URL tag, that would solve the problem.

contextPath = contextPath/controllerRequestMapping

Then, I could do something like this because I believe Spring will automatically retrieve the current context path:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>

<a href="<s:url value="/that"/>">That</a>
<a href="<s:url value="/other"/>">Other</a>

This, of course, would be optimal! Ideas? Thoughts...?

Thanks in advance!

Upvotes: 4

Views: 21654

Answers (5)

Ashok Korlakunta
Ashok Korlakunta

Reputation: 31

As of 4.1 every @RequestMapping is assigned a default name based on the capital letters of the class and the full method name. For example, the method getFoo in class FooController is assigned the name "FC#getFoo". This naming strategy isenter code here pluggable by implementing HandlerMethodMappingNamingStrategy and configuring it on your RequestMappingHandlerMapping. Furthermore the @RequestMapping annotation includes a name attribute that can be used to override the default strategy. The Spring JSP tag library provides a function called mvcUrl that can be used to prepare links to controller methods based on this mechanism.

For example given:

@RequestMapping("/people/{id}/addresses")
public class MyController {
@RequestMapping("/{country}")
public HttpEntity getAddress(@PathVariable String country) { ... }
}

The following JSP code can prepare a link:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
...
<a href="${s:mvcUrl('MC#getPerson').arg(0,'US').buildAndExpand('123')}">Get Address</a>

Make sure you have configured your MVC using either Java Config or XML way and not both the ways. You will get an exception as :more than one RequestMappingInfo HandlerMapping found.

Upvotes: 0

FFL
FFL

Reputation: 669

See code below to access request mapping, if you are using Spring 3.1 and above. I'm not sure if this is what you require. This is just an attempt and of course i do not know of any straight forward way. Invoke getRequestMappings() from inside a method that has request mapping.

public class FooController{

    private RequestMappingHandlerMapping handlerMapping = null;

    @Autowired
    public FooController(RequestMappingHandlerMapping handlerMapping){
        this.handlerMapping = handlerMapping;
    }

    public Set<String> getRequestMappings(){
        Map<RequestMappingInfo, HandlerMethod> handlerMap = handlerMapping.getHandlerMethods();
        Iterator<RequestMappingInfo> itr = handlerMap.keySet().iterator();
        while(itr.hasNext()){
            RequestMappingInfo info = itr.next();
            PatternsRequestCondition condition = info.getPatternsCondition();
            Set<String> paths = condition.getPatterns();
            HandlerMethod method = handlerMap.get(info);
            if(method.getMethod().getName().equals(Thread.currentThread().getStackTrace()[2].getMethodName()))
            return paths;

            }
        return new HashSet<String>();
    }



}

Upvotes: 0

stephen.hanson
stephen.hanson

Reputation: 9604

You could get the URI using the Servlet API. There is no "Spring" way to do this as far as I know.

@RequestMapping(value="/this", method=RequestMethod.GET)
public String getThis(HttpServletRequest request, Model m) {
    m.addAttribute("path", request.getRequestURI());
    return "test/this";
}

Then in your JSP:

<a href="${path}">This</a>

For more information about HttpServletRequest, see the API here.

Upvotes: 3

Japan Trivedi
Japan Trivedi

Reputation: 4483

According to me there is no difference in putting @RequestMapping annotation at both class level and method level. Instead of that you can have the combined @RequestMapping annotation on top of the method only.

So now your method level annotation will be something like this.

@RequestMapping(value="("/foo/test/this", method=RequestMethod.GET)

or

@RequestMapping(value="("/bar/test/this", method=RequestMethod.GET)

Now since both your methods return the same view you can have just one method for both of them. And in the annotation mapping value instead of foo and bar you can inroduce one path variable {from}. So finally your annotation and the method will be like this.

@RequestMapping(value="("/{from}/test/this", method=RequestMethod.GET)
public String getThis(@PathVariable("from") String from) {       
    return "test/this";       
}

And after doing this in your method you can perform different calculations or operations on based of the runtime value of path variable from you get. And in the JSP page you can simple get this value with ${from}.

Hope this helps you. Cheers.

Upvotes: 0

matt b
matt b

Reputation: 139931

There is no built-in way to access the @RequestMapping, but you can simply add the URL to the model and reference it from the view that way.

Upvotes: 0

Related Questions