Directory

← Back

URL Parameter Mapping

Flexible URL parameter mapping for Vaadin Flow

Author

Rating

Popularity

<100

URL Parameter Mapping for Vaadin Flow

While https://github.com/vaadin/flow/issues/2740 and https://github.com/vaadin/flow/issues/4213 are still in the works, the need for flexible parametrized routes still exist. This helper implementation lives on top of built in HasUrlParameter and provides support for named parameters.

Simple usage example:

import org.vaadin.flow.helper.*;

...

@Route("example")
@UrlParameterMapping(":exampleId/:orderId")
// Will match /example/12345/ORD223434, set exampleId = 12345 and
// call setOrder("ORD223434")
// Otherwise user will be rerouted to default NotFoundException view
class MyView extends Div implements HasUrlParameterMapping {
    // Note: parameter fields/setters should be public    
    @UrlParameter
    public Integer exampleId;
    
    @UrlParameter(name = "orderId", regEx = "ORD[0-9]{6}") 
    public setOrder(String order) { ... }
    ...
}

The following features are implemented:

  • Support for Integer, Long, Boolean, String and UUID properties (with automatic regular expression checks)
  • Parameter placeholders: order/:orderId
  • Optional parameters: order/:orderId[/:rowId]
  • Parameters in the middle of path: order/:orderId/edit
  • Multiple alternative mappings
  • (Optional) Automatic rerouting to view.
  • Inline regular expressions: forum/thread/:threadId/.*
  • Custom regular expressions: @UrlParameter(regEx = "overview|samples|links")
  • Dynamic regular expressions for parameters
  • RequestHandler support
  • URL formatting
  • Query parameters support

Sample code

@Route("example")
@UrlParameterMapping(":exampleId[/:version]")
// Will match /example/12345 and /example/12345/678
// version property will receive null when missing 
@Route("example")
@UrlParameterMapping("edit/:exampleId")
// Will match /example/edit/12345
@Route("order")
@UrlParameterMapping("detail/:orderId/edit")
// Will match /order/detail/12345/edit
@Route("order")
@UrlParameterMapping("detail[/:rowId]/edit")
// Will match /order/detail/12345/edit and /order/detail/edit
@Route("new-message")
@UrlParameterMapping(":userId")
...
@UrlParameter(regEx="[0-9]{1,6}")
Integer userId;
// Will match /new-message/123456, but not /new-message/1234567
@Route("forum/thread")
@RouteAlias("forum/message")
@UrlParameterMapping("forum/thread/:threadId[/:urlTitle]")
@UrlParameterMapping("forum/thread/:threadId/:messageId")
@UrlParameterMapping("forum/message/:messageId")
// Will match (with HasAbsoluteUrlParameterMapping)
// - /forum/thread/12345
// - /forum/thread/12345/forum-post-title
// - /forum/thread/12345/67890
// - /forum/message/67890
import org.vaadin.flow.helper.*;

...

@Route("example")
@UrlParameterMapping("example/:exampleId")
// Will match /example/12345 and call setExampleId(12345)
class MyView extends Div implements HasAbsoluteUrlParameterMapping {
    //                         note ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    @UrlParameter
    public Integer exampleId;
    
    ...
}
@Route(...)
@UrlParameterMapping(SomeView.ORDER_VIEW)
@UrlParameterMapping(SomeView.ORDER_EDIT)
class SomeView extends Div implements HasUrlParameterMapping {
    final static String ORDER_VIEW = ":orderId[/view]";
    final static String ORDER_EDIT = ":orderId/edit";

    @UrlMatchedPatternParameter()
    public String matchedPattern;

    @UrlParameter(name = "orderId")
    public void setOrder(Integer orderId) { ... }

    @Override
    public void beforeEnter(BeforeEnterEvent event) {
        if ( ORDER_VIEW.equals(matchedPattern) ) {
            ...
        } else {
            ...
        }
    }

    ...
}
@Route("order")
@UrlParameterMapping(":orderId")
@RerouteIfNotMatched(exception = OrderNotFoundException.class)
// --- OR ---
//@RerouteIfNotMatched(view = NoOrderView.class)
// Will match /order/12345
// Otherwise user will be rerouted to default OrderNotFoundException (or NoOrderView) view
@Route("example")
@UrlParameterMapping(":exampleId")
@IgnoreIfNotMatched
// Will match /example/12345
// Will not show NotFoundException view if no matches detected
import org.vaadin.flow.helper.*;

...

@Route("example")
@UrlParameterMapping(":selectedTab")
// Will match /example/12345 and call setExampleId(12345)
class MyView extends Div implements HasUrlParameterMapping {
    static {
        UrlParameterMappingHelper.setDynamicRegex(MyView.class, "selectedTab", MyView::getSelectedTabRegex);
    }

    @UrlParameter(dynamicRegEx = true)
    public String selectedTab;
   
    public String getSelectedTabRegex() {
        return String.join("|", backendService.getAvailableTabs());
    }    
    ...
}
class DownloadRequestHandler implements RequestHandler {
    @UrlParameterMapping("download/:uuid")
    public class ParameterMapping {
        @UrlParameter()
        public UUID uuid;
    }

    boolean handleRequest(VaadinSession session, VaadinRequest request,
                VaadinResponse response) throws IOException {
		VaadinServletRequest servletRequest = (VaadinServletRequest) request;
        ParameterMapping mapping = new ParameterMapping();
		
        if ( !UrlParameterMappingHelper.match(mapping, servletRequest.getRequestURI())) {
            return false;
        }
        
        ...
    }
}
@UrlParameter
public Integer orderId = 12345;

@UrlParameter
public Integer orderRowId = null;

...

String url = UrlParameterMappingHelper.format(this,"order/:orderId[/:orderRowId]/:1", "edit");
// url = "order/12345/edit"

orderRowId = 78;
String url2 = UrlParameterMappingHelper.format(this,"order/:orderId[/:orderRowId]/:1", "edit");
// url = "order/12345/78/edit"
import org.vaadin.flow.helper.*;

...

@Route("example")
@UrlParameterMapping(queryParameters = { "exampleId=:exampleId", "mode=:mode" })
@UrlParameterMapping(path = ":exampleId", queryParameters = { "mode=:mode" })
// Will match /example/12345 and set exampleId to 12345, mode to null
// Will also match /example?exampleId=34567&mode=edit and set exampleId to 34567 and mode to "edit"
class MyView extends Div implements HasUrlParameterMapping {
    @UrlParameter
    public Integer exampleId;
    
    @UrlParameter(regEx = "edit|preview")
    public String mode;
    ...
}

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

  • Removed banner.txt
Released
2019-01-11
Maturity
BETA
License
Apache License 2.0

Compatibility

Framework
Vaadin 10+
Vaadin 11+
Vaadin 12+
Browser
Browser Independent

Vaadin Add-on Directory

Find open-source widgets, add-ons, themes, and integrations for your Vaadin application. Vaadin Add-on Directory
The channel for finding, promoting, and distributing Vaadin add-ons.
Online