Mapping URL "names" to Controllers in JSPs - spring

I'm wondering if there is a way in Spring MVC to map "url names" to URLS. For instance:
list_users -> /admin/users/list
edit_user?id=123 -> /admin/users/edit/123 (or /users/edit?id=123)
list_programs -> /admin/programs/list
I come from a PHP background(specifically Symfony), where each URL/action has a "route name", with which you can create URLs in your view templates. In Symfony, you would do something like this in your template:
{{ path('user_edit', { 'id' : 123} }}
//output = /admin/users/edit/123
URLs do not necessarily need to be RESTful, but I'm just wondering if something like this could be accomplished with Spring MVC.
Possible Solution that I've thought about:
Keeping urls listed in a properties/messages file, like:
url.users.edit=/admin/users/edit/{id}
url.users.list=/admin/users/list
and then using <spring:message code="url.users.list" /> or something like this to generate the URLs. Is this already a generally accepted solution? Is this perhaps bad practice?
The reason I'm asking, is it seems like bad practice to have full URLs spread out throughout JSPs. What happens if 25 URLs are under an "/admin" sub-directory, and I want to move them to a different sub-directory, say "/backend".
Forgive me if there is a duplicate post somewhere on this, or if there is a simple solution that I'm overlooking, but it is a hard topic find a specific answer for.
Thanks!

In case anyone runs into this post, I have found a solution for mapping names to URLs for Spring MVC:
https://github.com/resthub/springmvc-router
This solution gets the job done quite nicely, and I especially like the fact that all of your URLs / routes are able to be kept in a central location. This implementation renders the #RequestMapping annotation useless.
Please keep the following in mind:
Make sure your dispatcher servlet uses * as the URL parameter. Took me awhile to figure out that / alone will not work, and will cause URLs to be generated incorrectly.
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

Related

Interesting Laravel routing url problems

I've got (what is to me) an interesting url question.
This is my situation. I have what will be a user populated database, so I cannot be sure how many subareas I will have.
I will always have an area, one or more subareas, and a location that ends my url.
example: /area/subarea1/subarea2/location
This is slightly simplified from what I need. I need to be able to service the following urls as well;
/area/subarea1/location
/area/subarea1/subarea2/subarea3/location)
My routes look something like this:
Route::get('area/{subarea1}', 'SubareaController#show');
Route::get('area/{subarea1}/{location}', 'LocationController#show');
Route::get('area/{subarea1}/{subarea2}', 'SubareaController#show2');
Route::get('area/{subarea1}/{subarea2}/{location}', 'LocationController#show2');
So the problem here is that my routes are overriding each other, because they are essentially the same.
My question is this. Is there any way to differentiate these routes when they have the same url structure? And if not, is there a better way to handle multiple subareas between an area, and a location?
EDIT
Ok I've been tried naming my routes, but I can't seem to be able to use the named routes correctly with all my parameters in the view. I may look into the area/{subarea1}/subarea1/{subarea2}/subarea2 solution, even though I would rather not have the longer URL.
This happens because Laravel has no way to distinguish each route from the other. For example, it would route these 2 url's to the same action:
example.com/area/my-subarea-1/my-location
example.com/area/my-subarea-1/my-subarea-2
So you need different paths. Try this:
Route::get('area/subarea1/{subarea1}', 'SubareaController#show');
Route::get('area/subarea1/{subarea1}/location/{location}', 'LocationController#show');
Route::get('area/subarea1/{subarea1}/subarea2/{subarea2}', 'SubareaController#show2');
Route::get('area/subarea1/{subarea1}/subarea2/{subarea2}/location/{location}', 'LocationController#show2');

Spring MVC Redirect for Many URLs

I have a web application with over 300 old urls to new URL's. As there are no consistenty patterns, I believe I can't use the URL Rewrite Filter. Some of these are 301's and others are 302's.
At this point, the only thing I think is basically have a controller with all these urls(there are over 300 URL's) and do a redirect reading from a properties files. I am not real comfortable with this and would appreciate if there was a better approach. Thanks.
May it would be possible to have some patterns and some explicit mapping (properties file) for the urls that do not match the patterns.
So if there is an request, first check the explicit mappings. If there is no explicit mapping, then use the "default" pattern way.
On the otherhand you are right: If there is no way a computer can not compute the mapping by some rules, then there is no way. (If something looks complicated than may it is complicated.)

What is the canonical way to handle errors during Ajax-requests?

For normal requests we can simple register an <error-page> in web.xml. However, this does not apply to Ajax-requests. By default errors during an Ajax-request will result in a little pop-window in the browser that shows the exception.
The main example I am struggling with is handling a ViewExpiredException in a uniform way. For standard requests, I redirect to a page that explains that the user is not logged in and provides a link to the login-page. I would like to do the same for Ajax-requests. There seem to be several ways:
I could write a javascript function that handles the error on the client-side and redirects to the error-page. I would then have to add this function every <f:ajax>-tag on all pages using the onerror-attribute. Is there a way to tell JSF that I want to have this javascript-function as the default error-handler for all <f:ajax>-tags?
I could use a custom exception-handler, as described in this blog. This seems to do what I want, but I wonder if it is overkill. Is there no simpler solution?
So my question is, how is this supposed to be solved? Which of the approaches I listed should be used? Is there another approach that I do not know of?
You can use jsf.ajax.addOnError() to set the default error handler. E.g.
jsf.ajax.addOnError(function(data) {
alert(data.responseText);
});
See also chapter 13.3.6.2 of the JSF2 spec. You can find all properties of data object in table 14-4 of the JSF2 spec.

Spring View Resolvers - Overhead of using Resource Bundle View Resolver vs JSP pages

In my application, I have both html and JSP files.
I need them both to pass through the controller.
But it is not possible to use multiple internalViewResolvers in an application . Chaining is not possible in the case of internalViewResolvers since even if specify the "Order" values, this will be ignored and this resolver will always come up last.
There are two options:
1)To use a ResourceBundleViewResolver and have a properties file explicitly mapping each of the request. This involves the overhead of reading from properties file.
2)Rename the html files as ".jsp" (i.e) though they are simple HTML pages rename it as .jsp to fix this. - This will involve the overhead of "JSP" to servlet conversion . Though pages does not have dynamic content, marking them as "JSP" seems an overhead for me
Please advise which is going to be a better solution.
Actually, you don't need to run both through the controller if the HTML files are static. If that is the case, you can use the mvs:resources tag to optimize retrievel. See my post on this topic. In your case, you would just add *.html to the resources list.
I wouldn't worry about the overhead. Neither of these options would take a lot of cpu or memory.
I would go with the second option as then you won't have to keep the resourcebundle updated when adding new html files.

SEO URL Structure

Based on the following example URL structure:
mysite.com/mypage.aspx?a=red&b=green&c=blue
Pages in the application use ASP.net user controls and some of these controls build a query string. To prevent duplicate keys being created e.g. &pid=12&pid=10, I am researching methods of rewriting the URL:
a)
mysite.com/mypage.aspx/red/green/blue
b)
mysite.com/mypage.aspx?controlname=a,red|b,green|c,blue
Pages using this structure would be publishing content that I would like to get indexed and ranked - articles and products (8,000 products to start, with thousands more being added later)
My gut instinct tells me to go with the first method, but would it would be overkill to add all that infrastructure if the second method will accomplish my goal of getting pages indexed AND ranked.
So my question, looking at the pro's and con's, Google Ranking, time to implement etc. which method should I use?
Thanks!
From an SEO perspective you want to try and avoid the querystring, so getting it into the URL and a short form URL is going to get you a better "bang for the buck" on the implementation side of things.
Therefore, I'd recommend the first.
Why don't use MVC pattern, this way all your link will be SEO ready. Check here, you will find what is MVC and also some implementation in .net!
You can easily make SEO-friendly URLs with the help of Helicon Ape (the software which allows having basic Apache functionality on your IIS server). You'll need mod_rewrite I guess.
If you get interested, I can help you with the rules.
Can you explain in more detail your current architecture and what the parameters all mean? There's nothing really wrong with query strings if it's truly dynamic content. Rewriting ?a=red&b=green&c=blue to /red/green/blue is kinda pointless and it's unclear from the URL what might be on the page.
The key is to simplify as much as possible. Split the site into categories and give each "entity" one URL.
For example, if you are selling products, use one URL per product, with keywords in the URL - e.g. mysite.com/products/red-widget or mysite.com/products/12-red-widget if you need the product ID.

Resources