How to configure CXF servlet outside of web.xml - spring

I want to be able to disable webservices using spring profile. I have surrounded all the cxf related beans with:
<beans profile="webservices">...</beans>
But what is left is cxf servlet in web.xml:
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
I'm thinking to replace it with:
<servlet>
<servlet-name>webservicesDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webservicesDispatcher</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
I need to configure webservicesDispather to do the same thing as the CXFServlet does. So far contents of webservicesDispatcher-servlet.xml looks like this:
<beans xmlns="... >
<beans profile="webservices">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
</beans>
</beans>
So, any idea what contents of webservicesDispatcher-servlet.xml should be?

AFAIK CXFServlet will have to be the front controller for CXF flow, DispatcherServlet cannot replace the functionality that CXFServlet performs - any reason why you want the DispatcherServlet alone to handle both Spring MVC flow and CXF WS flow - CXF servlet can refer to the beans in the context file defined by the DispatcherServlet either way.

Related

How to map multiple Controller in java Spring MVC in context.xml

I have 2 controllers(Home,Rest) in my application and I would like to add mapping for both of them in web.xml and applicationContext.xml.How would I do that ?
Please read and include this guide in your project it is helpfull for your.
Please define your class is controller using #Controller annotation
include this in web.xml file
<servlet>
<servlet-name>springweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springweb</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</servlet>
3.Write this in servlet-context.xml file
<context:component-scan base-package="mypack.controller" />
<context:annotation-config></context:annotation-config>
In base-package you can give your root package name.
When your web request is arrived in servlet-context.xml file, it is redirected to specific controller using base-package attribute you have defined.

Spring 4 project not working after adding websocket handling xml

I have a spring4 webapp which works perfectly fine , but after adding spring websocktes configuration xml my app refused to map any http get request.
Error message : Dispatcher servlet doesnt find any handler for this maping.
My web.xml looks like
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext*.xml</param-value>
</context-param>
<servlet>
<servlet-name>webapplication</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<async-supported>true</async-supported>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webapplication</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
My webapplication-servlet.xml looks like
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="1"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="2"/>
Till now every thing works fine as i am getting every request mapping from dispatcher servlet
but after integrating spring websockets in my app my dispatcher servlet doesnt map any http request to my any of the controllers.
I added below code snippet to my webapplication-servlet.xml and i also tried to add this in my application context also.
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/ws">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic"/>
</websocket:message-broker>

How to change Spring MVC default controller name and it's location

I am new to Java and Spring Framework. Iam using Spring STS 3.1.0.RELEASE with tomcat 7. I creating Spring MVC project by using following directions . File > Spring Template Project > Spring MVC Project. Follwoing is web.xml file code :
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And following is servlet-contxt.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="org.dave.foo" />
</beans:beans>
I want ot change default name and location of controller. For this purpose, I create new package org.dave.bar and move IndexController to this package. I also make change as mentioned below in servlet-context.xml file :
<context:component-scan base-package="org.dave.bar" />
But I receive 404 error after restaring web server and running the code on this url (http://localhost:8080/bar/). Can some one guied me what Iam doing wrong and how it can be rectified.
Thanks in advance
First in the web.xml you will need to define the URL Mapping for which you want the Spring MVC Dispatcher Servlet to handle(via request mapped methods in the controllers).
From what I understand in your question you will want to set the URL Mapping as follow (in web.xml)
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Second,
Under org.dave.foo you will need to place your Spring MVC controllers (classes annotated with #Controller and the URL mapped methods).
In your controller you will need a method mapped to the root of the spring dispatcher servlet URL mapping (defined in web.xml DispatcherServlet):
So for the definition in above you will need a method like this:
#RequestMapping(value = "/")
public ModelAndView index(HttpServletRequest request,
HttpServletResponse response) {
...
}
Note that in general the most specific requests mapping "wins". This means that if you have a request mapping of "/abc" in a controller in addition to the "/" request mapping, then, a request localhost/myapp/abc will "win" localhost/myapp/
You can take a look at a more detailed example here:
http://www.commonj.com/blogs/2012/11/30/spring-mvc-default-controller-name/
Hope it helped.

#Autowired does not work Spring 3

I looked all around to find a solution and couldn't find.
I am using Tomcat, Spring 3 with the jars:
org.springframework.aop-3.0.5.RELEASE.jar
org.springframework.asm-3.0.5.RELEASE.jar
org.springframework.beans-3.0.5.RELEASE.jar
org.springframework.context-3.0.5.RELEASE.jar
org.springframework.core-3.0.5.RELEASE.jar
org.springframework.expression-3.0.5.RELEASE.jar
org.springframework.jdbc-3.0.5.RELEASE.jar
org.springframework.orm-3.0.5.RELEASE.jar
org.springframework.test-3.0.5.RELEASE.jar
org.springframework.transaction-3.0.5.RELEASE.jar
org.springframework.web-3.0.5.RELEASE.jar
and my code is like this:
public class EmailResource {
#Autowired
EmailManager emailManager;
}
in applicationContext I have:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="emailManager" class="com.mycompany.manager.impl.EmailManagerImpl" />
<context:component-scan base-package="com.mycompany.component" />
and the web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
However, the emailManager is always null! What am I missing?
EDITED
The EmailResource is jersey servlet for rest calls and is defined like this:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mycompany.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
You need to use a Jersey/Spring connecter to get Jersey to recognize your Spring context on startup.
Replace:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.mycompany.resource</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
With:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
....
</init-param>
</servlet>
You'll also need the jersey-spring dependency:
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>${jersey.version}</version>
</dependency>
The problem is that the Jersey servlet is specified in web.xml as a servlet and thus is not under control of Spring. Spring can't wire the dependencies.
I don't know much about Jersey, but I found this article that is maybe useful to you.
Further, you've to consider EmailManager is an instance variable of a Servlet, and you declared it as Spring Singleton (the default):
<bean id="emailManager" class="com.mycompany.manager.impl.EmailManagerImpl" />
Thus emailManager should not have any state or it will be non-thread safe.
To explain the problem: suppose that emailManager contains a state, such as a destination address, a subject and a message body. Since is defined as a Singleton, there is only one instance for the whole application. If the servlet is called at the same time by two different people, it could happen that the first process inserts the subject and that same subject is rewritten by the second process before the first was able to send the email. So the data of the two emails will be mixed.
Alternatively it can be defined with scope request, so each request will have a different instance.

spring 3 mvc multiple application context instances

here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</context-param>
<!-- Handles all requests into the application -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Maps all /app requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Why there are two instances of application context created?
When I add a scheduled method with #Scheduled it is invoked twice, because of those two application contexts.
You are loading twice times the same spring config files. Of course you have two separate application contexts. At first I would rename the servlet name for the DispatcherServerlet to "spring3mvc". The servlet definition should look like this:
<servlet>
<servlet-name>spring3Mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
If you have it in this way, you should have a spring config file "spring3Mvc-servlet.xml" in your "WEB-INF" directory. Spring will find this file automatically because of the right naming convention. In this file you should just have the beans who are important for springMVC. It could look like this:
<context:component-scan base-package="org.company.gui.controller"/>
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".view.jsp"/>
</bean>
This should fix your problem.
I noticed that you have
<load-on-startup>1</load-on-startup>
in the following block
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
try removing that... it worked for me
Do you have any other spring filters or jsp pages in your web.xml not shown in your code snippet?
I ask, to answer your question, because I believe this quote from Spring documentation could explain what might be happening...
"In the web MVC framework, each
DispatcherServlet has its own
WebApplicationContext, which inherits
all the beans already defined in the
root WebApplicationContext. These
inherited beans defined can be
overridden in the servlet-specific
scope, and new scope-specific beans
can be defined local to a given
servlet instance."
If you answered "yes" to my web.xml question, then my guess is that Spring instantiates a root WebApplicationContext when a spring filter is created (via ContextLoaderListener). So, this would happen BEFORE...
Then, when the DispatcherServlet is created, the "contextConfigLocation" refers to the same files (that is, the same bean names), so a new WebApplicationContext gets overridden bean names local to that servlet!
I wonder, even if you answered "no", whether this might still happen anyway. Since you set "contextConfigLocation" (used by the ContextLoaderListener) and "override" it in DispatcherServlet configuration; I assume Spring is not checking whether those configurations are using the same file set.
You can run these scenarios through a debugger and put breakpoints on WebApplicationContext methods to find out for sure.
Workaround:
To solve the problem, either:
1) make sure your 2 contextConfigLocations don't overlap in files they use
Or:
2) break out the Scheduling bean in its own xml file and make sure it's referred to by only one of the 2 contextConfigLocations

Resources