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
I've developed a Spring API /getFileData, which accepts three URI parameters viz. businessDate/fileName/recordId. It is possible to have any of them can be passed as null. But I still want my API to be working in this case also. How can I achieve this?
I've tried using #GetMapping("getFileData/{businessDate}/{fileName}/{recordId}", "getFileData/{businessDate}//", "getFileData/{businessDate}/{fileName}/")..so on like this for all possible combinations.
#RequestMapping(value = "/getFileData/{businessDate}/{fileName}/{recordId}", method = RequestMethod.GET)
I want this API to be working for all the combination of URI parameters if something get missed out. for example someone requested,
/getFileData///22 or
/getFileData/22Dec2018/ or
/getFileData//treasure/22
You can do that with a #RequestParam of type java.util.Map.
With your design, you will have various #PathVariable params in the controller method as well as the order of path variables /{var1}/{var2}... constructs the url so I don't think it would be possible to skip a path variable in the url and still call the same controller method.
While I was modifying the code written by other developer I come across an end point #RequestMapping(value = "/ICD/{icdcode:.+} and wanted to know what is :.+ in the path variable.
This has already been answered
Spring MVC #PathVariable getting truncated
Spring MVC #PathVariable with dot (.) is getting truncated
Spring - Path variable truncate after dot - annotation
Basically, it is a regular expression. Spring considers that anything behind the last dot is an extension and get rid of it.
If you have a mapping to /somepath/{email} and try /somepath/test#gmail.com the value for the path parameter email will be test#gmail
Using the regular expression {pathparam:.+} everything is considered part of the value, even what is behind the last dot.
I came across a method in the controller. What is this id:.+ ??
#RequestMapping(value="/index/{endpoint}/{type}/{id:.+}", method=RequestMethod.POST, consumes=kContentType, produces=kProducesType)
#ResponseBody
public String indexData(#PathVariable(value="endpoint") String endpoint, #PathVariable(value="type") String type, #PathVariable(value="id") String id, #RequestBody String body, HttpServletRequest request) {
logger.debug("In web controller for endpoint " + endpoint);
return indexController.indexData(endpoint, type, id, body, getSecurityContextProvider(request));
}
The syntax of a path variable in a spring MVC controller requestmapping is {variable_name:regular_expression}. You can optionally omit the regular expression, which leads to what you see more often, {id}.
So, for the example /index/{endpoint}/{type}/{id:.+} the variable name is id and the regular expression is .+ (see below reference to spring docs).
The regular expression .+ is stating "match the metacharacter . one or more times". The '.' metacharacter represents any character including white space (though some implementations will not match newlines). See http://en.wikipedia.org/wiki/Regular_expression
The regular expression is being used to help Spring determine the value of the variable because you can have complex variable names or there might be other important information at the end of the path that would otherwise get sucked into the variable value if Spring just said "go until the end of the path" (eg. filename extensions or path variables).
It's possible that in your example, the id variable can contain special characters that would otherwise cause Spring to terminate the variable prematurely. I've run into this problem before when trying to use a filename that contained a file extension (foobar.jpg). Spring would return only the "foobar" part of the variable because Spring was assuming I wanted it to terminate the variable value at the period delimiter. So, in this case, to make sure that "id" matches the full value, you put the regex that tells Spring to go ahead and match everything between the last forward slash and the end of the path. SO Reference: Spring MVC #PathVariable getting truncated
Here's the excerpt from the Spring docs that deals with complex variable matching:
Sometimes you need more precision in defining URI template variables. Consider the URL "/spring-web/spring-web-3.0.5.jar". How do you break it down into multiple parts?
The #RequestMapping annotation supports the use of regular expressions in URI template variables. The syntax is {varName:regex} where the first part defines the variable name and the second - the regular expression."
Here is their (fairly complex) example:
#RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
public void handle(#PathVariable String version, #PathVariable String extension) {
// ...
}
Source: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
The example they provide shows how you perform complex mappings from requests to controller method paramters that you wouldn't be able to without using a regular expression.
To be more specific, right now I'm having a problem with the separator on decimal numbers (comma vs dot): If the wrong separator comes in a url parameter the webservice returns 404. But I'd like to find a proper solution that will handle the JSON reading/writing as well.
Note:
I've tried the answer in this other question but it references classes I don't have in my Jersey jars (If, QuantityXmlAdapter and NumberPersonalizedXmlAdapter) and I can't find a clue about them on Google.
I read your questions as this.
Your method
#GET
#Path('/resource/{decimal}')
public Response getResoureWithDecimal(#PathParam("decimal") double decimal)
Your request
GET /resource/1,2
Clearly, 1,2 is not a Java double and JAX-RS has no way to convert it to one.
Possible solution
Use a String as the parameter type and convert it with your own converter.
#GET
#Path('/resource/{decimal}')
public Response getResoureWithDecimal(#PathParam("decimal") String decimal) {
double decimalAsDouble = convertStringWithCommaToDouble(decimal);
// ...
}
The implementation of convertStringWithCommaToDouble(String) is up to you.
I am using the Spring RestTemplate to make calls to a Apache Solr index. I form a request string manually and don't supply any intentional {variable_name} template expansion variables. Part of the query is the term {!lucene q.op=OR}. Unfortunately this gets processed by the URITemplate engine as part of a restTemplate.getForObject call.
Ideally i would like to stop this processing. Is there away of escaping the { } characters so that URITemplate doesn't process them? I have tried encoding the characters but RestTemplate assumes a non-encoded string so they are encoded twice and cause a 400: Bad Request on the backend.
Sample URL:
http://localhost/solr/select?q={!lucene
q.op=OR}se_genbanklocus:*
se_gb_create:* se_gb_update:*
se_clone_name:*
se_sample_tissue:*&facet=true&facet.limit=3&facet.mincount=1&facet.field=se_sample_tissue&facet.field=se_sample_tissue_name&facet.field=se_sample_tissue_code&facet.field=se_sample_tissue_class&facet.field=se_nuc_acid_type&facet.field=ssam_sample_georegion&start=0&rows=10
I've found a work around in which i can use the template to expand one variable which contains the offending {!lucene q.op=OR}
restTemplate.getForObject(solrServer+"select?{query}" , String.class, requestString );
The problem here is that you're using RestTemplate for something it's not designed for. The sample URL you gave is not a REST-style URL, it's just a mass of query parameters, using encoded characters that you're not going to find in a REST scheme, hence the difficulty with unwanted substitutions.
How about using the overloaded method that accepts a URI?