Has problems after #PathVariable parameter value containing the '/' character,with Spring MVC - spring-mvc

I have a use case. Spring MVC REST Url receive content using the GET method code is as follows:
#RequestMapping("/q/{key}")
public String query(#PathVariable() String key, Model model){
//todo`
}
But the front end of such a request: /q/SiGeC%2FSi%E5%BC%82%E8%B4%A8%E7%BB%93. %2F decoded character /. The controller can not match mapping request.
How should I do?

You can include regular expressions in your path variable as such:
#RequestMapping("/q/{key:.*}")
This will grab EVERYTHING after the /q/. Or you can make it a more specific regex to match the pattern you are actually expecting.

Annotations of # PathVariable may not be able to solve this problem.Last use the workaround is resolved.Code is as follows:
#RequestMapping("/q/**")

Related

BizTalk WCF-WebHttp URI mapping problem with escaped variable

I am trying to use BizTak WCF-WebHttp adapter to send to Service Desk Plus CMDB API using Variable Mapping.
When trying using the browser, it works fine. Service Desk Plus CMDB API requires an URI like (strictly shortened for readability):
http://host.com/api/cmdb/ci?OPERATION_NAME=read&TECHNICIAN_KEY=Mykey&format=XML&INPUT_DATA=<?xml version='1.0'?>
<API>
<name>email#host.com</name>
</API>
I have used the URI http://host.com/api/cmdb/ci and URL Mapping.
<BtsHttpUrlMapping>
<Operation Url="?OPERATION_NAME=read&TECHNICIAN_KEY=MyKey&format=XML&INPUT_DATA=<?xml version=&apos;1.0&apos;?>
<API>
<name>email#host.com</name>
</API>"/>
</BtsHttpUrlMapping>
This works fine, but I need a more dynamic approach. I tried using Variable Mapping, so I replaced the hard coded email address with a variable.
<BtsHttpUrlMapping>
<Operation Url="?OPERATION_NAME=read&TECHNICIAN_KEY=MyKey&format=XML&INPUT_DATA=<?xml version=&apos;1.0&apos;?>
<API>
<name>{email}</name>
</API>"/>
</BtsHttpUrlMapping>
Trying to save the URL Mapping with the variable I get an error.
WCF-WebHttp Transport Properties
Error saving properties.
(System.InvalidOperationException) The UriTemplate
?OPERATION_NAME=read&TECHNICIAN_KEY=MyKey&format=XML&INPUT_DATA=<?xml version='1.0'?><API><name>{email}</name></API>
is not valid; each portion of the query string must be of the form 'name=value', when value cannot be a compound segment. See the documentation for UriTemplate for more details.
If I try a variable that is not within the escaped XML string, like with the key, then it works fine.
<BtsHttpUrlMapping>
<Operation Url="?OPERATION_NAME=read&TECHNICIAN_KEY={key}&format=XML&INPUT_DATA=<?xml version=&apos;1.0&apos;?>
<API>
<value>email#host.com</value>
</API>"/>
</BtsHttpUrlMapping>
My intention is to be able to use a variable within the escaped XML string. If that is not possible; I will have to turn to a dynamic adapter and Create the URI and URL mapping in an orchestration.
Did u understand why it said each portion of the query string must be of the form 'name=value? There are just a few ways to make UriTemplates work.
See how a UriTemplate works here. Here is an example that is valid:
weather/{state}/{city}?forecast={day}
So in your case you should make everything after INPUT_DATA= a variable. Which means the whole escaped XML string you were talking about.

Asp.Net Web Api Allow Url Encoded Forward/Backward Slash

I am trying to send a string with some special characters to my Asp.Net Web Api controller. However, Asp.Net can't seem to resolve the url encoded string. Sending something like "A%2F223%2F4" is the encoding for "A/223/4" and the same also doesn't work for backward slashes. It does work for other special characters though. Is there any way to get this working? Or is it possible to turn the automatic decoding off, so that I can do it manually?
This is my functions inside my controller:
[HttpGet, Route("getByArtNr/{articleNr}")]
public IHttpActionResult GetByArtNr(string articleNr)
{
Article article = dbContext.Article.Where(x => x.ArtNr == articleNr).FirstOrDefault();
if(article == null)
return NotFound();
return Ok(article);
}
Example request:
http://localhost:54282/api/v1/article/getByArtNr/A%2F223%2F4/
In order to send a string which has / (slashes) in it, we can use the wildcard parameters in the route. Something like this:
Route("getByArtNr/{*articleNr}")
This will allow for a chunk of a URL with multiple / characters to be read as a single parameter.
Hope it helps.

Spring Boot Filter URL Mapping

The request mapping for my controller is something like this:
/hospital/{hospitalId}/department/{departmentId}/doctors
And i tried to add the pattern for authentication required filter:
/hospital/*/department/*/doctors
But it's not working. It's there a chance to make this work?
The mapping for a filter isn't a Ant-style mapping as you're used to in Spring, but a mapping as defined in the Servlet specification. In section 12.2 it says:
the following syntax is used to define mappings:
A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
A string beginning with a ‘*.’ prefix is used as an extension mapping.
The empty string ("") is a special URL pattern that exactly maps to the
application's context root, i.e., requests of the form http://host:port//. In this case the path info is ’/’ and the servlet path and context path is empty string (““).
A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
All other strings are used for exact matches only.
/hospital/*/department/*/doctors only meets the criteria of the final bullet so it's treated as an exact match.
The best that you can do within confines of the servlet specification is to use /hospital/* and then do some secondary matching in your filter's code. You could use Spring Framework's org.springframework.util.AntPathMatcher to do so.

How to map several segments of URL to one PathVariable in spring-mvc?

I'm working on a webapp, one function of which was to list all the files under given path. I tried to map several segments of URL to one PathVariable like this :
#RequestMapping("/list/{path}")
public String listFilesUnderPath(#PathVariable String path, Model model) {
//.... add the file list to the model
return "list"; //the model name
}
It didn't work. When the request url was like /list/folder_a/folder_aa, RequestMappingHandlerMapping complained : "Did not find handler method for ..."
Since the given path could contains any number of segments, it's not practical to write a method for every possible situation.
In REST each URL is a separate resource, so I don't think you can have a generic solution. I can think of two options
One option is to change the mapping to #RequestMapping("/list/**") (path parameter no longer needed) and extract the whole path from request
Second option is to create several methods, with mappings like #RequestMapping("/list/{level1}"), #RequestMapping("/list/{level1}/{level2}"), #RequestMapping("/list/{level1}/{level2}/{level3}")... concatenate the path in method bodies and call one method that does the job. This, of course, has a downside that you can only support a limited folder depth (you can make a dozen methods with these mappings if it's not too ugly for you)
You can capture zero or more path segments by appending an asterisk to the path pattern.
From the Spring documentation on PathPattern:
{*spring} matches zero or more path segments until the end of the path and captures it as a variable named "spring"
Note that the leading slash is part of the captured path as mentioned in the example on the same page:
/resources/{*path} — matches all files underneath the /resources/, as well as /resources, and captures their relative path in a variable named "path"; /resources/image.png will match with "path" → "/image.png", and /resources/css/spring.css will match with "path" → "/css/spring.css"
For your particular problem the solution would be:
#RequestMapping("/list/{*path}") // Use *path instead of path
public String listFilesUnderPath(#PathVariable String path, Model model) {
//.... add the file list to the model
return "list"; //the model name
}

MVC3 Stripping Query String from my Parameter

I have an MVC3 Action that takes a parameter (a URL) that may have a query string in it. My action signature looks like this:
GetUrl(string url)
I expect to be able to send it urls, and it works every time unless there is a query string in the url. For example, if I navigate to:
MyController/GetUrl/www.google.com
the url parameter comes accross as "www.google.com" -Perfect. However, if I send
MyController/GetUrl/www.google.com/?id=3
the url parameter comes accross as "www.google.com/" How do I get MVC3 to give me the whole URL in that parameter? -Including the query string?
It's simple enough to just URL.Encode the passed in URL on the page but you're opening your self to some possible security problems.
I would suggest you encrypt the url then encode it then pass that as your value, the protects you from having people just passing in anything into your app.
That's because system considers id=3 as its own query string. When you construct the link in the view, you need to use #Url.Encode to convert raw url string to encoded string to be accepted as parameter of the controller.

Resources