Different urls mapping to the same xhtml file - jsf

With jsf 2.x I want to use urls like
../admin1.xhtml
../admin2.xhtml
../admin3.xhtml
that should all call the same xhtml file (generic.xhtml), but with a parameter like this:
../generic.xhtml?page=admin1
../generic.xhtml?page=admin2
../generic.xhtml?page=admin3
instead of creating a lot of useless identical xhtml files to serve the requests. How can i better achieve that with jsfs? Am i bound to write loads of xml or can i make a simple rule in faces-config.xml, or should i use some other tools?

Make use of PrettyFaces url prettyfier. First of all it'll allow you removing your file extensions, which is considered a best practice (you would be able to change your backend framework without altering the urls themselves).
Apart from that, there's the chance to integrate the parameter itself into the url:
<!-- Maps "/admin/#{page}" to the URL "/generic.xhtml?page=value" -->
<url-mapping id="admin-view">
<pattern value="/admin/#{page}" />
<view-id value="/generic.xhtml" />
</url-mapping>
So you'll be able to type:
/admin/admin1
And that will drive you to:
/generic.xhtml?page=admin1

Related

How to change index.html in every folder to / when we access it on browser

I've some unique problem, but I think this is not problem, I just want to optimize the url that my website have.
so I want to change all
index.html
on every folder as example
culture
folder, so normally if we want access
index.html
in culture folder we can just type
culture/index.html
right? but i want to access by just type
culture/
Is it possible to do that? If so, how we produce? I'm using jsf 2 as programming language.
Maybe I misunderstand your problem, but this can be done by configuring welcome files in the web.xml file:
Web Application developers can define an ordered list of partial URIs
called welcome files in the Web application deployment descriptor. The
purpose of this mechanism is to allow the deployer to specify an
ordered list of partial URIs for the container to use for appending to
URIs when there is a request for a URI that corresponds to a directory
entry in the WAR not mapped to a Web component. This feature can make
your site easier to use, because the user can type a URL without
giving a specific filename.
Note: Welcome files can be JSPs, static pages, or servlets.
Just:
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
I've tested this on WildFly 11 and it works, my project structure is:
+ WebContent
- index.xhtml
+ folder_a
- index.xhtml
+ folder_b
- index.html
+ folder_c
- other_name.xhtml
- some_name.html
When I enter:
http://localhost:8080/myproject/ I get a content from WebContent/index.xhtml
http://localhost:8080/myproject/folder_a I get a content from WebContent/folder_a/index.xhtml
http://localhost:8080/myproject/folder_b I get a content from WebContent/folder_b/index.html
Does the .xhtml file contain JSF content? is it parsed? I always
thought defining a jsf/facelets file as a welcome file did not work
and you needed http redirects via 'meta-inf'
.jsf' is that an extension I am using in myweb.xml` file:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
Please read answers for the below question to learn what it is:
JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?
What is the difference between creating JSF pages with .jsp or .xhtml or .jsf extension
JSF 2.0 does not have support for extensionless URL by default. This is a long waited feature for the community, but finally we got this with JSF 2.3 (released early 2017). If you care able to update your application to JSF 2.3, or maybe want some more information, please check it out here.
A brief example of how you can make the default JSF approach for extensionless URLs:
In the web.xml file, include each desired mapping using a tag inside the tag:
<url-pattern>/page1</url-pattern>
<url-pattern>/page2</url-pattern>
<url-pattern>/path/page1</url-pattern>
These patterns will redirect the user to the following paths respectively:
www.domain.com/page1 -> www.domain.com/page1.xhtml
www.domain.com/page2 -> www.domain.com/page2.xhtml
www.domain.com/path/page1 -> www.domain.com/path/page1.xhtml
Note that the above examples are not providing a way to redirect to the index.xhtml page, they are just a example of how the new JSF 2.3 mapping work.
However, if you can't update your project right now, I suggest you to follow #Kukeltje advice and take a look on the PrettyFaces library.
PrettyFaces is focused on provide a simple way to create URL mappings for older JSF versions. Heres a example of how it works:
In the pretty-config.xml file, include your desired mappings using a tag:
<url-mapping id="view-page">
<pattern value="/page" />
<view-id value="/page/index.xhtml" />
</url-mapping>
<url-mapping id="view-page-edit">
<pattern value="/page/#{id}" />
<view-id value="/page/edit.xhtml" />
</url-mapping>
These patterns would work like the following examples:
www.domain.com/page -> www.domain.com/page/index.xhtml
www.domain.com/page/2 -> www.domain.com/page/edit.xhtml?id=2
Both are good alternatives, PrettyFaces looks more powerful right now, since they are support this kind of solution for more time, but the JSF 2.3 should also do the trick.

Pretty faces: one mapping configuration for multi .xhtml page

I have one question. How could pretty faces do this:
<code>
<url-mapping id="home">
<pattern value="/viewer" />
<view-id value="/pages/*" />
</url-mapping>
</code>
Well, I wonder if pretty faces could hide paths of all .xhtml in folder using just one configuration as shown as above, instead of to config for each and every file.
This mapping doesn't make any sense. To which view should PrettyFaces forward if the client requests /viewer?
However, you can do something similar with Rewrite, which is the successor of PrettyFaces. With Rewrite you can do something like:
.addRule( Join.path("/viewer/{page}").to("/pages/{page}.xhtml") )
This will basically map your URLs like this:
/viewer/foo -> /pages/foo.xhtml
/viewer/bar -> /pages/bar.xhtml
/viewer/whatever -> /pages/whatever.xhtml
If you want to migrate your app to Rewrite, which is really simple, have a look at the PrettyFaces Migration Guide.

Rewriting URLs using pretty-config

I am facing problem with rewriting urls using pretty-config.xml and I want help. This is what I want.
I want to render the URL as:
http://www.example.com/{productId}
and the page actual URL is:
http://www.example.com/page/product.jsf
In short, I have one page but I want to render it each time as different url based on product id from the backing bean.
Sounds fairly simple. I would use this:
<url-mapping>
<pattern value="/#{productId}" />
<view-id value="/pages/product.jsf" />
</url-mapping>
Just make sure that you generate the correct links in your pages upon rendering.

using pretty faces with web filters

Using Tomcat 7 --- Primefaces 3.4.1 --- javax faces 2.1.17 --- prettyfaces-jsf2 3.3.3
I configured pretty faces on my project correctly but my web filters are not working with new urls which are written by pretty faces.
Here is an example pretty-config.xml
<url-mapping id="home">
<pattern value="/home"/>
<view-id value="/secure/homepage.xhtml"/>
</url-mapping>
<url-mapping id="register">
<pattern value="/register"/>
<view-id value="/public/register.xhtml"/>
</url-mapping>
<url-mapping id="welcome">
<pattern value="/"/>
<view-id value="/public/welcome.xhtml"/>
</url-mapping>
<url-mapping id="profile">
<pattern value="/profile/#{userId}"/>
<view-id value="/profile.xhtml"/>
</url-mapping>
login(welcome) and register pages are in "public" folder, and their web filter is defined with annotation : #WebFilter("/public/*")
for my home page in "secure" folder (exactly there will be more pages in the folder), i defined a web filter also and its annotation : #WebFilter("/secure/*)
pretty urls are working fine, but these filters are only working when i write the original urls.
1) How can i repair my webfilters ?
2) I also want to block user for entering original url. I know that pretty faces is hiding original urls fully but is there a way to do it ?
-- SOLVED -- thanks for BalusC
if you defined your filters with annotations, you can configure dispatcher settings like
#WebFilter(urlPatterns = "/public/*", dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD})
PrettyFaces uses like many URL-rewriting solutions RequestDispatcher#forward() to forward the request to the desired target resource.
Servlet filters, when mapped without any <dispatcher>, listens by default on "initial" requests only, not on forwarded, included, nor error'ed requests.
So, when you map another servlet filter in web.xml after the PrettyFaces one, then it would by default not be triggered, unless you explicitly set a <dispatcher> on FORWARD next to the default of REQUEST (you should keep this one for the case PrettyFaces actually doesn't need to perform a forward).
<filter-mapping>
...
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Or, for the case you're using #WebFilter on your filters, use the dispatcherTypes attribute:
#WebFilter(..., dispatcherTypes = { REQUEST, FORWARD })
Alternatively, if the filter in question doesn't change the request/response target in any way, e.g. setting the charset, compressing using Gzip, listening on exceptions, etc, then you can also just put it before the PrettyFaces one.

Add a global Jsp to include in Liferay tomcat-6

I have a Jsp that dynamically needs to get included in entire project as user opens any jsp. i.e. As a user opens a jsp my jsp should automatically gets included.
I have written this in web.xml in Tomcat
<jsp-property-group>
<url-pattern>/webapps/ROOT/html/*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<el-ignored>false</el-ignored>
<scripting-invalid>false</scripting-invalid>
<is-xml>false</is-xml>
<include-prelude>/WEB-INF/jsp/tracker.jsp</include-prelude>
<!-- <include-coda>/template/coda.jspf</include-coda> -->
</jsp-property-group>
I had kept my jsp in tomcat under WEB-INF/jsp/ and i want to include it into every porject as it contains a code that tracks log for user.
Or any other way to make this happen.
Thanks.
There is one more way to include your JSP for the whole portal and i.e. the dockbar.
You can create a hook and include your jsp in the /html/portlet/dockbar/view.jsp using either <jsp:include /> or <liferay-util:include /> or simple <%# include file="" /> (this would be static).
<jsp:include page="/jsp/yourJSPPageToBeIncluded.jsp" />
OR
<liferay-util:include page="/jsp/yourJSPPageToBeIncluded.jsp" />
OR
<%# include file="/jsp/yourJSPPageToBeIncluded.jsp" />
Note: the path may differ depending on where you will be putting the JSP.
Why I am choosing dockbar is because it is present on all the portal-pages of liferay. This won't work if you are opening a pop-up like configuration pop-up or look-and-feel pop-up or other custom dialog pop-ups since dockbar is not present in the pop-up. For using in pop-ups you would have to override portal_pop_up.vm in your custom-theme and write the code as suggested by #VikasV
$theme.include($themeServletContext, "/jsp/yourJSPPageToBeIncluded.jsp")
There are two ways for this.
Simple way is to include your JSP in the Theme. When your Theme is applied to your project, and when Theme is rendered, any pages in your project will render this included JSP.
Code sample below. This has to be placed in vm file(navigation.vm).
$theme.include($themeServletContext, "/jsp/yourJSPPageToBeIncluded.jsp")
Here, JSP folder is placed directly inside Theme war.
Other way (tedious one), is to include this JSP in each and every JSP page that you want this to be included.
Use <jsp:include> element for this.
Some references,
Ref1
Ref2

Resources