mapping controllers without annotations - spring

Is there a way to do mapping in Spring/Spring-boot to controllers without anno's on controllers?
In Grails I was able to write a completely abstracted api without api functionality, checks, annotations on the controller. This allows for all functionality and data to be handled in the front controller through handlerInterceptor... and controller merely has to create resource. This also makes it easier to share functionality/data for api across I/O flow in architecture.
How do we map request to controller/method without annotations? There must be a way since it can be done in Grails.

Put below tag in your bean configuration file. This will scan your controller class in your base package. Just define package name where you put your controller classes.
<beans
xmlns:context="http://www.springframework.org/schema/context">
<context:component-scan base-package=" " />
</beans>
As for example -
You have controller class called controller1, controller2 in com.pacakge.controller.demo1
and controller3, controller4 in com.pacakge.controller.demo2
here your code -
<context:component-scan base-package="com.pacakge.controller" />

Related

base package attribute in context:component-scan tag in spring 3

I am writing simple Hello application using maven in spring 3. I have made a HelloWorldService class by using #Service annotation. In the applicaioncontext.xml file giving different value to base-package attribute of context:component-scan base-package="yyy.xxx". My program is running.
What is the use of base-package in context:component-scan?
What is the purpose of the second tag, <context:component-scan>? Well, you need a bit of background information to understand the purpose of this tag.
Basically,say the #Controller annotation indicates that a particular class located at base-package="yyy.xxx" serves the role of a controller. Another example the #RequestMapping annotated methods to serve a web request.
So, component-scan base-package="yyy.xxx" will tell the spring container via the dispatcher servlet to locate such annotated classes and methods for mapping. But, There are plenty of more detailed explanation if you google it.

Clarification needed on Spring MVC without using Annotation

I am trying to understand Spring MVC in more detail what I currently know. I am referring to online tutorials and books. As I understand, Spring MVC framework has "Front controller" and "MVC" design patterns.
The front controller (DispatcherServlet) uses the HandlerMapping for mapping URL to the controller classes. I am not using annotations because I want to understand what the framework does behind the scenes.
In this quest, I created a simple web-application based on Spring MVC, the code is below:
Controller code:
public class SimpleSpringController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse res) throws Exception {
ModelAndView mw = new ModelAndView("welcome","welcomeMessage", "welcome user!");
return mw;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>FirstSpringMVCProject</display-name>
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring xml configuration
<beans>
<bean id="HandlerMapping1" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/welcome" class="com.example.controller.SimpleSpringController"/>
<bean id="viewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix"> <value>/WEB-INF/</value> </property>
<property name="suffix"> <value>.jsp</value> </property>
</bean>
</beans>
The application works as expected.
The concepts which I am not able to understand is on the spring configuration xml where we specify the HandlerMapping and ViewResolver implementations.
For example, we have the following bean definition in the above spring xml configuration:
<bean id="HandlerMapping1" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
In above xml config, org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping is one of the implementations of the HandlerMapping interface.
The bean id for this is HandlerMapping1, which is just a random identifier ( I could have very well chosen MyHandlerMapping). The following are the doubts:
Who reads this configuration file? Do front controller read this configuration file?
How does the framework knows that the id of HandlerMapping implementation in above case is HandlerMapping1. Usually we do getBean("beanId"), where we specifically know what a particular bean id is. How come spring framework is automatically infer that this is the implementation class of HandlerMapping.
Any inputs to understand this would be of great help.
Initialization
In Spring the front controller is the DispatcherServlet, this extends the FrameworkServlet. The FrameworkServlet by default creates a XmlWebApplicationContext and tries to read an XML file named <servlet-name>-servlet.xml (this is when using a web.xml!). (All this can be overridden by setting the appropriate init-params for the configured DispatcherServlet).
The DispatcherServlet will after loading eventually call the initStrategies method. This method will configure the delegation strategies for the DispatcherServlet. It will first try and detect most of the strategies by type (like HandlerMaping, HandlerAdapter, ViewResolver etc) and some by name (localeResolver, themeResolver, messageSource etc.). If that cannot be found the default strategies for a given interface will be installed. Those defaults are defined in the DispatcherServlet.properties inside Spring.
Important: As soon as you define a strategy yourself the defaults for that strategy don't apply anymore!. For instance if you have a BeanNameUrlHandlerMapping in your configuration, the default configuration for HandlerMapping isn't loaded anymore as you provided explicit configuration.
Request Handling
After startup the DispatcherServlet is ready to handle request.
Image comes from the Spring Framework reference guide
Handler Selection and execution
What happens is when a request is handled by the DispatcherServlet it will check all configured HandlerMappings to see if one is able to provide a handler (a Controller or #Controller is just one of the handler types that can be handled) for the given request. As soon as a handler is found, it will lookup a HandlerAdapter for the detect handler. If that is also found the found handler together with the current HttpServletRequest and HttpServletResponse are passed to the HandlerAdapters handle method.
View resolution
Now if a ModelAndView is being returned from the HandlerAdapter.handle method a View is going to be resolved if the ModelAndView.getViewName() method returns a name, this is going to be passed on the an to a ViewResolver to be resolved into a View.
When a View is either being resolver or being returned from the ModeAndView.getView() method, the render method is going to be called to let the chosen View render itself. With the (optional) model from the ModelAndView class.
Exception Handling
When an exception occurs during processing of the request this exception is first being passed to the configured HandlerExceptionResolvers. If one of them can handle it the selected HandlerExceptionResolvers resolveException method is being invoked. This method, just like the HandlerAdapter.handle method can return a ModelAndView, when this happens this is processed in the same way as a normal request (see View Resolution).
Note: This is also to some degree documented in the javadoc of the DispatcherServlet. You can find all the default strategies and well known names in there, as well as a explanation of the request handling flow.
The controller does not read the xml file, Spring does.
Your spring xml configuration is loaded in by Spring which wires everything together. Autowiring is taking place which is wiring by the Type, of which HandlerMapping1 can provide for the interface HandlerMapping.
Interestingly BeanNameUrlHandlerMapping is the default handler mapping class, so it is the one created by the DispatcherServlet when Spring cannot find any handler mapping class declared.
If you want to try and see something break, create a duplicate bean named HandlerMapping2 and read the error logging.
Spring framework reads the xml.
Well, for spring MVC to work, the handler should be instantiated.
The spring MVC framework needs to resolve the mappings and so we
have handlers like BeanNameUrl..., ControllerBeanNameHandlerMapping,
etc
However, HandlerMapping is not generally used by your application
code. So you need not specify whether this bean is autowired by type
or not. It is used by the framework. So it is autowired in the
framework classes by type.
You can try defining the bean in the xml without any id, name
something like
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
and it should still work.
Id or name is required only when you want to refer to the bean by id
or name for your use. Framework classes which need this handler
mapping don't refer to the bean of HandlerMapping type by id or
name. Framework will 'scan' the xml (or the loaded classes) and if
it finds a concrete class in there of type
(org.springframework.web.servlet.HandlerMapping) then it won't
complain.
To think of a similar case for example, when you run the junit
tests, the engine will scan for all the methods annotated with #Test
and it will 'know' that these are the methods it needs to execute as
tests. It does not matter what the names of test methods are.
Hope this answers the query.

Creating Spring Service that reads a file and serve queries based on its data

In a Java Web Project with Spring and JSF, I want do this: I want to have a service that in the first run of the app, reads a file and puts its data to a variable. then other classes can read that variable.
In fact I want that file reads one time and after that I just query the data, even web pages changed via links and navigation system.
Is there a Spring annotation to turn class to a service like this? Should I have some XML config files to specify a class as a service? I don't know what I have to do. What I know is that it can be done via Spring and I can get its data from JSF components, but how?
I have to do this based on MVC.
You can have it lazy-loaded on first call of the service. Or you can add a ContextListener to initialize the service on startup of the web context, assuming you are deploying to a J2EE container. Or you can make that service a spring bean with an init-method that initializes the data. Or any one of a hundred different ways. You'll need to determine what works best for your application.
Here's a spring example:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="myService"
class="org.your.Service"
init-method="initializeData"></bean>
</beans>
How you get hold of that service is up to you. You can either have the data stored statically on the class, or you can use the spring context to retrieve this single instance of the spring bean.
Spring documentation for lifecycle methods: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-lifecycle

Register Spring filter from BeanDefinitionParser

I am creating a custom namespace for use in the Spring XML configuration. I already implemented a NamespaceHandler and BeanDefinitionParser. So, now I can just put <myns:some-awesome-feature /> into my Spring configuration and it creates the required beans automatically.
In addition to creating some normal Spring beans I would also like to have this annotation register a OncePerRequestFilter to extract some information off of a request for my code to be able to utilize. Is there a way to register a filter programmatically using the two classes I have available when implementing a custom XML tag?
It is not possible without touching web.xml or WebApplicationInitializer, respectively.
But you can create an extendable solution that allows modifications in future without hassle.
Spring Security's <http pattern='...' security="..."/> automatically creates and registers a series of chained filter beans for you. All you have to do is to
register DelegatingFilterProxy in you web.xml and reference springSecurityFilterChain.
You can create a similar solution where you are defining e.g. <myns:awesome-http pattern='...' /> which instantiates OncePerRequestFilter. In web.xml you are declaring a DelegatingFilterProxy which references your awesomeFilterChain. In a future version you can add more filter to your chain without touching the configuration.
I have never implemented such a feature but I'm quite confident that it is possible.
As a starting point take a look at the source of HttpConfigurationBuilder and HttpSecurityBeanDefinitionParser to see how Spring Security implemented <http .../>.

spring xslt view

I want to add xslt view to my spring web application. But my web application configured using spring annotations and hence it does not have any expicitly declared view resolvers. I tried to add a view resolver specially for xslt but the rest of my application becomes unresolvable. It it possible to configure xslt view only using annotations? Or may be there is another solution?
Thank you.
I would guess that it would suffice to write a ViewResolver class and annotate it as #Component, provided that you have <mvc:annotation-driven /> in your xml context.

Resources