Spring mvc controller - how to do url restrictions - spring-mvc

This is spring mvc controller /city/{cityName}
#RequestMapping(value = "/city/{cityName}")
public String getCity (#PathVariable("cityName") String cityName, Model uiModel) {
}
www.example.com/city/{cityName}
Here cityName is dynamically loaded from url, my website can't support some of cityName,
it supports only Bengaluru, Kochin, Hyderabad and Chennai, due to dynamic things
it supports other cities or whatever in the place of cityName, it gives error,
how to restrict cityName for only 4 cities mentioned above.
Is there any way in controller itself or we have to maintain table(hard coded hashtable)
Suggest which is the best way to do

If you just want to have the four cities hardcoded in your code, you can also specify them using regular expression in #RequestMapping.
#RequestMapping("/cities/{cityName:Bengaluru|Kochin|Hyderabad|Chennai}")
public String getCity(#PathVariable("cityName") String cityName) {
}
That way if you specify a city which does not match the allowed values your controller will automatically return HTTP 404.
Update: Fixed the sample, the regex should go in #RequestMapping, not #PathVariable, sorry for the mistake

You'll either need separate controller mappings or to look up the cityName somewhere. That doesn't have to be hard-coded; you could instead use a YAML or properties file to initialize a Set or look it up in a database.

We can do at controller level statically
#RequestMapping(value = "/city/{cityname:bengaluru|chennai|kochin|hyderabad}")
OR we can create tables, query and put it in hashtable at application start up time.

Related

ASP.Net MVC 5 Routing wildcard + querystring

I am using this Route filter
[Route("search/{*segments}")]
this takes all the segments I am providing which could be many.
Here is an example
http://localhost:50877/search/c_50_showcases%5E-displays/a_brand-name:33113319_balt:1623762%7Cmooreco:1672386/a_total-number-of-shelves:33111115429_5:3138:lt/so_ts
Now I also need the query string with this route but I am unable to make it work.
http://localhost:50877/search/?query=HP%20DesignJet&items=HEW51645A|ELI75220
It gives me 403 error.
The Web server is configured to not list the contents of this directory
How can I make a route that can take wildcard and query string to handle the incoming request. I am bound to use search in Route.
Also I tried with this
http://localhost:50877/search/test?query=HP%20DesignJet&items=HEW51645A|ELI75220
It works but this effects the SEO.
Defining action and route this way:
[System.Web.Mvc.Route("search/{*segments}")]
public ActionResult Search(string segments, string query, string items)
allows to get wildcard (in segments variable) and also query string parameters (query and items)

Can Spring MVC's REST framework accept query strings rather than PathVariables?

In all the tutorials and articles I have read regarding Spring 3's RESTful additions to Spring MVC, I have only ever seen one way for the use to pass in query data, via a #PathVariable, like so:
#RequestMapping(value="/shops/{name}", method=RequestMethod.GET)
public #ResponseBody Shop getShopInJSON(#PathVariable String name) {
...
}
which would respond to something like http://www.example.com/myservlet/shops/{name}, which could evaluate to http://www.example.com/myservlet/shops/thebestshoparound.
My question is this: Is it possible to set up a RESTful interface that takes requests based on classic query strings, e.g. http://www.example.com/myservlet/shops?name=thebestshoparound, instead of PathVariables?
This seems like a really simple question, but I can't find it anywhere online.
Yes, use the annotation #RequestParam, here is an example:
public #ResponseBody Shop getShopInJSON(#PathVariable String name, #RequestParam(value="query", required=false) String query) {
// do stuff
}

Values in braces in Spring Annotations

This might be a simple question for those who know Spring, but since I am a newbie, I will ask it anyway.
I am going through some Spring code and I am not able to understand the following-
#RequestMapping(value="/{id}")
public void show(#PathVariable("id") long id, Model model) {...}
The comment for this section of the code is - "When using URI Templates, access parameters using the #PathVariable annotation.
Now earlier, I came across code like
#RequestMapping(value="/url/path")
public String list(Model model) {...}
By this, I understand that whenever the url "/url/path" is encountered, the list() method will be called, but I am not able to make sense of the former annotation. What does it mean?
Also, the next line says #PathVariable annotations can be limited via regular expressions
#RequestMapping(value="/{id}")
public void show(#PathVariable("id:[\\d]*") String idl) {...} // will match only numberic IDs
What does it mean?
16.3.2.2 URI Template Patterns
URI templates can be used for convenient access to selected parts of a URL in a #RequestMapping method.
For example, the URI Template http://www.example.com/users/{userId} contains the variable userId. Assigning the value fred to the variable yields http://www.example.com/users/fred.
In Spring MVC you can use the #PathVariable annotation on a method argument to bind it to the value of a URI template variable:
So, in your example:
#RequestMapping(value="/{id}")
public void show(#PathVariable("id") long id, Model model) {...}
This will extract the part of the URL represented by {id}, and bind it to the id method parameter, e.g. the path /42 will bind 42 to id.

asp.net MVC: Pass query string as a string, or individual parameters?

In asp.net MVC I have a search action in my controller and I am trying to decide If I should pass the query to my repository as a string
public ActionResult Search(string query)
{
return View(_repository.ListPeople(query));
}
or as individual parameters:
public ActionResult Search(string FirstName, string LastName, System.Nullable<byte> Education)
{
return View(_repository.ListPeople(FirstName, LastName, Education));
}
A lot of examples I have seen online use the query string method, but to me it doesn't feel as "safe", even though it's a little easier to deal with when you have a bunch of parameters to pass in. Is there a general consensus as to the better way to do this?
I would favour model binding. That way if you decide to add extra search options you have no changes to make apart from the model class.
Info here and here
Personally, I prefer to not have the repository take on the responsibility of parsing a query string. Looking at it from a separation of concerns point of view, I feel that the repository should remain implementation-agnostic. Having to create query strings for unit testing, for example, is more cumbersome than calling the method directly with parameters.
That being said, I also prefer to have controllers interface with well-defined services, as well, as it helps to keep the controllers lighter, in my experience. I try to let the service act as a gateway to the repository, although there is no requirement to do so. There are two things that I will pass into a repository (or more likely, service), depending upon what the purpose of the call is - either a set of parameters, like you give in your second example, or as a constructed domain object, if applicable.
I would most definitely suggest going with the second route. There's no need to couple your controller with your repository. Let your repository be in charge of getting data, it shouldn't have to do any kind of parsing of a query string. That's not its job. Let the controller deal with that.

Remove field in wsdl in Asp.net webservice

I'm generating dto classes with a template engine and would like to exclude some properties in an asmx webservice, what, if possible, is the best way to do this?
Ex:
[WebMethod]
public ProductPackages GetPackages()
{
ProductPackages packages = new ProductPackages();
packages.Packages.add(new PackageDTO());
return packages;
}
The PackageDTO contains some properties that's not relevant for this service.
But as the class can be regenerated any time i can't apply [XmlIgnore] to the fields.
So I'm looking for a way to apply a "exclude list" without touching the actual class.
Above is just an example, the template engine generates dto's for all tables in a given project, and I would like to be able to use them in services without needing to maintain a big bunch of nearly identical classes.
Just hit the same problem. You can exclude fields by marking them as internal.
public class Order
{
public double OrderPrice;
internal double ProfitMargin;
internal string TheTruthAboutThisCustomer;
}
If you don't want to return a field or property, then don't have it in the object you return! It's as simple as that.

Resources