Web Server: Custom URL Rewrite Rule Tutorial

From Resin 4.0 Wiki

(Difference between revisions)
Jump to: navigation, search
 
(4 intermediate revisions by one user not shown)
Line 1: Line 1:
 
{{Config}} {{WebServer}} {{Cookbook}}
 
{{Config}} {{WebServer}} {{Cookbook}}
  
If you want to take control of URL processing, you can create a custom Resin rewrite rule.
+
To take control of Resin Web Server URL processing, you can create a custom Resin rewrite rule.
Just like Resin's <resin:Forward> tag, your custom rule can match on a URL, and even have
+
Just like Resin's built-in <resin:Forward> rewrite tag, your custom rule can match on a URL. It can even use
 
rewrite predicates like Resin's <resin:IfSecure> or <resin:IfHeader> or <resin:IfFileExists>.
 
rewrite predicates like Resin's <resin:IfSecure> or <resin:IfHeader> or <resin:IfFileExists>.
  
Line 17: Line 17:
  
 
To use your rule, you'll create an instance in the <web-app> using the standard CDI XML syntax.
 
To use your rule, you'll create an instance in the <web-app> using the standard CDI XML syntax.
 +
 +
The XML tag name "MyDebugRewrite" is your class name. The XML namespace "urn:java:org.example.mypkg" is your
 +
class package. Resin will create your MyDebugRewrite class, call the setters for "regexp" and "target" and
 +
add it as a new rewrite rule.
  
 
=== WEB-INF/resin-web.xml ===
 
=== WEB-INF/resin-web.xml ===
Line 29: Line 33:
 
== The FilterChain Action ==
 
== The FilterChain Action ==
  
=== qa/MyDebugFilterChain.java ===
+
The action for a rewrite rule is a standard Java Servlet FilterChain, implementing
 +
javax.servlet.FilterChain. Because Resin executes it just like a normal filter,
 +
you can do anything in your action that you can do in a filter. In this example,
 +
we just print the request URL and the rewrite target.
  
  package qa;
+
Since not all rewrite rules need a target, the target is optional. For example, the
 +
resin:NotFound rule doesn't have a target. The example include the target to show
 +
how it can be used.
 +
 
 +
=== org/example/mypkg/MyDebugFilterChain.java ===
 +
 
 +
  package org.example.mypkg;
 
   
 
   
 
  import javax.servlet.*;
 
  import javax.servlet.*;
Line 37: Line 50:
 
  import java.io.*;
 
  import java.io.*;
 
   
 
   
  public class TestFilterChain implements FilterChain {
+
  public class MyDebugFilterChain implements FilterChain {
 
   private String _target;
 
   private String _target;
 
   
 
   
   public TestFilterChain(String target)
+
   public MyDebugFilterChain(String target)
 
   {
 
   {
 
     _target = target;
 
     _target = target;
Line 59: Line 72:
  
 
== The Rewrite Rule ==
 
== The Rewrite Rule ==
 +
 +
The example rewrite rule itself simply creates the MyDebugFilterChain action,
 +
allowing the AbstractTargetDispatchRule to handle the URL matching and any predicates.
 +
It's possible to override the parent behavior, for example if you want to add more
 +
complex requirements or complicated rewriting. (For example, for A/B testing.)
 +
 +
Since the default behavior supports rewrite predicates like &lt;resin:IfSecure> and
 +
embedded filters, your custom rewrite rule will get those behavior automatically.
  
 
=== MyDebugRewrite.java ===
 
=== MyDebugRewrite.java ===
  
  package qa;
+
  package org.example.mypkg;
 
   
 
   
 
  import javax.servlet.*;
 
  import javax.servlet.*;
Line 68: Line 89:
 
  import com.caucho.rewrite.*;
 
  import com.caucho.rewrite.*;
 
   
 
   
  public class Test extends AbstractTargetDispatchRule
+
  public class MyDebugRewrite extends AbstractTargetDispatchRule
 
  {
 
  {
 
   @Override
 
   @Override
Line 77: Line 98:
 
                                     FilterChain next)
 
                                     FilterChain next)
 
   {
 
   {
     return new TestFilterChain(target);
+
     return new MyDebugFilterChain(target);
 
   }
 
   }
 
  }
 
  }

Latest revision as of 00:00, 28 January 2012

Gears-48.pngWeb-48.pngCookbook-48.png

To take control of Resin Web Server URL processing, you can create a custom Resin rewrite rule. Just like Resin's built-in <resin:Forward> rewrite tag, your custom rule can match on a URL. It can even use rewrite predicates like Resin's <resin:IfSecure> or <resin:IfHeader> or <resin:IfFileExists>.

A rewrite rule has two components:

  • the action, which is a servlet javax.servlet.FilterChain
  • the rule itself, which implements com.caucho.rewrite.DispatchRule

Once you write the action and the rule, you can use it in your WEB-INF/resin-web.xml just like any other rewrite rule.

In this example, we'll create a trivial rewrite rule that just displays the request URI and the target URI.

Contents

Using the rewrite rule in the resin-web.xml

To use your rule, you'll create an instance in the <web-app> using the standard CDI XML syntax.

The XML tag name "MyDebugRewrite" is your class name. The XML namespace "urn:java:org.example.mypkg" is your class package. Resin will create your MyDebugRewrite class, call the setters for "regexp" and "target" and add it as a new rewrite rule.

WEB-INF/resin-web.xml

<web-app xmlns="http://caucho.com/ns/resin"
         xmlns:resin="urn:java:org.example.mypkg">

  <mypkg:MyDebugRewrite regexp="^/test/" target="/new/"/>

</web-app>

The FilterChain Action

The action for a rewrite rule is a standard Java Servlet FilterChain, implementing javax.servlet.FilterChain. Because Resin executes it just like a normal filter, you can do anything in your action that you can do in a filter. In this example, we just print the request URL and the rewrite target.

Since not all rewrite rules need a target, the target is optional. For example, the resin:NotFound rule doesn't have a target. The example include the target to show how it can be used.

org/example/mypkg/MyDebugFilterChain.java

package org.example.mypkg;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class MyDebugFilterChain implements FilterChain {
  private String _target;

  public MyDebugFilterChain(String target)
  {
    _target = target;
  }

  public void doFilter(ServletRequest request,
                       ServletResponse response)
    throws ServletException, IOException
  {
    HttpServletRequest req = (HttpServletRequest) request;

    PrintWriter out = response.getWriter();

    out.println("URI: " + req.getRequestURI());
    out.println("target: " + _target);
  }
}

The Rewrite Rule

The example rewrite rule itself simply creates the MyDebugFilterChain action, allowing the AbstractTargetDispatchRule to handle the URL matching and any predicates. It's possible to override the parent behavior, for example if you want to add more complex requirements or complicated rewriting. (For example, for A/B testing.)

Since the default behavior supports rewrite predicates like <resin:IfSecure> and embedded filters, your custom rewrite rule will get those behavior automatically.

MyDebugRewrite.java

package org.example.mypkg;

import javax.servlet.*;
import javax.servlet.http.*;
import com.caucho.rewrite.*;

public class MyDebugRewrite extends AbstractTargetDispatchRule
{
  @Override
  public FilterChain createDispatch(DispatcherType type,
                                    String uri,
                                    String queryString,
                                    String target,
                                    FilterChain next)
  {
    return new MyDebugFilterChain(target);
  }
}
Personal tools
TOOLBOX
LANGUAGES