1

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?

mkczyk
  • 2,460
  • 2
  • 25
  • 40

2 Answers2

3

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'

Oskar Dajnowicz
  • 1,700
  • 12
  • 16
  • I wanted to do GET method like this (don't POST): `https://web.archive.org/web/20150609000851/http://en.wikipedia.org/wiki/Main_Page` There is no way to do this? Maybe value mapping with `*` or custom `@RequestMapping`? – mkczyk Nov 12 '15 at 01:27
  • Yes this work, thanks. But with this solution I must parse URL, because I getting `/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page` instead of `https://en.wikipedia.org/wiki/Main_Page`. [Here](http://stackoverflow.com/a/2335449/2442133) I found solution that give me `https:/en.wikipedia.org/wiki/Main_Page`. I don't know why `https://` is replaced with `https:/` (one slash fewer). – mkczyk Nov 14 '15 at 20:01
  • @mkr321 i updated my answer to exactly fit your needs, it will always merge slashes into maximm one slash because this is how RequestMapping works – Oskar Dajnowicz Nov 14 '15 at 21:11
1

Just encode all special characters in the URL.

https://en.wikipedia.org/wiki/Main_Page

becomes this:

https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMain_Page

and you can pass it as URL parameter without any problems. Decoding is done automatically, so if you access the parameter as variable in your controller, it contains the URL already decoded and you can use it without any converting needed.

More information about URL encoding: https://en.wikipedia.org/wiki/Percent-encoding

dunni
  • 43,386
  • 10
  • 104
  • 99