How to make Spring ignore #RequestMapping annotations in specific packages - spring-mvc

I've been playing around with the concept outlined in this answer, to share a common 'contract' between server and client. I'm trying to use this concept in a Spring MVC application that contains both REST endpoints and a Feign client. The #RequestMappings on the REST endpoints are picked up like normal by Spring, but: it also picks up the #RequestMapping on the abstract API class I use for my Feign client, i.e., in terms of the linked example, I have a UserService and UserClient in my code, and Spring picks up the #RequestMapping in the UserService class.
I don't understand why this happens in the first place, because:
The UserService class is an interface. Why and how does Spring think it can map an endpoint to an interface method?? This will obviously never work.
The package containing UserService is not included in the basePackage list of the #ComponentScan annotation on my Application class
Any clues on how I can convince Spring to just ignore all classes in this package??

So apparently this is a known issue, see this thread for ways to fix it.

Related

Managing Facebook object within a Controller

This is a more general Spring question that isn't necessarily a Spring Social Facebook issue; however, I'm asking the question here because it is not clear to me how Spring is managing the Facebook reference that is passed into the controller constructor.
I'm running this in a Spring boot app, version 1.5.3.RELEASE.
I've googled around and have read many things about how scoped-proxies work and whether the Controller is a singleton and such; but something is still not clear to me with this particular use case. My concern is over whether or not two or more simultaneous request will cause one reference to interfere with the other. It seems to me that there will be a conflict regardless of the scoped-proxy solution. To address this concern, I injected a Facebook and ConnectionRepository object into the controller constructor wrapped in a Provider class.
#Inject
public CopyGroupController(
Provider<Facebook> facebook,
Provider<ConnectionRepository> connectionRepository) {
It appears to have injected meaningful data; but when attempting to run this code:
#PostConstruct
public void init() {
ConnectionRepository repo = connectionRepository.get();
this.userManager.createOrGetUser(
repo.findPrimaryConnection(Facebook.class));
}
This failure occurs:
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
This creates more uncertainty because I thought the FacebookTemplate was being managed as a request or session scoped bean and that it would Inject as a Provider so the object would reside on ThreadLocale; so two or more concurrent requests will not conflict. Passing a request scoped bean in a controller singleton constructor doesn't make any sense to me either. So I'm puzzled as to why a user specific reference would even be passed into a constructor that should only be called once.
I've tried setting breakpoints in the constructor to verify whether or not there is a conflict; but The same error as above would occur. Could someone please explain to me whether or not this is an issue and if so; how is the best, most modern way to resolve it.
Any assistance would be greatly appreciated.
Thank you in advance.
You have to register a RequestContextListener
Here you can find the problem detail
And here you can get how to add in using spring boot

Why #PostFilter don't work sometimes in Spring Security service?

I'm using spring security in my project. I have a service as follow:
public interface A {
#PostFilter("hasPermission(filterObject, 'read')")
List<MyEntity> method1();
#PostFilter("hasPermission(filterObject, 'read')")
List<MyEntity> method2();
}
In Implementation method1() I use method2(), But PostFilter in method2() don't work in this state.
Why?
Your observation is correct.
To process security annotations, Spring uses proxies. A proxy is a dynamically generated class that is put between the caller and the actual implementation. So when you use interface A you are not actually invoking your implementation directly, but a security layer.
By default Spring uses interface proxies; the proxy implements the interface in question. That means the the security is only invoked when you use A as an interface. The security is not enforced when a method is invoked from the implementation class itself, because the implementation does not know of the proxy.
By using class proxies, the security annotations can work when a method is invoked from the class itself, because then the proxy extends the implementation. However, still only annotations on public methods work.
For a more in-depth explanation of proxies, see Proxying mechanisms in Spring framework manual.

Difference between #RestController and #RepositoryRestController

What is the typical use case code that shows the difference between those two annotations - meaning the #RestController and the #RepositoryRestController - ?
According to the annotation the RepositoryRestController is a way to provide custom controllers that still take advantage of Spring Data REST functionality.
Spring Data REST Reference Guide, 15.6. Overriding Spring Data REST Response Handlers:
Sometimes you may want to write a custom handler for a specific
resource. To take advantage of Spring Data REST’s settings, message
converters, exception handling, and more, use the
#RepositoryRestController annotation instead of a standard Spring MVC
#Controller or #RestController.
Most importantly the RepositoryRestController is aware of the Spring Data REST base path and will be served under this base path.

Spring Framework: what is the purpose of <mvc:annotation-driven />

I'm relatively new to Spring and I'm a little confused about the tag.
After going through the documentation and looking around different posts it seems like the main use of is that it is required by Spring MVC to dispatch requests to #Controllers.
I created a controller with two requestMappings:
#RequestMapping(method=RequestMethod.GET, value="/health")
#RequestMapping(method=RequestMethod.GET, value="/test")
I tested the web app with and without in the servlet.xml and it doesn't seem like any difference was made with being omitted or not. The requests seemed to still reach my controller just fine.
Can anyone explain to me what exactly that tag is used for?
Thanks in advance!
The support for #Controller and #RequestMapping is provided by Spring by default. However, by enabling mvc:annotation-driven you get support for processing the requests that are mapped to annotated controller methods, such as declarative validation, formatting and conversion service. An excerpt from spring's blog that introduced the new config features
It applies sensible defaults based on what is present in your
classpath. Such defaults include:
Using the Spring 3 Type ConversionService as a simpler and more robust alternative to JavaBeans PropertyEditors
Support for formatting Number fields with #NumberFormat
Support for formatting Date, Calendar, and Joda Time fields with #DateTimeFormat, if Joda Time is on the classpath
Support for validating #Controller inputs with #Valid, if a JSR-303 Provider is on the classpath
Support for reading and writing XML, if JAXB is on the classpath
Support for reading and writing JSON, if Jackson is on the classpath
Another related usefull blog post
If this tag is not added to the XML, then you will have to manually
define the beans for components like HandlerAdapter, HandlerMapping,
Binding Initializer, Request Message converters, etc. This tag helps
registering the following components.
DefaultAnnotationHandlerMapping - This is a HandlerMapping
implementation which maps the HTTP requests to the handler methods
defined using the #RequestMapping annotation.
AnnotationMethodHandlerAdapter - It is responsible for scanning the
controllers to identify methods (and parameters) annotated with #MVC
annotations. It scans and caches handler methods annotated with
#RequestMapping. Also handles the #RequestParam, #ModelAttribute,
#SessionAttributes and #InitBinder annotations.
ConfigurableWebBindingInitializer - The initializer for the Web Data
Binder. Helps in declaratively configuring the Web Binder with
validators, conversion services, property editors, etc.
LocalValidatorFactoryBean - Implements the validator interface and
enables JSR303 validation. This is injected into
ConfigurableWebBindingInitializer.
FormattingConversionServiceFactoryBean - A conversion factory that
returns conversion services for basic objects like date and numbers.
This factory is again injected into ConfigurableWebBindingInitializer.
Support for Message Converters
Finally a more formal definition in the official docs

Extend HttpServlet implement ServletContextListener

Is it a good practice for a class to extend HttpServlet and implement ServletContextListener?
public Myclass extends HttpServlet implements ServletcontextListener {
}
What are the pros and cons of doing this?
Some thoughts:
You will have at least two instances of your class. The container create one as ServletContextListener and at least one as HttpServlet when your servlet get an incoming request.
Since the 2+ instances you cannot use instance (just static) members to share data.
It's easier if other classes don't use the data/objects that you initialize and share in the listener because you don't have to put these data/objects to the application scope in the ServletContextListener and retrieve them in the HttpServlet.
If your initialization logic is complex maybe it's worth to separate it from the servlet code (e.g. putting the initialization code to a different class and using the application scope to get the shared objects in the servlet).
It all depends on you, the implementer. ServletcontextListener has its particular purpose. Make sure you know what it is for before using it.
In case you are creating an HTTP servlet you must extend HttpServlet.If your class wants to "receive notifications about changes to the servlet context of the web application" (copied from javadocs) it is part of, you have to implement ServletcontextListener.

Resources