Rewrite Examples
Frequently the best way to learn how to use a technology is to see examples of how it has been used in similar situations. Here are some examples of how to use Rewrite’s core Servlet functionality in common scenarios. For the purpose of brevity, extraneous code has been omitted.
Before you get started with Rewrite, you may wish to read the installation guide or configuration manual, including instructions for using Rewrite annotations, or migrating from PrettyFaces 3.x.
The following examples will show a few ways to get started using Rewrite; however, in reality, rewrite is a flexible tool, and be used for any purpose, not limited to those listed below.
Join an inbound URL to a server-side resource:
Typically the most basic task – masking the URL of an internal resource with another URL of your choice.Exhibit 0
public class ExampleConfigurationProvider extends HttpConfigurationProvider { @Override public Configuration getConfiguration(final ServletContext context) { return ConfigurationBuilder.begin() // A basic join .addRule(Join.path("/").to("/pages/home.xhtml")) // Using parameters to return physical resources .addRule(Join.path("/{param}").to("/pages/{param}.html")) // Using parameterization (the value of 'p' is converted to a request parameter) .addRule(Join.path("/project/{p}").to("/pages/project/create.xhtml")) // Redirect requests to the server-side resource to the correct location .addRule(Join.path("/signup").to("/pages/signup.xhtml").withInboundCorrection()) // Perform additional operations on rule execution .addRule(Join.path("/404").to("/pages/404.xhtml").perform(Response.setCode(404))); } }
Activate a Configuration Based on Dev/Test/Production Environment Detection
A frequent concern, is the ability to run configuration in a specific deployment environment. In this case, it is sometimes necessary to distinguish between test and production servers. Our recommendation for this is to use one of a few techniques. (This can be done in whichever manner fits your needs, but here are a few examples.)Exhibit 1
public class EnvironmentDetectionConfigurationProvider extends HttpConfigurationProvider { @Override public Configuration getConfiguration(ServletContext context) { return ConfigurationBuilder .begin() // Using File Markers .addRule().when(Filesystem.fileExists(new File("/root/env/server/production.marker"))) .perform(Subset.evaluate(ConfigurationBuilder.begin() // Your specific rules here ) // Using URL domain detection .addRule().when(Domain.matches("{server}.domain.com")) .perform(Subset.evaluate(ConfigurationBuilder.begin() .addRule(Join.path("/production-monitor").to("/views/monitor.jsp?servername={server}")) // Your specific rules here (example using rule parameters) .where("server").matches("prod1|prod2|prod3")) ) // Using a custom condition (example shows using a "-P" jvm system property) .addRule() .when(new HttpCondition() { @Override public boolean evaluateHttp(HttpServletRewrite event, EvaluationContext context) { return Boolean.getBoolean("production.mode.enabled"); // Using a system property. } }) .perform(Subset.evaluate(ConfigurationBuilder.begin() .addRule().when(JAASRoles.required("admin")) .perform(Lifecycle.proceed()).otherwise(Forward.to("/login"))) // Your specific rules here ); } }
Create a dynamic logout URL without the need for a Servlet or page
Why write a full logout page, just to do what can be done with a single method call?Exhibit 2
public class ExampleConfigurationProvider extends HttpConfigurationProvider { @Override public Configuration getConfiguration(final ServletContext context) { return ConfigurationBuilder.begin() // Create a dynamic logout URL via EL .addRule() .when(Direction.isInbound().and(Path.matches("/logout"))) .perform(Invoke.binding(El.retrievalMethod("#{session.invalidate}")) .and(Redirect.temporary(context.getContextPath() + "/"))) // Create a dynamic logout URL via direct service call .addRule() .when(Direction.isInbound().and(Path.matches("/logout"))) .perform(new HttpOperation() { @Override public void performHttp(HttpServletRewrite event, EvaluationContext context) { event.getRequest().getSession().invalidate(); } }) .and(Redirect.temporary(context.getContextPath() + "/")); } }
Show different resources when a user is logged in/logged out
Showing different content to users in different roles is a paramount task in any web application.Exhibit 3
public class AuthenticationStatusInterceptor extends HttpConfigurationProvider { @Inject @LoggedIn private Profile profile; @Override public Configuration getConfiguration(final ServletContext context) { Condition loggedIn = new Condition() { @Override public boolean evaluate(Rewrite event, EvaluationContext context) { return profile.isLoggedIn(); } }; /* * If the user is not logged in, show them the guest home page instead of the dashboard. */ return ConfigurationBuilder.begin() .addRule(Join.path("/") .to("/pages/loggedOffHome.xhtml")) .when(loggedIn) .addRule() .when(Direction.isInbound() .and(Path.matches("/login").or(Path.matches("/signup")) .andNot(loggedIn)) .perform(Redirect.temporary(context.getContextPath() + "/")); } }
Inject beans and services into configuration using CDI
This example depends on the rewrite-integration-cdi module; you will need to include it as a dependency/JAR in your application.Exhibit 4
public class ExampleConfigurationProvider extends HttpConfigurationProvider { @Inject private RuleDatabase source; @Override public Configuration getConfiguration(final ServletContext context) { return ConfigurationBuilder.begin() .addRule() .when(new HttpCondition() { public boolean evaluate(HttpServletRewrite event, EvaluationContext context) { return source.includes(event.getRequest().getRequestURL()); } }) .perform(new HttpOperation() { @Override public void performHttp(HttpServletRewrite event, EvaluationContext context) { source.takeAction(); } }); } }
Relocate resources using a Content Distribution Network (CDN)
The goal of a CDN is to serve content to end users with high availability and high performance, increasing the performance of websites that use them. Besides better performance and availability, CDNs also offload the traffic from your servers onto a server designed to quickly serve static files.Exhibit 5
public class ExampleConfigurationProvider extends HttpConfigurationProvider { @Override public Configuration getConfiguration(final ServletContext context) { return ConfigurationBuilder.begin() // Relocate jQuery to CDN .addRule(CDN.relocate("{p}jquery{s}.js") .to("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js")) .where("p").matches(".*") .where("s").matches(".*") // Relocate custom CSS (or other outbound link) to a custom URL .addRule(CDN.relocate("{p}foo-{version}.css") .to("http://mycdn.com/foo-{version}.css")); .where("p").matches(".*") .where("version").matches(".*") } }
Secure resources using JAAS roles constraints
Exhibit 6
public class JaasRolesTestProvider extends HttpConfigurationProvider { @Override public Configuration getConfiguration(final ServletContext context) { Configuration config = ConfigurationBuilder .begin() .addRule() .when(JAASRoles.required("admin", "privacy-monitor") .and(Direction.isInbound()) .and(Path.matches("/admin/{tail}"))) .perform(Forward.to("/internal/resource.jsp")) .where("tail").matches(".*"); return config; } }
Please, if its possible, could you guys provide examples that:
– receive a parameter and set it in a bean, like in #{ p : bean.p }
– join a path and execute an action before redirecting. Pretty much like the ‘action’ tag in pretty config mapping.
Thanks a lot
Sure! Will do, for now, this should do:
Please, is there a way to set a session attribute with a parameter?
For instance:
This:
Would perform:
Is there a way to get this behavior with 1.1.0.Final?
The reason I’m asking this is because setting a parameter to requestParameterMap doesn’t work well with @ViewScope and ajax submissions to the same view.
Once you perform the ajax request the param is gone from requestParameterMap. By setting the attribute to session would solve it.
Other way would be binding the param to a EL property of a SessionScoped bean, but wouldn’t that be ugly?
Please could you give me some hints what is the recommended way to make prettyfaces domain sensitive? I am curious how to serve "microsites" in following pattern:
I have applicatoin on main domain configured for prettyURL parameters like
http://www.mainDomain.com/embed/#{lang}/microsite1/somestuff
and want the same application serve
http://www.microsite1.com/somestuff
with the same jsf page
It means capture server name microsite1 from request –> prepend /embed/#{lang}/microsite1/ according dynamic microsite configuration –> and let prettyconfig do it’s jobs.
I want to keep http://www.microsite1.com/somestuff adress in browser and need #{lang} to be injected to JSF bean.
Currently I am using prettyFaces 3.3. Is it possible to achieve this by prettyfaces and possible enhancements by Rewrite?
Thank a lot for any advice.
Hi,
Assume, all my XHTML files are located in webapp under the folder "mod". I would like to avoid the need to type /mod/… in URLs. How can I rewrite URLs with the Rewrite, so that all requests get a prefix "mod" when resolving against real paths? For instance, when somebody types as URL
, it should be resolved (mapped) to
.
Thanks in advance.
Hi
Is there some "universal" configuration file, which makes JSF links human-readable by default?
I mean all "/long_path/sample.jsf?id=10&name=tom" are automatically converted to "/sample/10/tom" in all auto-generated urls (including jsf 2.2 navigation model) and such links are processed correctly?
I understand that there could be a problem in binding named parameters with URL fragments, but probably there’s some solution for this (like annotations)?
Thanks in advance,
Andrey
Hi,
Can i use this rewrite for doing this in jsf 2 application :
when user type : localhost , il redirect to localhost/MyApp.
thank’s