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!
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 .
@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.
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.
var ctrl= new MyController(); ctrl. ControllerContext = ControllerContext; //call action return ctrl. Action();
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With