Announcement Announcement Module
Collapse
No announcement yet.
Invoke another Controller without using Response.sendRedirec Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Invoke another Controller without using Response.sendRedirec

    Currently, in my Controller, I'll perform some type of logic and then wish to view another page so I do a response.sendRedirect("/some/URL") and hardcore the name of the URL so that the correct Controller associated with that URL is invoked. Is there a better way to do this? This way is crappy because I'm hardcoding the URL.

    When I look at the examples like JPetstore, all of the controllers just return a ModelAndView. None of them seem to suffer this problem. Am I thinking about this all wrong? Don't get me wrong, almost all of my Controllers return ModelAndViews but sometimes I need to invoke another Controller to render the proper view instead of duplicating the logic in the same Controller.

    I would love to hear what the experienced developers have to say about this.

    --JS

  • #2
    That problem was one of the reasons I started my own sourceforge spring project. It is available at www.competities.com/springworkflow and developed to solve this very annoying problem. All the controllers and corresponding actions are described in an xml file. When a controller should invoke another controller, that controller throws a WorkflowRedirectException with a key that correspondents to another action and the workflow system will then invoke the referred controller. As a side benefit you dont have to code your own navigation javascripts or hrefs anymore if you have different options on a page resulting in different submit requests and because all the actions are centralized in a xml, its easy to turn on and off specific actions for specific pages.

    HTH

    Comment


    • #3
      Re:Invoke another Controller without using Response.sendRedi

      Hmmmm. This problem merits a branch? I didn't realize it was that serious. :-) But c'mon, there must be another way. What do the Spring guys think of this? Thanks for the reply, by the way.

      --JS

      Comment


      • #4
        Yeah pathetic isnt it. Well everyone wants to have their 15 minutes of fame and since I dont fancy going on the tv telling about how I have the biggest collection of used toiletpaper in the world, I created a sourceforge project

        But no, that wasnt the only reason I started that subproject. The main reason was the abillity to have all your actions centralized in a big xml file so that you can turn actions on and off on specific pages without having to change the jsp's. And as a side effect, the stacking of controllers emerged from that.

        Your problem could also be solved by a returning a RedirectView("/some/place") I think, but that would still leave you with the hardcoded url. But that isnt so weird, since the orignal requests all come with hardcoded urls.

        Another way could be to get your controller from the applicationContext and invoke the correct methods. This, of course, is more likely to work when your next controller is a multiactioncontroller, since that doesnt have binder and validate methods associated with it that will be performed without you knowing it.

        Hope that helps more

        Comment


        • #5
          I don't think you need that many sophistication.
          If you want to forward the job of a controller to another, you can make a
          Code:
          return otherController.handleRequestInternal(request,response);
          which will return the ModelAndView of another controller which will have made its submiting action.
          If you only want to have for view an external url, you can return a MovelAndView by an instance of RedirectView as view instead of just a name (even if generally, for internal ressource, using a name and a ViewResolver is a better approach) like this
          Code:
          return new ModelAndView(new RedirectView("/html/success.html", false), model);
          the boolean indicates whether the url is relative to the ServletContext (useful for being independant of the web application context) or not.
          Does it solve your problem ?

          Olivier

          Comment


          • #6
            Originally posted by ojolly
            I don't think you need that many sophistication.
            If you want to forward the job of a controller to another, you can make a
            Code:
            return otherController.handleRequestInternal(request,response);
            which will return the ModelAndView of another controller which will have made its submiting action.
            If you only want to have for view an external url, you can return a MovelAndView by an instance of RedirectView as view instead of just a name (even if generally, for internal ressource, using a name and a ViewResolver is a better approach) like this
            Code:
            return new ModelAndView(new RedirectView("/html/success.html", false), model);
            the boolean indicates whether the url is relative to the ServletContext (useful for being independant of the web application context) or not.
            I wouldn't call handleRequestInternal on another controller. That's subverting the normal get or post process that should be hitting that controller. You'll be using the existing request object for example, with all the params that were passed into the current controller.

            But using a new RediirectView is ok as long as you just externalize the URL so the first controller doesn't have it hard-coded inside. Then it can be set in the appcontext along with view names and handler mappings, etc.
            Code:
            return new ModelAndView(new RedirectView(getMyOtherControllerUrl(), true), model);
            In this case the RedirectView is marked as true for the context relative flag, which is preferred so the path can be relative to the context (should still start with a '/').

            I have been playing around with the idea of creating a special view resolver which would detect view names of the type
            redirect:xxxxxx
            and would be placed at the beginning of the view resolver chain, and would automatically use a redirect view. This would arguably be a bit cleaner even, as the first controller wouldn't even know that a redirect is involved.

            Comment


            • #7
              RedirectView

              Ok, I got it. RedirectView was the solution I was looking for. Thanks guys!

              --JS

              Comment


              • #8
                Hi ,
                One question I got on this is
                how to catch that model from another controller it is passed to?

                Comment

                Working...
                X