Dynamic URL structure with Spring 4 - spring

We have a Spring MVC webapp and our product URL structure needs to be SEO friendly. Such as www.mydomain.com/{productname}. Every time we add a product to inventory, we want to have URL to display those product details.
We could not figure our how to generate dynamic URLs with Spring Controller Resource path.
Can someone please help us.
Would appreciate your help.
Thanks
Raj

A Spring URL structure like www.mydomain.com/{productname} would seem to imply that 'productname' is always unique. If so, each product could have a property called 'name' or 'productname'; this property could be used to retrieve the relevant product in your controller method. This will only work if every 'productname' is unique.

What you are looking for is URI Template Patterns. In Spring MVC, #PathVariable annotation is used to bind an argument to the value of URI template variable.
#RequestMapping(path="/{productname}", method=RequestMethod.GET)
public String findProduct(#PathVariable String productname, Model model) {
List<Product> product = productService.findProductsByName(productname);
model.addAttribute("product", product);
return "displayProduct";
}
Note that the service call returns List<Product> instead of one Product, since ideally, product name is not unique to one item. If you want the URI to identify exactly one product, make sure that product name is unique to one product only.

Related

Laravel 5.8 - one route two different controller action

In laravel 5.8, I have have 2 type of url.
/news/{category} - > send to news controller index action, if have category bind
/news/{news} - > send to news controller details action, if have news bind
Another case abort with 404.
How can i solve this problem?
In Laravel and almost all frameworks and routing systems I'm aware of, the Route and Controller/Action relationship is 1:1. Each route can only have one controller or action to handle it.
If I understand your question correctly, you have a single route pattern of /news/{parameter}, and you want one of three things to happen:
{parameter} contains a valid Category slug. Retrieve the category and display the appropriate view.
{parameter} contains a valid Article (details) slug. Retrieve the article and display the appropriate view.
{parameter} does not contain a valid category or article slug, and thus is not found. Return a 404 error.
You'll still need only a single controller action, but you can separate the logic to make it easy to understand:
routes/web.php:
Route::get('/news/{param}', 'NewsController#index');
app/Http/Controllers/NewsController (with pseudo code):
class NewsController extends Controller
{
public function index(string $param)
{
if ($category = Category::whereSlug($param)->first()) {
// Return your category view.
}
if ($article = Article::whereSlug($param)->first()) {
// Return your article view.
}
\abort(404);
}
}
I would personally recommend against sharing a common URL structure for two different entity types like this. It opens the possibility for name conflicts (a Category and Article have the same slug) and can make the user experience confusing. (It might hurt search engine optimizations or results, also, but that's just speculation - I don't have anything to confirm or deny that.)

Spring RESTful Service URL to object

How can I convert a URL (http://127.0.0.1:8080/authors/1) to domain object?
I will let my clients submit URLs as foreign keys and I have to resolve them somehow.
For example I want to create a book with the author 1
POST /books
{"title":"Harry Potter", "author":"http://127.0.0.1:8080/authors/1"
I found a class named UriToEntityConverter that sounds right but of course 0 tutorials or examples.
I am serving my objects from a #RestController.
you could simply define your path using request mapping and store the variable using pathVariable annotation
#RequestMapping(value="/authors/{id}", method=RequestMehtod.POST)
public RequestEntity<String> doSomething(#PathVariable("id") long id) //id will contain your id

SEO friend urls for spring mvc application

I have an application with urls like site.com/article/1/title.htm
I have #RequestMapping /article/{id}/{title}.htm that server this request and gets the article.
What I am looking achieve is to have a url like site.com/title.htm but cant think of a way to do that using Spring MVC because I need id of the article. any ideas? Thanks in advance
When you create an article, you need to create the SEO-friendly URL also and persist it, along with the article. Now you need to have a repository method that allows you to retrieve articles by permalink, and a Spring MVC endpoint that calls that repository method.
Using the title may not be a good idea, as the title is usually not URL-friendly, and may eventually be non-unique. But it is a good idea to use the title as the input for the permalink.
Here's a sample permalink algorithm:
Take the title
replace all occurrences of one or more space or punctuation with a single dash
replace all non-ascii characters with their ascii neighbors
check whether that permalink already exists
if it does, add a counter
This is how the read path could look like:
#Autowired
private ArticleRepository ar;
#RequestMapping(value="/article/{id}/{ignored}") #ResponseBody
public Article getByIdAndIgnorePermalink(#PathVariable String id, #PathVariable String ignored){
return ar.getById(id);
}
#RequestMapping(value="/article/{title}.html") #ResponseBody
public Article getByPermalink(#PathVariable String permalink){
return ar.getByPermalink(permalink);
}
There is no way send hidden id obviously, so it has to be done through a permalink of the article or simply via title, to achieve site.com/title.html you need to get rid of all the fixed bits by adding this request mapping rule:
#RequestMapping(value = "/**/{articleTitle}.html"
but to get the article you can obviously use id as its not there in the URL and have to work with that articleTitle or generate a permalink as suggested by #Sean above.

mvc routing - Passing data to a display controller from the Route

I have a route like the following:
/Company/1234/Contact/3456
The general pattern for my routes is that strings are actions/areas and numerics are the records ids.
In the Contact controller (action{edit}) I want to pass in the id from the company and the contact.
Is there a way in the framework to get that information? Or do I need to parse all numeric values in the route in order to know which is what?
Any help would be great.
Based on an other question I asked MVC3 Routing - Routes that builds on each other
The solution would be to name my routes correctly, with each id having a unique name.
Company would be CompanyId, contact would be ContactId.
/Company/{CompnayId}/Contact/{ContactId}
Then in the controller method the signature could look like:
ActionView Edit(int CompanyId, int ContactId))
{
...
}

Generate a URL programmatically using the route information without the request context

I'd like to include a relative URL as parameter in one of my custom validation attributes. Something like:
[RemoteValidation(Url= Html.ActionLink("Index","Home"))]
public class Lalala...
How can I do it?
I know that usually I need the request context in order to generate an URL, but considering it is just a relative one, is there any way I can generate the relative url for an action and controller names?
Thanks.
Have you considered using the [Remote] attribute instead of writing custom attributes?
[Remote("Index", "Home")]
public string Username { get; set; }
And here's a nice article illustrating it in action.

Resources