RequestMapping with String parameter containing URL - java

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?

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'

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

Related

How can I pass a value with '/' symbol as get parameter to my controller?

I have controller:
#RestController
public class MyController {
#GetMapping(value = "/products/{value}")
public String get(#PathVariable String value) {
System.out.println(value);
return "OK";
}
}
After start server I try to send a message like this:
http://localhost:8080/products/Mazda
and I see in console Mazda. But when I send value with a backslash:
http://localhost:8080/products/Mazda\6
I get an error:
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
How can I pass a value with '\' symbol as get parameter to my controller?
I expect: Mazda\6
First, you need to encode the path variable on the client side. Here is an example for Java:
URLEncoder.encode("Mazda\\6", "UTF-8");
The result will be Mazda%5C6.
The second step is to allow the processing of requests containing special characters in their URLs.
Third, decode the string in the controller:
String decodedValue = URLDecoder.decode(value, "UTF-8");

How to correctly escape '/' in Spring Rest #PathVariable

In Spring Boot 1.5.4 I have a request mapping like this:
#RequestMapping(value = "/graph/{graphId}/details/{iri:.+}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public JSONObject getGraph(#PathVariable Long graphId,
#PathVariable String iri) {
log.debug("Details called for graph ID {} for IRI {}", graphId, iri);
return detailsService.getDetails(graphId, iri);
}
Accessing
http://localhost:9000/api/v1/graph/2/details/http%3Anthnth33
works fine and the server maps the request correctly and the code returns the expected result
But accessing
http://localhost:9000/api/v1/graph/2/details/http%3A%2F%2Fserverurl.net%2Fv1%2Fus%2Fh.schumacher%408tsch.net%2Fn%2FLouSchumacher
gives a bad server request (Failed to load resource: the server responded with a status of 400 (Bad Request)). The request mapping to the end point isn't even done in that case.
Obviously the slash '/' encoded as %2F (using encodeURIComponent()) causes trouble. Why? What am I missing? How should uri parameter then be encoded?
The question is not only about how to extract PathVariables but more on how to force String to recognize the correct mapping.
The issue with your example is how Spring is doing path matching. The URL you have provided as example
http://localhost:9000/api/v1/graph/2/details/http%3A%2F%2Fserverurl.net%2Fv1%2Fus%2Fh.schumacher%408tsch.net%2Fn%2FLouSchumacher
will be decoded into by container
http://localhost:9000/api/v1/graph/2/details/http://serverurl.net/v1/us/h.schumacher#8tsch.net/n/LouSchumacher
before processing by Spring matcher. This makes matche think that this only http: corresponds {iri:.+} and as later goes / so it is some longer path you don't have a mapping for.
The approach described here should work for you: Spring 3 RequestMapping: Get path value
#RequestMapping(value = "/graph/{graphId}/details/**",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public JSONObject getGraph(#PathVariable Long graphId,
HttpServletRequest request) {
String iri = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
log.debug("Details called for graph ID {} for IRI {}", graphId, iri);
return detailsService.getDetails(graphId, iri);
}

How to get parameter which is containing question mark(?) from rest url in spring

i need get string from url where is "?" but controller does not accept "?"
I need send something like "Hello world?"
but I get only "Hello world"
I find solution for dot(.) -- value = "{textToTransform:.+}"
#RestController
#RequestMapping(textTransformCtrl.BASE_URI)
public class textTransformCtrl {
#Autowired
private TextTransformatorService textTransformatorService;
public static final String BASE_URI = "transform/text";
#RequestMapping(value = "{textToTransform:.+}")
public String getText(#PathVariable final String textToTransform) {
return textTransformatorService.transformText(textToTransform);
}
}
Question mark is a reserved character in URLs. It indicates where the query string starts.
If you want to send a ? as a parameter value and be able to read it on server side, you must URL encode it.
When URL encoded, Hello world? becomes Hello+world%3F.
You can use %3F to manually encode it or take a look at UriBuilder

How to deal with dot in an url path in writing service

I am writing a "GET" endpoint looks like following:
#RequestMapping(value = "/{configSetId}/{version}", method = RequestMethod.GET, produces = { "application/json" })
public ResponseEntity<List<Metadata>> getMetadatasByConfigSetIdAndVersion(
#PathVariable("configSetId") final String configSetId,
#PathVariable("version") final String version) {
return ResponseEntity.ok(metadataService.getMetadatasByConfigSetIdAndVersion(configSetId, version));
}
So I can send a "GET" request to localhost:8080/{configSetId}/{version}, for example: localhost:8080/configSet1/v1
But the problem is if the version is "v1.02", then the ".02" will be ignored and the version I got is v1. How can I avoid this behaivor? Thank you!
Since "." is special character so don't use it directly on your request.
Instead of
v1.02
Just try
v1%2E02
Where %2E is URL encoding of ".".
For more information, please refer to this link HTML URL Encoding

Is it possible to extarct path parameter and url in jersey

I am actually trying to separate URL and path parameters in jersey implementation.
My request URL is /web/seller/{pathpartma1}/{pathparam2}
I need to get the following data from the request
Request url: /web/seller
Parameter1 name = pathpartma1
Parameter2 name = pathparam2
My method looks like this
#GET
#Path(value = "/web/seller/{pathparam1}/{pathparam2}")
#Produces(MediaType.JSON)
public String myMethod(#Context HttpServletRequest request,#PathParam("pathparam1") String pathparam1, #PathParam("pathparam2") String pathparam2)
{
/////
}
Can some one tell if it is possible to extract url and path parameter names in my method.
Your Path is incorrect - the lef tbrace is missing at the end.

Categories

Resources