MessageBrokerServlet with XmlWebAppInitializer approach - java

I want to remove my web.xml file from my Spring boot project.
I'm trying an hybrid approach (as this guide).
I've this MessageBrokerServlet define in my web.xml as follow:
<servlet>
<servlet-name>MessageBrokerServlet</servlet-name>
<servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MessageBrokerServlet</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>
This servlet uses a services-config.xml file about its configuration.
In the guide when I've mapped a servlet with a config location file I must write as follow:
ServletRegistration.Dynamic dispatcher = container
.addServlet("dispatcher", new DispatcherServlet(context));
So I link the servlet with its context file, but my MessageBrokerServlet has not a construction with parameter, so I've written this following code:
// MessageBrokerServlet
XmlWebApplicationContext context = new XmlWebApplicationContext();
context.setConfigLocation("/WEB-INF/flex/services-config.xml");
MessageBrokerServlet mbs = new MessageBrokerServlet();
mbs.init(context.getServletConfig());
ServletRegistration.Dynamic messageBrokenServlet = container.addServlet("MessageBrokerServlet", mbs);
messageBrokenServlet.setLoadOnStartup(1);
messageBrokenServlet.addMapping("/messagebroker/*");
container.addListener(new ContextLoaderListener(context));
But when I get the servletConfig from context object it is null.
How can I pass to my MessageBrokerServlet the correct servletConfig, so I can linked to services-config.xml file?

The lifecycle of the MessageBrokerServlet is handled by the servlet container. This is no difference (well a little maybe) in a Spring Boot application. So no need to call the init method.
The MessageBrokerServlet has also nothing to do with Spring so trying to load the configuration with Spring and then expect the MessageBrokerServlet to act on it won't do anything either.
With Spring Boot you can simply register a servlet as a bean in the application context and Spring Boot will take care of the registration. To register the servlet wrap it in a ServletRegistrationBean to pass the init parameters and further configuration. See also this section of the Spring Boot Reference guide.
#Bean
public MessageBrokerServlet messageBrokerServlet() {
return new MessageBrokerServlet();
}
#Bean
public ServletRegistrationBean<MessageBrokerServlet> messageBrokerServletRegistration() {
ServletRegistrationBean<MessageBrokerServlet> registration =
new ServletRegistrationBean(messageBrokerServlet(), "/messagebroker/*");
return registration;
}
Place this in your #SpringBootApplication annotated class or a specific #Configuration annotated class.
This mimics exactly what you have posted as the part in your web.xml. If you have additional init-param blocks (you didn't show them) you can use the addInitParameter method to add those to the ServletRegistrationBean.

Related

Spring MVC : new action ignored [duplicate]

I'm writing a Spring MVC application deployed on Tomcat. See the following minimal, complete, and verifiable example
public class Application extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { };
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { SpringServletConfig.class };
}
protected String[] getServletMappings() {
return new String[] { "/*" };
}
}
Where SpringServletConfig is
#Configuration
#ComponentScan("com.example.controllers")
#EnableWebMvc
public class SpringServletConfig {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
}
Finally, I have a #Controller in the package com.example.controllers
#Controller
public class ExampleController {
#RequestMapping(path = "/home", method = RequestMethod.GET)
public String example() {
return "index";
}
}
My application's context name is Example. When I send a request to
http://localhost:8080/Example/home
the application responds with an HTTP Status 404 and logs the following
WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI `[/Example/WEB-INF/jsps/index.jsp]` in `DispatcherServlet` with name 'dispatcher'
I have a JSP resource at /WEB-INF/jsps/index.jsp I expected Spring MVC to use my controller to handle the request and forward to the JSP, so why is it responding with a 404?
This is meant to be a canonical post for questions about this warning message.
Your standard Spring MVC application will serve all requests through a DispatcherServlet that you've registered with your Servlet container.
The DispatcherServlet looks at its ApplicationContext and, if available, the ApplicationContext registered with a ContextLoaderListener for special beans it needs to setup its request serving logic. These beans are described in the documentation.
Arguably the most important, beans of type HandlerMapping map
incoming requests to handlers and a list of pre- and post-processors
(handler interceptors) based on some criteria the details of which
vary by HandlerMapping implementation. The most popular implementation
supports annotated controllers but other implementations exists as
well.
The javadoc of HandlerMapping further describes how implementations must behave.
The DispatcherServlet finds all beans of this type and registers them in some order (can be customized). While serving a request, the DispatcherServlet loops through these HandlerMapping objects and tests each of them with getHandler to find one that can handle the incoming request, represented as the standard HttpServletRequest. As of 4.3.x, if it doesn't find any, it logs the warning that you see
No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName
and either throws a NoHandlerFoundException or immediately commits the response with a 404 Not Found status code.
Why didn't the DispatcherServlet find a HandlerMapping that could handle my request?
The most common HandlerMapping implementation is RequestMappingHandlerMapping, which handles registering #Controller beans as handlers (really their #RequestMapping annotated methods). You can either declare a bean of this type yourself (with #Bean or <bean> or other mechanism) or you can use the built-in options. These are:
Annotate your #Configuration class with #EnableWebMvc.
Declare a <mvc:annotation-driven /> member in your XML configuration.
As the link above describes, both of these will register a RequestMappingHandlerMapping bean (and a bunch of other stuff). However, a HandlerMapping isn't very useful without a handler. RequestMappingHandlerMapping expects some #Controller beans so you need to declare those too, through #Bean methods in a Java configuration or <bean> declarations in an XML configuration or through component scanning of #Controller annotated classes in either. Make sure these beans are present.
If you're getting the warning message and a 404 and you've configured all of the above correctly, then you're sending your request to the wrong URI, one that isn't handled by a detected #RequestMapping annotated handler method.
The spring-webmvc library offers other built-in HandlerMapping implementations. For example, BeanNameUrlHandlerMapping maps
from URLs to beans with names that start with a slash ("/")
and you can always write your own. Obviously, you'll have to make sure the request you're sending matches at least one of the registered HandlerMapping object's handlers.
If you don't implicitly or explicitly register any HandlerMapping beans (or if detectAllHandlerMappings is true), the DispatcherServlet registers some defaults. These are defined in DispatcherServlet.properties in the same package as the DispatcherServlet class. They are BeanNameUrlHandlerMapping and DefaultAnnotationHandlerMapping (which is similar to RequestMappingHandlerMapping but deprecated).
Debugging
Spring MVC will log handlers registered through RequestMappingHandlerMapping. For example, a #Controller like
#Controller
public class ExampleController {
#RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
public String example() {
return "example-view-name";
}
}
will log the following at INFO level
Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()
This describes the mapping registered. When you see the warning that no handler was found, compare the URI in the message to the mapping listed here. All the restrictions specified in the #RequestMapping must match for Spring MVC to select the handler.
Other HandlerMapping implementations log their own statements that should hint to their mappings and their corresponding handlers.
Similarly, enable Spring logging at DEBUG level to see which beans Spring registers. It should report which annotated classes it finds, which packages it scans, and which beans it initializes. If the ones you expected aren't present, then review your ApplicationContext configuration.
Other common mistakes
A DispatcherServlet is just a typical Java EE Servlet. You register it with your typical <web.xml> <servlet-class> and <servlet-mapping> declaration, or directly through ServletContext#addServlet in a WebApplicationInitializer, or with whatever mechanism Spring boot uses. As such, you must rely on the url mapping logic specified in the Servlet specification, see Chapter 12. See also
How are Servlet url mappings in web.xml used?
With that in mind, a common mistake is to register the DispatcherServlet with a url mapping of /*, returning a view name from a #RequestMapping handler method, and expecting a JSP to be rendered. For example, consider a handler method like
#RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
return "example-view-name";
}
with an InternalResourceViewResolver
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
you might expect the request to be forwarded to a JSP resource at the path /WEB-INF/jsps/example-view-name.jsp. This won't happen. Instead, assuming a context name of Example, the DisaptcherServlet will report
No mapping found for HTTP request with URI [/Example/WEB-INF/jsps/example-view-name.jsp] in DispatcherServlet with name 'dispatcher'
Because the DispatcherServlet is mapped to /* and /* matches everything (except exact matches, which have higher priority), the DispatcherServlet would be chosen to handle the forward from the JstlView (returned by the InternalResourceViewResolver). In almost every case, the DispatcherServlet will not be configured to handle such a request.
Instead, in this simplistic case, you should register the DispatcherServlet to /, marking it as the default servlet. The default servlet is the last match for a request. This will allow your typical servlet container to chose an internal Servlet implementation, mapped to *.jsp, to handle the JSP resource (for example, Tomcat has JspServlet), before trying with the default servlet.
That's what you're seeing in your example.
I resolved my issue when in addition to described before:`
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("/WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
added tomcat-embed-jasper:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
`
from: JSP file not rendering in Spring Boot web application
In my case, I was following the Interceptors Spring documentation for version 5.1.2 (while using Spring Boot v2.0.4.RELEASE) and the WebConfig class had the annotation #EnableWebMvc, which seemed to be conflicting with something else in my application that was preventing my static assets from being resolved correctly (i.e. no CSS or JS files were being returned to the client).
After trying a lot of different things, I tried removing the #EnableWebMvc and it worked!
Edit: Here's the reference documentation that says you should remove the #EnableWebMvc annotation
Apparently in my case at least, I'm already configuring my Spring application (although not by using web.xml or any other static file, it's definitely programmatically), so it was a conflict there.
Try to amend your code with the following change on your config file. Java config is used instead of application.properties.
Do not forget to enable configuration in configureDefaultServletHandling method.
WebMvcConfigurerAdapter class is deprecated, so we use WebMvcConfigurer interface.
#Configuration
#EnableWebMvc
#ComponentScan
public class WebConfig implements WebMvcConfigurer {
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
I use gradle, your should have the following dependencies in pom.xml:
dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.3.0.RELEASE'
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '9.0.35'
}
I came across another reason for the same error. This could also be due to the class files not generated for your controller.java file. As a result of which the the dispatcher servlet mentioned in web.xml is unable to map it to the appropriate method in the controller class.
#Controller
Class Controller{
#RequestMapping(value="/abc.html")//abc is the requesting page
public void method()
{.....}
}
In eclipse under Project->select clean ->Build Project.Do give a check if the class file has been generated for the controller file under builds in your workspace.
Clean your server. Maybe delete the server and add the project once again and Run.
Stop the Tomcat server
Right click the server and select "Clean"
Right click server again and select "Clean Tomcat Work Directory"
In my case using a tutorial for SpringBoot(2.7.3) RestController, startup failed with java.lang.ClassNotFoundException: javax.validation.ParameterNameProvider
I thought that Spring REST does not use WebMvc so I removed 'spring-boot-starter-web' and that resolved the startup problem. However, POST requests failed with the '404 Not Found' issue described here and spent several hours experimenting with
server.servlet.context-path
#RestController vs #Controller etc, and
SecurityConfig options
I finally resolved the 404 issue by
restoring dependency 'spring-boot-starter-web'
adding dependency
javax.validation
validation-api
and after undoing my 101 debug hacks it worked.
Very painful because even with root logger at DEBUG, there were no server-side logs to help.
For me, I found that my target classes were generated in a folder pattern not same as source. This is possibly in eclipse I add folders for containing my controllers and not add them as packages. So I ended up defining incorrect path in spring config.
My target class was generating classes under app and I was referring to com.happy.app
<context:annotation-config />
<context:component-scan
base-package="com.happy.app"></context:component-scan>
I added packages (not folders) for com.happy.app and moved the files from folders to packages in eclipse and it resolved the issue.
In my case, I was playing around with import of secondary java config files into a main java config file. While making secondary config files, I had changed the name of the main config class, but I had failed to update the name in web.xml. So, every time that I had restarted my tomcat server, I was not seeing mapping handlers noted in the Eclipse IDE console, and when I tried to navigate to my home page I was seeing this error:
Nov 1, 2019 11:00:01 PM org.springframework.web.servlet.PageNotFound
noHandlerFound WARNING: No mapping found for HTTP request with URI
[/webapp/home/index] in DispatcherServlet with name 'dispatcher'
The fix was to update the web.xml file so that the old name "WebConfig" would be instead "MainConfig", simply renaming it to reflect the latest name of the main java config file (where "MainConfig" is arbitrary and the words "Web" and "Main" used here are not a syntax requirement). MainConfig was important, because it was the file that did the component scan for "WebController", my spring mvc controller class that handles my web requests.
#ComponentScan(basePackageClasses={WebController.class})
web.xml had this:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.lionheart.fourthed.config.WebConfig
</param-value>
</init-param>
web.xml file now has:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
com.lionheart.fourthed.config.MainConfig
</param-value>
</init-param>
Now I am seeing the mapping in the console window:
INFO: Mapped "{[/home/index],methods=[GET]}" onto public
org.springframework.web.servlet.ModelAndView
com.lionheart.fourthed.controller.WebController.gotoIndex()
And my web page is loading again.
In my case, I had created Config.java (class) and also config.xml and mapping was done partially in both of them. And since config.java uses #Configuration annotation , it was considered priority. And was not considering config.xml.
If anyone gets in trouble like this , just delete config.java with annotation and try to keep config.xml , it works fine.
For me, the issue was hidden in the web.xml file.
Inside the servlet tag, you'll find:
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/todo-servlet.xml</param-value>
</init-param>
Make sure that in the <param-value> you have kept the correct location of the dispatcher servlet (aka Front Controller).
I had kept an incorrect location, hence I was able to view the homepage but all other pages were giving HTTP 404 error.
I had same problem as **No mapping found for HTTP request with URI [/some/path] in DispatcherServlet with name SomeName**
After I analyzed for 2 to 4 days I found out the root cause. Class files was not generated after I run the project. I clicked the project tab.
Project-->CloseProject-->OpenProject-->Clean-->Build project
Class files for source code have been generated. It solved my problem. To check whether class files have been generated or not, Please check the Build folder in your project folder.
So the problem can be as simple as an additional space in the path of the project. Make sure that there is no space in the path which took me quite some time to solve.

what is the use of servletcontainer initializer and how does this play a role in configuring servlets without web.xml

I am trying to configure spring app without web.xml,after googling i found webappintializer can do that, which internally uses servletcontainer initilizer,what is the use of servletcontainer initializer and how does this play a role in configuring servlets without web.xml
If you want to do initialization when the application starts or clean up when it is destroyed, you should use this interface.
When the application starts, the Servlet container calls the OnStart method of this interface, passing in as a parameter a set of all classes that implement, extend or are annotated with the type(s) declared in the HandlesTypes annotation.
The specification also add a number of methods to dynamically register Servlets, filters and listeners.
Following is example how you initialize your spring dispatcher Servlet :
public class MyWebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext ctx) throws ServletException {
ServletRegistration.Dynamic dispatcher = ctx.addServlet("dispatcher", new DispatcherServlet());
dispatcher .setLoadOnStartup(1);
dispatcher .addMapping("/");
}
}
WebApplicationInitializer - This provides programmatic way of registering servlets to your Servlet Context. Prior to servlet 3.0, you can do it only through web.xml. With servlet 3.0 specification you can register your dispatcher servlet to the servlet context, so they will be aware of your application context and function similar to servlets registered in your web.xml.
ServletContext is nothing but that provide interface method to interact with your servlet container. Its Javadoc is pretty good.
SpringServletContainerInitializer which is an implementation of ServletContainerInitializer is responsible for invoking the onStartup of WebApplicationInitializer and passes it a ref to ServletContext.
Both web.xml and WebApplicationInitializer can coexist and you can register additional servlets and i think you can override servlets as well.
You have tons of example out there in web to show you how to use WebApplicationInitializer
Hope this helps.

Spring MVC: autowire ignored in servlets

For some reasons, I can autowire in my controllers but not in a servlet I created.
This is the top part of my servlet:
#Component
public class MyServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
#Autowired
private CobiService cobiService;
In my web.xml this is the related configuration:
<servlet>
<servlet-name>convservlet</servlet-name>
<servlet-class>com.gim.servlets.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>convservlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
And this is the way I tell spring to scan for components:
<context:component-scan base-package="com.gim" />
For some reason my autowired object cobiService is null. Did I forget anything? What should I change?
Servlets are not managed by Spring, they are managed by the Servlet container (like Tomcat). Therefore Spring cannot inject dependencies into Servlets in a normal Spring way. You can however do something like the following:
public class MyServlet extends javax.servlet.http.HttpServlet {
private CobiService cobiService;
#Override
public void init() throws ServletException {
super.init();
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
cobiService = applicationContext.getBean(CobiService.class);
}
}
You can override your servlet init method, and do
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext (this);
SpringBeanAutowiringSupport
There is no need to do
implements javax.servlet.Servlet, since you are extending HttpServlet
There are two servlets being created. One is being created by the servlet container/Java EE container when the application initializes and reads the configured <servlet> tag inside the web.xml file. The other would be created when the Spring IOC container performs its component scanning upon initialization.
In this case, the first instance is not able to participate in dependency injection because it was not created within the Spring IOC container. In order to participate in dependency injection, a bean must be managed by the Spring IOC container. When the servlet container/Java EE container instantiates the servlet it has no knowledge of Spring's IOC container.
Unfortunately, when a request comes in that satisfies the url-pattern specified in the web.xml file for the servlet, the request is redirected to the first instance created by the servlet container/Java EE container which is not a bean and not a candidate for autowiring.
If you were to remove the servlet from web.xml and add a #RequestMapping annotation to the servlet, the second instance (which is an actual bean able to utilize autowiring) would be utilized for requests fullfilling the specified url pattern in the #RequestMapping, however at that point you pretty much have a controller.
So in summary, my recommendation would be to adhere to Spring conventions and use a controller class. The controller class will match and exceed the functionality provided by the Servlet.

Why Must I create a ContextLoaderListener with SpringForm?

I was trying to get spring form to work, I am using spring mvc only, When ever I try to add the spring form tag with a modelAttribute it fails and says that no ContextLoaderListener was found.
this is my JSP code for creating the form:
<sf:form method="POST" cssClass="form-horizontal" modelAttribute="companySearch">
and here is how i find my beans and my mvc is annotation-driven
<context:component-scan base-package="com.mubasherjson.controllers" />
<context:annotation-config />
<bean id="companySearch" class="com.mubasherjson.models.CompanySearch" />
<mvc:annotation-driven />
and this is my code of the post method
#RequestMapping(method = RequestMethod.POST)
public String showResultPage(Model model){
model.addAttribute(new CompanySearch());
return "result";
}
I also tried it with #ModelAttribute annotation but still nothing works, I also added the action attribute to the form but still no luck, my root path of this method is "/"
why must I create a ContextLoaderListener here ? basicly the CompanySearch is a Model and its a simple POJO, If I remove the form or comment it everything works fine. what seems to be the problem here, I've checked various questions here but still don't get it in my case
Bootstrap listener to start up Spring's root WebApplicationContext.
Simply delegates to ContextLoader.
Doc
It is a servlet listener called by container. Which creates application context and loads the XML bean definition files. It means everything starts with it and have to have it.
You can define it by
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
ContextLoaderListener Vs DispatcherServlet
In Spring MVC, there are two context. One is the application context or global context which is booted up by ContextLoaderListener. It takes all the configuration file mentioned in contextConfigLocation parameter.
Now if you are are using Spring MVC also than Dispatcher servlet is required, which boots up another container which is also known as web application container. This container takes the global container as a parent.
If you are using Spring in the backend only, then the global context is good enough. However if you are using Spring MVC also for front end than you need Dispatcher Servlet also.
(Copied from http://www.coderanch.com/t/516563/Spring/DispatcherServlet-ContextLoaderListener, I am too lazy and there is already lots of stuff out there)

How to mage java servlet managed (or DI) in Spring?

I have a project with a few old HTTPServlets, I would like a way to manage the creation/life-cycle of the Servlet in Spring so I can do a few things like DI and pass in database objects through Spring/Hibernate integration.
First I have setup the Spring application context in web.xml as follows;
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Next I have my servlet definition in web.xml;
<servlet>
<servlet-name>oldHttpServlet</servlet-name>
<display-name>oldHttpServlet</display-name>
<servlet-class>com.package.MyServlet</servlet-class>
</servlet>
In my Spring application-context.xml I would like to make some bean def as follows;
<bean id="oldHttpServlet" class="com.package.MyServlet"></bean>
I think the above I need to implement some interface within my servlet, keep the bean definition as above in the Spring app-context.xml and then make a change to the servlet definition in the web.xml... I'm not sure what is the simplest change to make as there is some inheritance to worry about on the MyServelet.java side, which looks like this;
class MyServlet extends MyAbstractServlet{
void doStuff(){
//YOu know...
}
}
And MyAbstractServlet;
class MyAbstractServlet extends HttpServlet{
doPost(){
//Some post implementation here...
}
}
What is the best way to wrap MyServlet in Spring and have it loaded from there rather than being instantiated via web.xml?
I'm assuming the best way would be to use Springs HttpRequestHandler and then use the HttpRequestHandlerServlet in the web.xml in place of the current servlet. However I'm not sure how I go about implementing the HttpRequestHandler interface to work with the existing doPost() stuff in the myAbstractServlet...
If you need to inject dependencies into a servlet than I would go with Spring's HttpRequestHandlerServlet. You create an implementation of HttpRequestHandler (it has a method:
public void handleRequest(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException;
that you need to implement - it is the equivalent of what you'd have in a doGet / doPost.
The instance of all your HttpRequestHandler implementatins should be handled by spring (set up an annotation driven config and annotate it with, say, #Component) or use an XML config to set up those beans.
In your web.xml create the mapping for HttpRequestHandlerServlet. If you name the servlet the same as you did your HttpRequestHandler then Spring will make HttpRequestHandlerServlet automatically handle the request with the matching HttpRequestHandler.
Since HttpRequestHandler is a Spring bean, you can make Spring inject all the services you need into it.
If you still do not want to use HttpRequestHandler in lieu of Servlets than all that is left is some "programming judo", like retrieving WebApplicationContext with Spring utils and getting beans from there by a "per name" basis. Servlets are not instantiated by Spring so it cannot manage them. You would have to create a base class for your servlets and manage the DI as an initialization step yourself.
The code would look like this (inside a servlet):
WebApplicationContext webContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
CertainBeanClass bean = (CertainBeanClass) webContext.getBean("certainBean");
[EDIT]
Indeed, as one of the commenters suggested, there IS one more option. It still requires you to do a manual setup in your servlets init method though. Here is how this would look like:
public void init(ServletConfig config) {
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
You may also try your luck with #Configurable annotation on Servlet with weaving, but this might or might not work (I think Servlet might get initialized before Spring context is set up, so it still won't have the possibility to do its magic).
The ideal use of Servlet should be as Controller and underlying container manages its life cycle so we don't need Spring to manage its instance
so I can do a few things like DI and pass in database objects through Spring/Hibernate integration.
You should never have dependency of Servlet in your dao/services, Your servlet should be calling services which is perfectly suitable to manage with Spring DI context
regarding SpringBeanAutowiringSupport, note from the javadoc:
NOTE: If there is an explicit way to access the ServletContext, prefer such a way over using this class. The WebApplicationContextUtils class allows for easy access to the Spring root web application context based on the ServletContext.

Categories

Resources