Rewrite Annotations

Splash Forums Rewrite Users Rewrite Annotations

This topic contains 10 replies, has 3 voices, and was last updated by  Christian Kaltepoth 8 years, 7 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
  • #24201



    I would like to use Rewrite Annotations to implement a RESTful service. Is it possible at all? This page doesn’t describe all annotations

    Assume we have this class with Spring annotations to map incoming requests

    public class ExportController extends HttpServlet {
        private ServletContext servletContext;
        @RequestMapping(method = RequestMethod.POST) {
        public void catchAll(
             @RequestParam(value = "type", required = false) String type,
             @RequestParam(value = "filename", required = false) String filename) {
        @RequestMapping(value = "/demo", method = RequestMethod.GET)
        public String catchDemo() {
        @RequestMapping(value = "/test/{fileName}", method = RequestMethod.GET)
        public ResponseEntity<byte[]> imageDownload(
             @PathVariable("fileName") String fileName) throws IOException {

    What would be a replacement of this code with Rewrite?

    Thanks a lot in advance.


    Hey Oleg,

    You can do this, but you’d probably need to implement your own Annotation handlers, since at the moment we don’t support REST-style annotations.

    However, if you look in our showcase, you can see how I’ve implemented this using the Rewrite Configuration itself:

    We could probably add a few annotations to make this easier, but I have to ask, why not just use the JAX-RS specification from Java EE? RESTEasy is really quite nice to use!

    This is actually very easy to do, even in your own code; all you need to do is create a custom annotation, and implement an AnnotationHandler:

    Once this is done, you register your annotation handler as a service and you’re done! You now have an annotation that will use Rewrite to add behavior to your classes!

    This is the mechanism we use internally to create all annotations, and it’s also a public SPI that anyone can use for their own needs. The whole philosophy of Rewrite is to use the same APIs internally that users would use to extend the framework.

    What do you think?

    Does that help? Are your maybe interested in adding REST support to Rewrite?


    A sample annotation, handler, and registration:

    The annotation:

    public @interface Join
        * The external path to which the resource will be exposed.
       String path();
        * The internal resource to be exposed.
       String to();

    The handler:

    public class JoinHandler implements AnnotationHandler<Join>
       public Class<Join> handles()
          return Join.class;
       public int priority()
          return HandlerWeights.WEIGHT_TYPE_STRUCTURAL;
       public void process(ClassContext context, Join annotation, HandlerChain chain)

    The registration:



    Hi Lincoln,

    I have understood. Many thanks! I will give it a try.

    The problem with JAX-RS 1.x is that the spec. doesn’t specify client API and you will end up with implementation specific code because you have to configure JAX-RS Application, etc. in web.xml. So, it is not portable across multiple app servers. JBoss has RESTeasy as JAX-RS impl. and WebLogic has Jersey. We have to support both. I could not manage this. JAX-RS 2.0 specifies client API and you are portable, but JAX-RS 2.0 only works in JEE 7 complaint servers (GlassGish 4 currenty) :-).

    Therefore, I thought about some simple JAX-RS like annotations. Maybe we can provide 4-6 main annotations for that. We will see.


    It would be interesting to attempt to implement the JAX-RS 2 annotations in Rewrite, actually. I think it could be done, actually. The only tricky bit would be Marshalling/Unmarshalling of objects with JAXB or etc.



    Yes, it would be interesting. For XML response I would probably take XStream, for JSON Gson and for binary data quite normally Java. But it will require at least two extra dependencies…



    Your example is really good! But how can we combine annotations on class level with annotations on method level? In my Spring example above the class is annotated with @RequestMapping(“/”) and the methods e.g. with @RequestMapping(value = “/demo”, method = RequestMethod.GET). The method’s annotations should complement the class’ one. Do you know what I mean?

    • This reply was modified 8 years, 7 months ago by  Oleg.

    So.. the way combining annotations works is this (as far as I know… Christian did most of the work on annotations; I just refined the API:)

    Order of annotation processing:

    1. Class
    2. Method
    3. Parameter

    Each handler is provided a Context variable:

    public void process(ClassContext context, Join annotation, HandlerChain chain)
    public void process(MethodContext context, URLAction annotation, HandlerChain chain)
    public void process(ParameterContext context, Param annotation, HandlerChain chain)

    As you can see here, each sub-context also has access to the parent contexts:

    Additionally, you can store variables in the contexts for use in sub-parameter handlers:

    This is how we implemented Join with Parameter and URLAction.



    I saw ClassContext, but MethodContext and ParameterContext with access to parent contextes are really nice. Thanks for examples. By the way, what is HandlerWeights.WEIGHT_TYPE_STRUCTURAL in public int priority()? What does it mean and what is it good for?


    For that you’ll need to ask Christian. Lower priorities are evaluated first, but I believe these constants were set up to give a generic reference point, and a common set of priorities that can be used to simplify guesswork about which priority is which.


    Hey all,

    I’m back from my vacation. So I can join the discussion now. 🙂

    Regarding the HandlerWeights constants. IMHO there are typically two types of annotation handlers:

    The first type builds the basic structure of the rules. It creates for example conditions, operations or bindings. The other type of handler enriches/modifies the conditions/operations/parameters created by the first type of handlers. So the enriching handlers must always execute AFTER the structural ones.

    Example: @Parameter creates a parameter binding. @Matches modifies the parameter binding by specifying a regular expression for it.

    Lincoln is right. You can choose your own constants for ordering. These default ones are just there to simplify your life. 🙂

Viewing 11 posts - 1 through 11 (of 11 total)

The forum ‘Rewrite Users’ is closed to new topics and replies.

Comments are closed.