Search code examples
javaspringhtmlrequest-mapping

RequestMapping with String parameter containing URL


I have a Spring controller with two parameter long and String:

@RequestMapping(value = "/webpage")
@Controller
public class WebpageContentController {
//...
    @RequestMapping(value = "{webpageId}/{webpageAddress}", method = RequestMethod.GET)
    public String contentWebpageById(@PathVariable long webpageId, @PathVariable String webpageAddress) {
        System.out.println("webpageId=" + webpageId);
        System.out.println("webpageAddress=" + webpageAddress);
        //...
    }
//...

If I invoke it like this:

http://localhost:8080/webarch/webpage/1/blahblah

All is fine:

webpageId=1
webpageAddress=blahblah

But If I pass String parameter with slash (in this case URL address):

http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page

I get an error:

org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page] in DispatcherServlet with name 'appServlet'

How pass such parameter?


Solution

  • Well the error is caused by springs controllers mapping, when Spring sees url like

    http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
    

    It doesn't 'know' that the 'https://en.wikipedia.org/wiki/Main_Page' should be mapped as parameter to "{webpageId}/{webpageAddress}" mapping since every slash is interpreted as a deeper controler method mapping. It looks for controller method mapping like (webpage/1/http:{anotherMapping}/wiki{anotherMapping}/Main_Page{anotherMapping}) wich this kind of mapping is obviously not handled by "{webpageId}/{webpageAddress}"

    EDIT

    According to your comment you can try something like this

    @RequestMapping(value = "/{webpageId}/**", method = RequestMethod.GET)
    public String contentWebpageById(HttpServletRequest request) {
    
        String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);  
    
        String extractedPathParam = pathMatcher.extractPathWithinPattern(pattern, request.getServletPath());
        extractedPathParam = extractedPathParam.replace("http:/", "http://");
        extractedPathParam = extractedPathParam.replace("https:/", "https://");
        //do whatever you want with parsed string..
    }
    

    Using spring 4.2.1

    SomeParsing should use some Regular Expression to extract only the URL 'variable'