Request Mapping with a dot (.) in last path - spring-mvc

I have following request mapping.
#RequestMapping(value = "/{userId}", produces = { MediaTypes.HAL_JSON_VALUE })
#ResponseStatus(HttpStatus.OK)
public Resource<UserDTO> findUser(#PathVariable final String userId) {
User user = administrationService.getSecurityUserById(userId);
return userResourceAssembler.toResource(modelMapper.map(user, UserDTO.class));
}
I use RestTemplate to get the resource. The user ids passed in the url contain a dot (.) like: john.doe -> request URL: http://mysite/users/john.doe
When the above method gets called I only get john in #PathVariable userId.
How can this be fixed? to get john.doe
Thx.

anything that goes after a dot in RequestMapping is considered an extension and therefore ignored, if you want to be able to read along with the dot and the rest of the string I recommend using a regex in your Request mapping such as: /{userId:.+}
more detailed explanation can be found here: Spring MVC #PathVariable with dot (.) is getting truncated

Related

Creating a route template that matches all urls that starts with a specific pattern in ASP.NET Core

I have an application that is written on the top of ASP.NET Core 5 / .NET 5 Framework. I need to create a route template that would direct any URL that starts with /homes-for-sale-in-{city}-{id:int} to define controller/action.
Here are some examples of urls
/homes-for-sale-in-los-angeles-100/condo,apartment_type
/homes-for-sale-in-los-angeles-100/0-5000_price/10_page
/homes-for-sale-in-los-angeles-100/condo_type/0-5000_price/2_page
.... yes there are many more
I tried the following pattern
[Route("/homes-for-sale-in-{city}-{id:int}{*.}", Name = "HomesForSaleByCity")]
public async Task<IActionResult> Display(string city, id? id)
{
return View();
}
But I get this error:
RoutePatternException: A path segment that contains more than one section, such as a literal section or a parameter, cannot contain a catch-all parameter.
How can I add a pattern that would redirect any url that would starts with a pattern?
This did the trick
[Route("/homes-for-sale-in-{city}-{id:int}/{**filters}", Name = "HomesForSaleByCity")]
public async Task<IActionResult> Display(string city, id? id, string filters = "")
{
return View();
}
I believe you need to use regex for your routing, and may refer this page once.

CreatedAtRoute can't find route matching supplied values

I am running into a problem with a .NET Core tutorial. It is written in .NET Core 2.2, but I want to use the current release 3.0.
This is also the only difference I can find in my setup vs the tutorial's.
The issue is as follows:
I have a HttpPost route with a CreatedAtRoute call in it, but that can't find the route it has to.
I always get this error when testing through Postman:
System.InvalidOperationException: No route matches the supplied values.
at Microsoft.AspNetCore.Mvc.CreatedAtRouteResult.OnFormatting(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(ActionContext context, ObjectResult result, Type objectType, Object value)
...
But when checking through the debugger I see that everything goes fine, excpet for this line. So the new photo I want to upload is also added in Cloudinary and into the database.
The call I make is:
return CreatedAtRoute("GetPhoto", new {id = photo.Id}, photoToReturn);
This should find this route, in the same file:
[HttpGet("{id}", Name = "GetPhoto")]
public async Task<IActionResult> GetPhoto(int id)
{
Is there anything I miss here? I haven't found any useful answer yet...
Edit: public repo available, when cloning and running this, I still get the same error...
Edit 2: in the meanwhile, the tutorial covered more topics and I have found this:
CreatedAtRoute that calls another Controller with:
return CreatedAtRoute("GetUser",new {Controller="Users",id=createdUser.Id}, userToReturn);
works, when trying to call a route inside the same controller, it fails, also with this one:
return CreatedAtRoute(nameof(GetMessage), new {Controller = "Messages", id = message.Id}, message);
To call this route in the same controller:
[HttpGet("{id}", Name = "GetMessage")]
public async Task<IActionResult> GetMessage(int userId, int id)
Instead of
[HttpGet("{id}", Name = "GetPhoto")]
Use:
[HttpGet("/{id}", Name = "GetPhoto")]
I was getting same error and i solved it by putting '/' before id.

Url.OriginalString vs Url.AbsoluteUri

What is the difference between HttpContext.Current.Request.Url.OriginalString and HttpContext.Current.Request.Url.AbsoluteUri?
I need to get the URL in the page load, but confused about the both.
Depending on the url, you could get the same result. It depends how exact you want it to be, if you want all fragments, and how you want to use it.
The following is for Uri but I think it applies to Url too (a url is a uri, essentially).
AbsoluteUri
The AbsoluteUri property includes the entire URI stored in the Uri instance, including all fragments and query strings.
This
Uri baseUri= new Uri("http://www.contoso.com");
Uri myUri = new Uri(baseUri,"catalog/shownew.htm?date=today");
Console.WriteLine(myUri.AbsoluteUri);
will return
http://www.contoso.com/catalog/shownew.htm?date=today
https://msdn.microsoft.com/en-us/library/system.uri.absoluteuri(v=vs.110).aspx
Uri.OriginalString
Gets the original URI string that was passed to the Uri constructor.
The following example creates a new Uri instance from a string. It illustrates the difference between the value returned from OriginalString, which returns the string that was passed to the constructor, and from a call to ToString, which returns the canonical form of the string.
// Create a new Uri from a string address.
Uri uriAddress = new Uri("HTTP://www.ConToso.com:80//thick%20and%20thin.htm");
// Write the new Uri to the console and note the difference in the two values.
// ToString() gives the canonical version. OriginalString gives the orginal
// string that was passed to the constructor.
// The following outputs "http://www.contoso.com/thick and thin.htm".
Console.WriteLine(uriAddress.ToString());
// The following outputs "HTTP://www.ConToso.com:80//thick%20and%20thin.htm".
Console.WriteLine(uriAddress.OriginalString);
https://msdn.microsoft.com/en-us/library/system.uri.originalstring(v=vs.110).aspx

Can Spring be directed to take a parameter from either the body or the URL?

An argument to a Spring MVC method can be declared as RequestBody or RequestParam. Is there a way to say, "Take this value from either the body, if provided, or the URL parameter, if not"? That is, give the user flexibility to pass it either way which is convenient for them.
You can make both variables and check them both for null later on in your code
like this :
#RequestMapping(value = GET_SOMETHING, params = {"page"}, method = RequestMethod.GET)
public
#ResponseBody
JSONObject getPromoByBusinessId(
#PathVariable("businessId") String businessId, #RequestParam("page") int page,
#RequestParam("valid") Boolean valid,
#RequestParam("q") String promoName) throws Exception {}
and then use a series if if-else to react to requests.
I wrote it to work with any of the three params be null or empty, react to all different scenarios.
To make them optional, see :
Spring Web MVC: Use same request mapping for request parameter and path variable
HttpServletRequest interface should help solve this problem
#RequestMapping(value="/getInfo",method=RequestMethod.POST)
#ResponseBody
public String getInfo(HttpServletRequest request) {
String name=request.getParameter("name");
return name;
}
Now, based on request data coming from body or parameter the value will be picked up
C:\Users\sushil
λ curl http://localhost:8080/getInfo?name=sushil-testing-parameter
sushil-testing-parameter
C:\Users\sushil
λ curl -d "name=sushil-testing-requestbody" http://localhost:8080/getInfo
sushil-testing-requestbody
C:\Users\sushil
λ

Spring MVC handler returns String with extra quotes

I'm using Spring 3.1 and I have a handler that should return a String value.
Here's how my handler looks like:
#RequestMapping(value = TEST_HANDLER_PATH, method = RequestMethod.POST)
public ResponseEntity<String> handleTest(HttpServletRequest request,
#RequestParam("parma1") String param) throws Exception {
String ret = ...
...
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "text/plain;charset=utf-8");
return new ResponseEntity<String>(ret, headers, HttpStatus.CREATED);
}
I also tried annotating method with #ResponseBody with return ret; at the end.
In both cases, when I hit the service, I get extra quotes around String value (e.g. "This is a test").
I'm guessing this is due to message conversion. That's why I tried defining Content-Type header, to hit StringHttpMessageConverter explicitly, to no avail.
Had the same problem.
Just make sure you register a org.springframework.http.converter.StringHttpMessageConverter as well as your Jackson one so that Strings are treated literally and not attempted to be converted to JSON (with extra quotes).
Just instantiate with default constructor or constructor with your preferred Charset. The media types should be set for you with the standard internal defaults. If you're configuring via code extending WebMvcConfigurerAdapter then you just add the converters in the configureMessageConverters(List<HttpMessageConverter<?>> converters) method.
In my case, I had over-engineered =)
Had introduced a converter for bean's toString Operations like this:
class SerializableToString implements Converter<Serializable, String>
restricting that (only to my beans), resolved the issue X)
Note: debugging with a breakpoint # org.springframework.core.convert.support.GenericConversionService.getConverter helped.
In a related scenario, I had an IntegrationFlow for a GET that incorrectly requested a transform. Basically the target service would receive the #PathVariable as a quote escaped string
return IntegrationFlows.from("getThing")
.transform(Transformers.toJson())
.handle(
The .transform(Transformers.toJson()) was forcing the strings to be escaped in the URI, so simply removing it - it shouldn't have been there - fixed the issue.
Turns out there was a JSON message converter registered in one of the imports.

Resources