« Back to Friendly URLs

FriendlyURLMapper

Standard portlet URLs are anything but succinct.

http://www.liferay.com/web/michael.young/blog?p_p_id=33&p_p_lifecycle=0&p_p_state=normal&p_p_mode=view&p_p_col_id=column-2&p_p_col_count=1&_33_struts_action=%2Fblogs%2Fview_entry&_33_entryId=5215369

Much of this information is unnecessary, and by including only the critical pieces in the path a radical transformation occurs.

http://www.liferay.com/web/michael.young/blog/-/blogs/5215369

This URL consists of two pieces separated by a /-/. The first half identifies the page as usual. The second half first identifies the portlet it refers to with a fragment ("blogs" in this case) known as the friendly URL mapping. Everything after the mapping can be used by the portlet however it chooses. The blogs portlet simply appends the post id.

This simple change, known as friendly URL mapping, has huge benefits to usability, by allowing users to quickly scan the URL and know where they are on a site. It also reduces tampering by hiding the implementation details and actual parameter names.

Unfortunately, before Liferay 6, adding friendly URL mapping to a portlet required subclassing BaseFriendlyURLMapper and writing complicated string manipulation code. Not so with Liferay 6.0.3, thanks to an ingenious system borrowed from Ruby on Rails called "URL Routing".

Friendly URL Routes #

A route is a pattern for a URL. It can include named fragments that will automatically be parsed from the URL into the parameter map, as well static content. In Liferay, a friendly URL route looks like this:

/{instanceId}/view/{folderId:\d+}/{name}

Each section of the pattern surrounded by brackets is a fragment. Each fragment contains a name and an optional regular expression to specify the format of the fragment, separated from the name by a colon. When a URL is parsed, each fragment will be extracted from the URL into an entry in the parameter map with the same name. For instance, the URL:

/5b21f/view/25/test

Would be parsed into the parameter map:

instanceId=5b21f&folderId=25&name=test

The real power of this system is that it also works in reverse. Every URL that can be parsed by a route can also be generated from the resulting parameter map.

To understand how this system works in practice we will be taking a detailed look into the friendly URL routing for the document library display portlet.

liferay-portlet.xml #

Here is an excerpt of /portal-web/docroot/WEB-INF/liferay-portlet.xml/

<portlet>
	<portlet-name>110</portlet-name>
	<struts-path>document_library_display</struts-path>
	<friendly-url-mapper-class>com.liferay.portal.kernel.portlet.DefaultFriendlyURLMapper</friendly-url-mapper-class>
	<friendly-url-mapping>document_library_display</friendly-url-mapping>
	<friendly-url-routes>com/liferay/portlet/documentlibrary/document-library-display-friendly-url-routes.xml</friendly-url-routes>
	<instanceable>true</instanceable>
</portlet>

The three entries to notice are "friendly-url-mapper-class", "friendly-url-mapping", and "friendly-url-routes".

DefaultFriendlyURLMapper #

The largest change in how friendly URL mapping works in Liferay 6.0.3 is this class. In 99% of portlets, you will simply use this class and an accompanying routes xml file, and never write a single line of Java.

Note: In previous versions of Liferay, a unique friendly URL mapper class was required for each portlet so that the URL mapping could be specified. In Liferay 6, several new methods have been added to the FriendlyURLMapper interface to allow this mapping to be set dynamically at runtime, eliminating this requirement.

document-library-display-friendly-url-routes.xml #

The full content of this file is shown below.

<?xml version="1.0"?>
<!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 6.0.0//EN" "http://www.liferay.com/dtd/liferay-friendly-url-routes_6_0_0.dtd">

<routes>
	<route>
		<pattern>/{instanceId}/</pattern>
		<implicit-parameter name="folderId">0</implicit-parameter>
		<implicit-parameter name="struts_action">/document_library_display/view</implicit-parameter>
	</route>
	<route>
		<pattern>/{instanceId}/view/{folderId:\d+}</pattern>
		<implicit-parameter name="struts_action">/document_library_display/view</implicit-parameter>
	</route>
	<route>
		<pattern>/{instanceId}/view/{folderId:\d+}/{name}</pattern>
		<implicit-parameter name="struts_action">/document_library_display/view_file_entry</implicit-parameter>
	</route>
</routes>

This single file, which only takes about 10 minutes to write, is all that's required to add industrial strength friendly URL mapping to the document library display portlet.

The format of this file is fairly self-explanatory. All the routes for a portlet are listed in the order they should be matched against a URL, which is the same order Liferay will attempt to use them when constructing a new friendly URL from a parameter map.

The string inside

<pattern>...</pattern>
is the URL pattern described above.
<implicit-parameter>
's serve two roles. When a URL is parsed, the implicit parameters for the matching route will be copied onto the parameter map. When a URL is built, the implicit parameters for a route must match the portlet URL parameters before that route will be used.

In the example above, if a portlet URL is created with the struts_action parameter set to "/document_library_display/view", the second route will be used. If struts_action is set to "/document_library_display/view_file_entry", the third route will be used.

If you are familiar with the usual contents of portlet URLs in Liferay, you will know that they usually contain at least the following parameters:

  • p_p_id
  • p_p_col_id
  • p_p_col_pos
  • p_p_col_count
  • p_p_lifecycle
  • p_p_state
  • p_p_mode

DefaultFriendlyURLMapper automatically hides all of these, and only displays them if they are set to a value other than the default. For instance, p_p_mode will be hidden if it is set to "normal", but will be shown if set to "maximized". This system makes your URLs much cleaner without breaking functionality.

Generated Parameters #

Up to this point, parameters from the portlet URL have only been directly mapped to fragments of the friendly URL path. Using generated parameters, much more complex mappings are possible. Examine the route definition below:

<route>
	<pattern>/{jspPageName}</pattern>
	<generated-parameter name="jspPage">/{jspPageName}.jsp</generated-parameter>
</route>

In this example, a portlet URL is created with the jspPage parameter set to "/view_profile.jsp". When the friendly URL is generated, the jspPage parameter is automatically parsed using the pattern specified in the generated-parameter option, and the jspPageName "virtual parameter" is set for use in the friendly URL pattern. The resulting friendly URL will be "/view_profile".

When this friendly URL is recognized, the opposite process takes place. First, jspPageName is parsed from the URL. The router then constructs the jspPage parameter using its pattern string and the jspPageName. When the parameters are passed to the portlet, only jspPage is set, making the mapping process entirely transparent.

Advanced Features #

Routes support two advanced features that make them even more flexible. The ignored-parameter option forces a parameter to never be shown in the query string. The overridden-parameter options always sets a parameter to the given value when a URL is parsed, but does not set any requirements on the contents of the portlet URL parameters when a URL is generated.

The example below uses these two options together to ensure that p_p_lifecycle is never placed in the query string, and that it will always be set to 1 (action phase) when the URL is parsed.

<route>
	<pattern>/rss</pattern>
	<ignored-parameter name="p_p_lifecycle" />
	<overridden-parameter name="p_p_lifecycle">1</overridden-parameter>
</route>

The difference between this setup and using a single implicit-parameter is subtle. The route above will be used to build a URL even if p_p_lifecycle is set to 0, whereas an implicit-parameter would require it to be 1.

When should you use ignored parameters or overridden parameters instead of implicit parameters? Generally, ignored and overridden parameters should only be used to support legacy applications. Best practice dictates that you always set the portlet URL parameters exactly as you want them to be received later, without depending on the friendly URL mapper to override them. For new portlets, you should simply remove irrelevant parameters from your portlet URLs, and set important parameters to the proper values.

Instanceable Portlets #

Before Liferay 6, it was very difficult to add friendly URL mapping to an instanceable portlet (a portlet that can be added multiple times to the same page). With friendly URL routes, it is now trivial, in fact you've already seen how to do it earlier in this article.

DefaultFriendlyURLMapper automatically populates two special parameters for instanceable portlets: p_p_id and instanceId. As you can see in the routes.xml file for document library display above, simply insert one of these two parameters as a fragment in each route, and the rest is handled for you automatically.

Changes in FriendlyURL in 5.1.1 #

This information is largely irrelevant when using the new friendly URL routes system in Liferay 6, but is kept here for legacy purposes.

It is important to note that changes in Liferay 5.1.1 added a friendly URL delimiter to the URL in order to avoid clashes with Layout friendly URLs.

Previously, if someone made a page with path:

/web/guest/community/forums/message_boards

Liferay could not distinguish between it and the Portlet Friendly URL

/message_boards/category/243728

The solution was to have a delimiter, and after considering many options, /-/ was the winner.

Now there is no collision:

/web/guest/community/forums/message_boards/-/message_boards/category/243728

0 Attachments
93176 Views
Average (5 Votes)
The average rating is 4.6 stars out of 5.
Comments
Threaded Replies Author Date
Would it be possible to have more information... François Cassin November 28, 2008 2:46 AM
The problem can be that you build a... Luca Preziati June 9, 2009 5:06 AM
Hi does Liferay 5.2 support portlets on the... Denis O'Sullivan October 23, 2009 3:44 PM
Hi all, I got my answer "If you are trying to... Denis O'Sullivan October 29, 2009 5:50 AM
Then please guide me the way how to create... Naga Surya Dhanunjaya Rao Sriapthy January 21, 2010 8:25 AM
Well, this has nothing to do with... Alberto Gallardo November 19, 2010 8:15 AM
Alberto,how does we make a URL like... Raja Nagendra Kumar November 23, 2010 9:55 PM
Basically how to apply SEO friendly URL's to... Raja Nagendra Kumar December 4, 2010 8:44 PM
hi this is yogesh i written code as like this... Yogesh Kumar October 7, 2013 8:13 PM
Is it possible for a friendly url mapper to... Flávio Stutz December 17, 2010 1:46 PM
I am facing with big problem with change URL... phuc nguyen March 20, 2014 5:30 AM
any guilde for JSF portlets? Andrew Koltsov April 8, 2010 3:48 AM
Does it not work for JSF ones? Alex Wallace April 12, 2010 2:48 PM
Hi, I have created a custom portlet using... Muhammed Shakir July 28, 2010 1:26 AM
Please note that I am doing all this in custom... Muhammed Shakir July 28, 2010 3:06 AM
Hi Shakir, I am facing the same problem and by... Rajendra Mhetre March 7, 2011 7:47 AM
Typo: The PROLOG for the file ... Alberto Gallardo October 19, 2010 2:05 AM
I tried to edit the wiki, but the failure is... Alberto Gallardo October 19, 2010 2:35 AM
Is ant once successful in making this work in... Raja Nagendra Kumar November 9, 2010 4:23 AM
Hi, I have create portlet using Spring(3.0)... Babu Dobwal November 10, 2010 3:35 AM
I have followed the same document for... Babu Dobwal November 10, 2010 3:49 AM
anyone how to write a route for: ... lpu123 xyz August 28, 2011 8:07 PM
How to get FriendlyURLMapper in page... M. Ahamed Maqbool October 18, 2012 12:30 AM
Hi, I really need your help in creating... Nabil Bahtat January 5, 2015 2:04 PM
Hi all, I tried to implement friendly url for... Nabil Bahtat January 11, 2015 2:06 AM

Would it be possible to have more information on the buildPath method please ?

I am unable to get custom parameters from the portletURL, where does it come from ?
Posted on 11/28/08 2:46 AM.
The problem can be that you build a friendlyUrlMapper for non instanziable portlet while yours are instanziable.
Do you set the correct portletId: for example

String portletId = parts[2];
if (Validator.equals(portletId, _PORTLET_ID))
portletId = _PORTLET_DEFAULT_INSTANCE;


addParam(params, "p_p_id", portletId);

and this part for passing correct parameter:

String namespace = StringPool.UNDERLINE + portletId + StringPool.UNDERLINE;


if(parts.length == 4 || parts.length == 5){
if(parts[3].compareTo("-")!=0)
params.put(namespace + "tagsSelected", new String[] { parts[3]});
}

if(parts.length == 5 )
params.put(namespace + "keywords",new String[]{parts[4]});



params.put(namespace + "struts_action",new String[] { VIEW_STRUTS_ACTION});
Posted on 6/9/09 5:06 AM in reply to François Cassin.
Hi does Liferay 5.2 support portlets on the same page? I have 2 portlets on the same page and both need to translate the SEO friendly url.

If the 2 portlets are on separate pages, all works ok and my FriendlyUrlMapper implemenation works fine for each
http://localhost:8080/web/guest/mypage/-/portletA/friendlyname
http://localhost:8080/web/guest/mypage/-/portletB/friendlyname

But if both on same page I can't get it to work. I'm not sure how to define the url with both on the same page but assumed the following: http://localhost:8080/web/guest/mypage/-/portletA/portletB/friendlyname

Since I assumed portletA and portletB would each be triggered in turn. ...This url may be wrong and may be part of the problem.

When both portlets are on the same page then it appears only 1 has their FriendlyUrlMapper populateParams() method called. And that is the one which appears first after the Liferay dash
i.e. in the following case only portletA populateParams() method is called
http://localhost:8080/web/guest/mypage/-/portletA/portletB/friendlyname

...and in the following case only portletB populateParams() method is called
http://localhost:8080/web/guest/mypage/-/portletB/portletA/friendlyname

any help/workarounds is greatly appreciated.
Posted on 10/23/09 3:44 PM.
Hi all, I got my answer "If you are trying to hit two portlets on the same page at once with one URL, the FriendlyUrlMapper is not the way to do. FriendlyUrlMapper hits one portlet at a time."
Posted on 10/29/09 5:50 AM.
Then please guide me the way how to create friendly URL to the two different porltets in the same page.
Thanks in advance.
Posted on 1/21/10 8:25 AM in reply to Denis O&#039;Sullivan.
any guilde for JSF portlets?
Posted on 4/8/10 3:48 AM.
Does it not work for JSF ones?
Posted on 4/12/10 2:48 PM in reply to Andrew Koltsov.
Hi,
I have created a custom portlet using portlet plug-in, also mapped the friendly-url-routes file in liferay-portlet.xml file. There is no error or exception thrown while deploying or running however it does not give me the value of the parameter in my jsp. The routes.xml looks like this:
<route>
<pattern>/{instanceId}/{programId:\d+}</pattern>
<implicit-para­meter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="struts_action">/material/material_view
</implicit-parameter>
</route>
Now­ when I type the following url in my browser: http://localhost:8080/web/guest/course-material/-/coursematerial/3223
I am expecting
long prId = ParamUtil.getLong(request, "programId"); to give me the programId as 3223. But it does not.

Any help or pointer to where I am going wrong will be of great help. Stuck on this since many days.
Posted on 7/28/10 1:26 AM.
Please note that I am doing all this in custom portet in plugin environment
Posted on 7/28/10 3:06 AM in reply to Muhammed Shakir AK Misarwala.
Typo:

The PROLOG for the file
document-library-display-friendly-url-routes.xml
contains a typo:
<!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 6.0.0//EN" "[http://www.liferay.com/dtd/liferay-friendly-url-routes_6_0_0.dtd">]

The square braquets should be removed.
Posted on 10/19/10 2:05 AM.
I tried to edit the wiki, but the failure is not in the source code!

Could it be a bug in the wiki component?

Regards
Posted on 10/19/10 2:35 AM in reply to Alberto Gallardo.
Is ant once successful in making this work in 6.x of Liferay..

We tried to this but nothing seem to work..
Any ways to debug..
Posted on 11/9/10 4:23 AM.
Hi,
I have create portlet using Spring(3.0) Annotations and i have deployed it in liferay server(6.0.5), It is working fine.

Now i need to do configuration for friendly url(for my portlet).
Is I need to follow same document for configuration the same?
Please reply.
Posted on 11/10/10 3:35 AM.
I have followed the same document for configuration friendly url for my portlet(my portlet build using Spring 3.0 Annotations).
But it is not showing friendly url.

Please reply if any body have any idea ?....
Posted on 11/10/10 3:49 AM in reply to Babu Dobwal.
Well, this has nothing to do with FriendlyUrlMapper: you need to use "public render parameters," and they are independent of the "FriendlyUrlMapper."

I have tested public render parameters and FriendlyUrlMapper together in LR 6.0.5 with non-instanceable portlets, and it works.
Posted on 11/19/10 8:15 AM in reply to Denis O&#039;Sullivan.
Alberto,how does we make a URL like /home/-/sales/2010 land in home page with all the portlets having access to /sales/2010.
Posted on 11/23/10 9:55 PM in reply to Alberto Gallardo.
Basically how to apply SEO friendly URL's to Pages instead of portlets..

Also, once page is able to support friendly URL, can all the portlets on this page know what is the page URL including Query String.

For SEO, we think page URL being friendly would be more important than portlet URL's being more friendly.
Posted on 12/4/10 8:44 PM in reply to Raja Nagendra Kumar.
Is it possible for a friendly url mapper to send the parameters to portlets as Public Render Parameters?

Multiple portlets on the same page that supports the same public param could read the same parameter set in FriendlyURL mechanism. Both would have a route.xml like <pattern>/${myPublicParam}</pattern>. When I hit a page with /-/valueOfPublicParam, both could get it by renderRequest.getParameter("myPublicParam").

Is it possible?

See my request at http://issues.liferay.com/browse/LPS-4023
Posted on 12/17/10 1:46 PM in reply to Alberto Gallardo.
Hi Shakir,
I am facing the same problem and by any way its not working.
Can you please share the progress on this.

Thanks
Posted on 3/7/11 7:47 AM in reply to Muhammed Shakir AK Misarwala.
anyone how to write a route for:

http://localhost:8080/web/guest/home?
p_p_id=slogancontest_WAR_slogancontes­tportlet&
p_p_lifecycle=0&p_p_state=normal&p_p_mode=view&
p_p_col_id=column-2&p_­p_col_count=1&
_slogancontest_WAR_slogancontestportlet_jspPage=%2Fhtml%2Fsearch.­jsp&
_slogancontest_WAR_slogancontestportlet_redirect=%2Fweb%2Fguest%2Fhome&
_sl­ogancontest_WAR_slogancontestportlet_groupId=10181&
_slogancontest_WAR_slogancon­testportlet_keywords=myslogan123

I have tried with the following, but it does not work (due to "redirect and "groupId" ?!):
<route>
<pattern>/BLA_search/{groupId:.\d+}/{keywords:.*}</pattern>
<implicit-param­eter name="redirect">/web/guest/home</implicit-parameter>
<implicit-parameter name="jspPage">/html/search.jsp</implicit-parameter>
</route>
Posted on 8/28/11 8:07 PM.
How to get FriendlyURLMapper in page tittle(portal-normal.vm)?
Posted on 10/18/12 12:30 AM.
hi this is yogesh i written code as like this for friendly url but this is not working.could you plz help me.
<route>
<pattern>/{jspPageName}</pattern>
<generated-parameter name="variantName">/html/variantdisplayfriendlyurl/{jspPageName}.jsp</generated-­parameter>
<ignored-parameter name="p_p_lifecycle" />
<ignored-parameter name="p_p_state" />
<ignored-parameter name="p_p_mode" />
</route>


<!-- mapping code starts here -->
<friendly-url-mapper-class>com.liferay.portal.kernel.portlet.DefaultFri­endlyURLMapper</friendly-url-mapper-class>
<friendly-url-mapping>submit-name</friendly-url-mapping>
<friendly-url-routes>com/variantDisplayFriendlyURL/friendlyurl-routes.xml<­/friendly-url-routes>
<!-- mapping code ends here -->
Posted on 10/7/13 8:13 PM in reply to Raja Nagendra Kumar.
I am facing with big problem with change URL and already apply FriendlyUrlMapper & public render parameters but it does not work, At now the my problem as below:
- I already have FriendlyUrl as expectation but "public render parameters" return null value therefore it not show data.
So please help me for this by explain in more details or give me the sample/demo for this,

Thanks in advance,
Posted on 3/20/14 5:30 AM in reply to Alberto Gallardo.
Hi,
I really need your help in creating friendly url for my portlet, because I’m reaaly new to liferay development.
I tried to implement friendly url for my portlet “product” but unfortunatly it didn’t work.

Thanks alot.
Nabil

Below the origine url I want to transform as friendly URL

http://localhost:8080/web/guest/product? p_p_id=225_INSTANCE_08MX& p_p_lifecycle=0 &p_p_state=normal& p_p_mode=view& p_p_col_id=column-1&
p_p_col_count=1 &_225_INSTANCE_08MX_struts_action=%2Fproduct%2Fview_product
&_225_INSTANCE_08MX_redirect=http%3A%2F%2Flocalhost%3A8080%2Fweb%2Fguest%2Fprodu­ct%3Fp_p_id%3D25_INSTANCE_08MX%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mo­de%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_count%3D1%26_225_INSTANCE_08MX_%252F­%3D
&_225_INSTANCE_08MX_productId=25414

Thanks a lot.

Nabil
Posted on 1/5/15 2:04 PM.
Hi all,
I tried to implement friendly url for my portlet embeded in web content portlet but it did'nt work. In fact, the friendly url is created, but when I click on it in an Href link,
it does not fire the struts_action which is parametred in the route.
I really don't know what is wrong, below the detail of my implementation.
Please, I need your help, I spent several days to try to fix without success.

My source url
http://localhost:8080/web/guest/product? p_p_id=225_INSTANCE_08MX& p_p_lifecycle=0 &p_p_state=normal& p_p_mode=view& p_p_col_id=column-1&
p_p_col_count=1 &_225_INSTANCE_08MX_struts_action=%2Fproduct%2Fview_product
&_225_INSTANCE_08MX_redirect=http%3A%2F%2Flocalhost%3A8080%2Fweb%2Fguest%2Fprodu­­ct%3Fp_p_id%3D25_INSTANCE_08MX%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_m­o­de%3Dview%26p_p_col_id%3Dcolumn-1%26p_p_col_count%3D1%26_225_INSTANCE_08MX_%25­2F­%3D
&_225_INSTANCE_08MX_productId=25414

My route file
<?xml version="1.0"?>
<!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 7.0.0//EN" "http://www.liferay.com/dtd/liferay-friendly-url-routes_7_0_0.dtd">

<routes>
<route>
<pattern></pattern>
<ignored-parameter name="redirect" />
<implicit-parameter name="p_p_id">225_INSTANCE_08MX</implicit-parameter>
<implicit-parameter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="p_p_state">normal</implicit-parameter>
<implicit-parameter name="p_p_mode">view</implicit-parameter>
<implicit-parameter name="p_p_col_id">column-1</implicit-parameter>
<implicit-parameter name="p_p_col_count">1</implicit-parameter>
<implicit-parameter name="struts_action">/product/view</implicit-parameter>
</route>
<route>
<pattern>/{p_p_id}</pattern>
<ignored-parameter name="redirect" />
<implicit-parameter name="p_p_id">225_INSTANCE_08MX</implicit-parameter>
<implicit-parameter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="p_p_state">normal</implicit-parameter>
<implicit-parameter name="p_p_mode">view</implicit-parameter>
<implicit-parameter name="p_p_col_id">column-1</implicit-parameter>
<implicit-parameter name="p_p_col_count">1</implicit-parameter>
<implicit-parameter name="struts_action">/product/view</implicit-parameter>
</route>
<route>
<pattern>/{p_p_id}/productId={productId}</pattern>
<ignored-parameter name="redirect" />
<implicit-parameter name="p_p_id">225_INSTANCE_08MX</implicit-parameter>
<implicit-parameter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="p_p_state">normal</implicit-parameter>
<implicit-parameter name="p_p_mode">view</implicit-parameter>
<implicit-parameter name="p_p_col_id">column-1</implicit-parameter>
<implicit-parameter name="p_p_col_count">1</implicit-parameter>
<implicit-parameter name="struts_action">/product/view_product</implicit-parameter>
</route>
<route>
<pattern>/{p_p_id}/view_product/productId={productId}</pattern>
<ignored-parameter name="redirect" />
<implicit-parameter name="p_p_id">225_INSTANCE_08MX</implicit-parameter>
<implicit-parameter name="p_p_lifecycle">0</implicit-parameter>
<implicit-parameter name="p_p_state">normal</implicit-parameter>
<implicit-parameter name="p_p_mode">view</implicit-parameter>
<implicit-parameter name="p_p_col_id">column-1</implicit-parameter>
<implicit-parameter name="p_p_col_count">1</implicit-parameter>
<implicit-parameter name="struts_action">/product/view_product</implicit-parameter>
</route>
</routes>
Posted on 1/11/15 2:06 AM.