Results 1 to 3 of 3

Thread: Externalizing Complex URL Mappings

  1. #1
    Join Date
    Apr 2011
    Posts
    4

    Question Externalizing Complex URL Mappings

    I have a use case that seems a bit more complex than the documentation addresses and could really use some guidance.

    Imagine a site that has a wide variety of dynamic content bound to a particular location. Hotel information about a location, weather information, restaurant information, etc. This information all lives on different pages with different views associated - urls like:

    /{location}/hotels
    /{location}/weather
    /{location}/restaurants

    But in all of these cases, the "business logic" of the controller is the same: identify and validate the location, then forward to the appropriate view based on the path.

    This is all very straightforward and easily accomplished with annotations and path variables. But...

    The trouble comes in when the number of similar pages gets large. Thing dozens or even hundreds of distinct URI's spread all over a bunch of different paths that should ideally share a controller. In that circumstance maintaining URL mappings in source code becomes very unwieldy and you really want to externalize the URL's to a central config. That's all well and good if your URL's are simple - just use SimpleUrlHandlerMapping. But what do you do when you need to also support path variables (SimpleUrlHandlerMapping will only handle "*" wildcards)? Is it even possible to do such a thing?
    Last edited by cadement; Apr 22nd, 2011 at 09:18 AM. Reason: typos

  2. #2
    Join Date
    Apr 2013
    Posts
    2

    Default

    I am dealing with the same issue. Did you progress about that ?

  3. #3
    Join Date
    Apr 2011
    Posts
    4

    Default

    I ultimately decided to create a controller-chain structure for these sorts of issues. Basically, we create a parent controller that has a mapping for URI's that trail off the parent controller, then have logic in that mapping to forward to another controller to handle the delegated functionality (passing along the resolved parent domain object in the model that is forwarded to the "subcontext" controller). In this way, the logic of the parent domain (for instance, mapping User objects in the below sample) lives in just one place, but that place isn't muddied up by logic for all of the related types of data.

    For example, here's a skeleton of structures that would be able to handle the URL "/user/my-id" in a parent User controller, and also intercept the URL's "/user/my-id/blogs" and "/user/my-id/blogs/a-blog-id" at the parent User controller but then forward along the request to a subcontext "Blogs" controller to handle blog-related issues:

    Sample Controller
    Code:
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
       @RequestMapping("/{id}")
       public ModelAndView getUser(@PathVariable("id") String id) {
          ...
       }
       
       @RequestMapping("/{id}/{subcontext}/**")
       public String redirectToSubcontext(@PathVariable("id") String id, @PathVariable("subcontext") String subcontext, Model model, HttpServletRequest request) {
            User user = userServiceDelegate.getUserByIdOrProfileUri(id);
            model.addAttribute("user", user);
            String forwardUrl = forwardFactory.forSlugInUri(subcontext, request.getRequestURI());
            return forwardUrl;
       }
    }
    Forward Factory
    Code:
    public class ForwardFactory {
    
        public String forSlugInUri(String slug, String uri) {
            int slugIndex = uri.indexOf(slug);
            String forwardMapping = slugIndex != -1 ? uri.substring(slugIndex) : "";
            return "forward:/" + forwardMapping;
        }
    }
    Sample Subcontext Controller
    Code:
    @Controller
    @RequestMapping("/blogs")
    public class UserBlogsController {
    
       @RequestMapping
       public ModelAndView getAllBlogs(@ModelAttribute("user") User user) {
          ...
       }
       
       @RequestMapping("/{id}") {
       public ModelAndView getBlog(@ModelAttribute("user") User user, @PathVariable("id") String id) {
          ...
       }
    }

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •