I want to have multiple implementations of #ControllerAdvice for different types of controllers. How do I force a controller to use only the one I want?
I can not use #ControllerAdvice( assignableTypes = MyController.class ) because I am putting the controller advice in a jar that will be pulled in as a dependency and users will create their controllers later.
You can define a specific or list of annotations in your Jar, then in controllerAdvice you can use "annotations" declaration to control the operations. And Controllers that are annotated with this/one of those annotation(s) declared in #ControlledAdvice will be assisted by the #ControllerAdvice annotated class.
Related
In a spring boot app, using annotations only, i want to implement security
I have added an #EnableGlobalMethodSecurity(jsr360Enabled=true) to a configuration class. the class also has an #EnableSecurity anntation
Now, when i add a #RolesAllowed to any #RestController class, be it on method level or level, the startup logs don't list the class at all. instead , there is line:
'Rejected bean name (rest controller class): no URL paths identified'.
Does anyone have an idea what might be causing this?
After #M.Deinum set me on the path, i did some reading and have an explanation. If anyone can elaborate more or correct me on the more technical details, feel very welcome.
Spring proxies classes to wire beans together.
Classes that don't implement an interface are proxied by using CGLib to make a subclass with additional functionality
classes that do implement an interface, spring uses dynamic proxy to access the functionality of the class, but doing so it can only proxy interface methods.
in my case, my controller implements an interface with non-endpoint related methods, so spring ignored all handling methods and the RequestMappingHandlerMapping did not find any methods to bind, because if only 'saw' the interface methods on the class
using #EnableGlobalMethodSecurity(proxyTargetClass=true) forces the use of CGLib, so the full methods are recognised by our mapper.
When I am using Spring 3.x
While using annotations its difficult for me to know Which type of Controller class we are going to fetch using this #Controller
With reference to
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/Controller.html
These are implementing Controller class
AbstractController
AbstractUrlViewController
MultiActionController
ParameterizableViewController
ServletForwardingController
ServletWrappingController
UrlFilenameViewController
AbstractWizardFormController
SimpleFormController
However when we are using #Controller annotation in our Spring MVC
program how to know that Our #Controller annotation is implementing
any of these controllers, Kindly anyone explain me
I think you are missing the point here. In the old times to register a controller, your class must have implemented controller interface and choose request mapping type. Sometimes you had to implement lots of code to achieve single request mapping.
Nowadays, when we have annotations, the model has changed. We can handle multiple request types per controller class. Because in single #Controller annotated class we can handle many request mappings.
Controller annotation is a specialized #Component, that tells Spring that inside it will find #RequestMapping handlers. Those handlers can be used either for returning Json, HTML or for uploading files.
Now logic connected with same module can be placed under single controller class, you are more flexible in what you want to achieve. Secondly #Controller enables us to reduce code anount significantly.
You aren't using any of those classes. You confuse the Controller interface with the annotation.
The annotation is just a marker that states that your bean is a Spring Controller and can send an receive HTTP requests.
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Controller.html
The Controller interface was introduced when there were no annotations in the Java language.
Which type of Controller class we are going to fetch using this
#Controller ?
The #Controller annotation is to tell the web container that this is the controller class for requests with urls specified with #RequestMapping(URI). you are going to fetch no class if you are annotating your class with #Controller , you just need to provide a request handler method within the class and annotate it with #RequestMapping , though the controller class can also be annotated with #RequestMapping and in that case , only method inside the class will work as request handler method.
how to know that Our #Controller annotation is implementing any of
these controllers ?
The names of the classes you have mentioned are implementing Controller interface , not that #Controller annotation is implementing anything .Those controller classes are for specific purposes ,as their names suggest .
Can Spring MVC paths be set as Java config, rather than using annotations on the controller?
I want to re-use one controller class under different path mappings, and have each instance wired with different service implementations.
For example, the API will look a bit like this:
PUT /mysql/some_key/some_value
GET /mysql/some_key
DELETE /mysql/some_key
PUT /oracle/some_key/some_value
GET /oracle/some_key
DELETE /oracle/some_key
So there'd be one instance of the controller wired with a MySqlCrudService and one instance of the controller with an OracleCrudService.
How would one configure this? The controller could have the methods annotated (eg #RequestMapping(method=RequestMethod.PUT, value="/{key}/{value}"), but when constructing the controller in Java config I'd need to specify the class-level path mapping.
org.springframework.stereotype;
or
org.springframework.web.servlet.mvc;
I had been using the stereotype but just noticed I have another option ?
org.springframework.stereotype.Controller
Is an annotation. It indicates that the annotated class is a controller as well as a candidate for auto-detection (like a #Component). This is the annotation you want to use.
org.springframework.web.servlet.mvc.Controller
Is an interface for implementing controllers. In most simple cases you probably don't want to be using this.
I have several controllers in a spring mvc application. They are regular beans that inherit from MultiActionController. They also have a custom MethodNameResolver that inspects a certain request parameter.
Now I am trying to use a new controller - a pojo with #Controller annotation. I am using #RequestMapping to resolve methods.
I am not sure if I understand this correctly, but as explained here in the spring reference, it is possible to use #RequestMapping with various filters (e.g. GET vs POST) without specifying a path, and then if a url applies to several methods then Spring falls back to InternalPathMethodNameResolver to decide which method to invoke.
How can I tell Spring to fall back to my custom MethodNameResolver? Is it enough to inject the resolver to my pojo controller?
(my controller doesn't inherit from any Spring specific class)
I guess you need to declare AnnotationMethodHandlerAdapter bean and set its methodNameResolver property.