Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically call @Controller

I am transitioning code that used implementations of Spring MVC's Controller to use the annotation stereotype @Controller. Everything is going fine except for one issue:

Given a request/response, how do I programmatically handle requests for annotation-based controllers?

Previously, (regardless of implementation) I was able to call:

controller.handleRequest(request, response)

What is the equivalent with annotations? I had assumed there would be some (perhaps static?) utility class along the lines of:

SpringAnnotationBasedControllerUtils.handleRequest(<? extends @Controller> handlerObject, HttpServletRequest request, HttpServletResponse response);

to handle the details of mapping a request to the dynamic signatures allowed by the @Controller stereotype, but I can't find such a thing.

Any suggestions?

(Please no comments on why this is a bad idea or should be unnecessary with a "good" design, etc. This is code under maintenance and must be as noninvasive as possible so a complete re-write is not an option at this time.)

Thanks!

like image 476
Brian Kent Avatar asked Aug 24 '09 20:08

Brian Kent


People also ask

Can we use @controller and @RestController together?

Yes, it's possible to have Controllers and RestControllers in the same webapp. If you want some methods of your controller to return views, and some others to return response bodies (i.e. act as in a RestController), then use @Controller , and annotate your "REST" methods with @ResponseBody .

What is the difference between @RestController and @controller annotation?

@Controller annotation indicates that the class is a “controller” like a web controller. @RestController annotation indicates that class is a controller where @RequestMapping methods assume @ResponseBody semantics by default. In @Controller, we need to use @ResponseBody on every handler method.

What is the use of @controller in Java?

The @Controller annotation indicates that a particular class serves the role of a controller. Spring Controller annotation is typically used in combination with annotated handler methods based on the @RequestMapping annotation. It can be applied to classes only. It's used to mark a class as a web request handler.

How do you call a controller action from another controller in Web API?

var ctrl= new MyController(); ctrl. ControllerContext = ControllerContext; //call action return ctrl. Action();


2 Answers

You just call the method on the object. That's one of the big benefits of annotation-driven controllers, you can write just the methods your code needs without having to bend things out of shape to conform to the interfaces. So just wire your controller bean into your code, and call the method directly.

Or are you saying you want to re-invent the mechanism by which Spring maps requests on to annotated-controllers? If so, have a look at the source for Spring's AnnotationMethodHandlerAdapter and DefaultAnnotationHandlerMapping classes. It's complex, though - annotated controllers make it easier to write controllers, but the underlying mechanism is unpleasant.

like image 112
skaffman Avatar answered Oct 12 '22 10:10

skaffman


Spring has something called a HandlerAdapter that takes a request and a controller implementation and calls it. This is to allow controllers from other frameworks to be reused in Spring. You want the AnnotationMethodHandlerAdapter. I believe you can instantiate this yourself:

HandlerAdapter adapter = new AnnotationMethodHandlerAdapter();
ModelAndView modelAndView = adapter.handle(request, response, controller);

I have done something similar myself - but I am unsure whether I am not leaving something essential out.

like image 28
waxwing Avatar answered Oct 12 '22 09:10

waxwing