RequestMapping in spring mvc - spring

I am trying to understand requestmapping in spring mvc, I have an application, actually I am just getting started with spring mvc.
I have these two urls
The first one with a forward slash at the end seems to be working fine.
http://localhost:8080/contactmanager/index/
The second one without a forward slash at the end does not work
http://localhost:8080/contactmanager/index
This second one gives me the 'HTTP Status 404 -' error, how can I force the application to be appending a forwards slash at the end of the url?
The method in the controller looks like this
#RequestMapping("/index")
public String listContacts(Map<String, Object> map) {
map.put("contact", new Contact());
map.put("contactList", contactService.listContact());
//org.springframework.web.context.ContextLoaderListener
//org.springframework.web.context.ContextLoaderListener
//org.springframework.web.servlet.DispatcherServlet
//org.springframework.web.servlet.DispatcherServlet
return "contact";
}
and my web.xml looks like this
<servlet>
<servlet-name>contactmanager</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/contactmanager-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>contactmanager</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Thanks in advance.

Using java configuration:
#Configuration
#EnableWebMvc
public class WebConfig {}
or using XML configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
From Spring's reference documentation:
The above registers a RequestMappingHandlerMapping, a
RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver
(among others) in support of processing requests with annotated
controller methods using annotations such as #RequestMapping ,
#ExceptionHandler, and others.
In RequestMappingHandlerMapping there is useful boolean flag - decription from Javadoc:
/**
* Whether to match to URLs irrespective of the presence of a trailing slash.
* If enabled a method mapped to "/users" also matches to "/users/".
* <p>The default value is {#code true}.
*/
public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) {
this.useTrailingSlashMatch = useTrailingSlashMatch;
}
Since this is enabled by default just make sure that your configuration uses RequestMappingHandlerMapping.
If this doesn't help you, check that spring's default servlet is configured: <mvc:default-servlet-handler/> and try add to web.xml
<!-- Disables Servlet Container welcome file handling. Needed for compatibility with Servlet 3.0 and Tomcat 7.0 -->
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>

Related

Issue in running Spring Restful web services without Spring Boot

I am trying to build Restful web services. My Maven project name is rest and I am following Spring's Building a RESTful Web Service to do that but I don't want to use Spring Boot but just create a war and host it on Tomcat in my eclise/STS. Here are my web.xml and XX-servlet.xml files:
web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
rest-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.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-4.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.rest" />
<mvc:annotation-driven/>
</beans>
GreetingController.java
#RestController
public class GreetingController2 {
private final AtomicLong counter = new AtomicLong();
#RequestMapping("/greeting")
public Greeting greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format("Hello %s", name));
}
}
when I run this on Tomcat the URL: http://localhost:8080/rest gives 404 and I see this message in tomcat console Aug 16, 2017 3:59:28 PM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/rest/] in DispatcherServlet with name 'rest'
whereas I do have the mapping.
And when I hit http://localhost:8080/rest/greeting I get http 406 with message The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers. whereas as per the tutorial it should be converted to JSON which can be rendered in the browser.
I spent a lot of time trying to figure out and looking at various posts on SO to find what's wrong but could not.
You dont have a default mapping like
#RequestMapping("/")
As per your code above you should have below url working fine
http://localhost:8080/rest/greeting

No mapping found for HTTP request with URI [/FitnessTracker/]

I am getting an warnning in springmvc
as No mapping found for HTTP request with URI [/FitnessTracker/] in DispatcherServlet with name 'fitTrackerServlet'
INFO: FrameworkServlet 'fitTrackerServlet': initialization completed in 2194 ms
Feb 26, 2017 9:43:08 AM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping found for HTTP request with URI [/FitnessTracker/] in DispatcherServlet with name 'fitTrackerServlet'
When i press url http://localhost:8080/fitnessTracker/ I am getting 404 error.
Thanks
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<servlet-name>fitTrackerServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>fitTrackerServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<display-name>Archetype Created Web Application</display-name>
</web-app>
and my servlet-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.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-3.2.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.pluralsight.controller"></context:component-scan>
<!--
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>
and my controller
#Controller
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello (Model model) {
System.out.println("Test");
model.addAttribute("greeting", "Hello WorldX");
return "hello";
}
}
Does your component-scan base-package match the package where your HelloController is in? If not, that is the problem.
<context:component-scan base-package="com.pluralsight.controller"></context:component-scan>
Configures component scanning directives for use with #Configuration
classes. Either basePackageClasses() or
basePackages() (or its alias value()) may be specified to define
specific packages to scan.
Spring does not find your HelloController and so doesn't map anything.
Otherwise you could also follow these steps.
I am wondering why you have you application configured with XML. With this tool you can start a maven project with a Spring boot application that will be, by default, already configured to build exactly what you want.
Then you only need a class with:
#RestController
#RequestMapping("/fitnessTracker")
public class HelloController {
#RequestMapping(value = "/greeting")
public String sayHello (Model model) {
System.out.println("Test");
model.addAttribute("greeting", "Hello WorldX");
return "hello";
}
}
And that's it, Spring will do the rest for you ;)
In my case the problem was that i was using this url-pattern
<url-pattern>/*</url-pattern>
instead of this
<url-pattern>/</url-pattern>
and also i had to add
#RequestMapping(value = "/fitnessTracker")
under the
#Controller
annotation.
I found the solution at : https://www.baeldung.com/spring-mvc-404-error for the pattern.

Spring 4.2.1 RestController tried to return template instead return JSON

I tried to create a Spring Rest Controller, based on this example i create a controller like this.
DeveloperRestController.java
#RestController
public class DeveloperRestController {
#RequestMapping("/developer/list")
public Developer index() {
Developer developer = new Developer("Developername", "developer#yahoo.com");
return developer;
}
}
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">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!--Here we specify about the DispatcherServlet class in the Web Deployment Descriptor-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
</web-app>
dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.developerdata.controller" />
<context:annotation-config />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
But it shows 404 page not found, seems that spring tried to load a template...
Result:
Error 404 /WEB-INF/jsp/developer/list.jsp
what should i do?
Seems like you have a configuration issue. The sample you are basing yours on is spring boot based. So it handles the configuration for you. To get yours working you will need to add jackson to the classpath. If you are using maven then:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.2</version>
</dependency>
Then you need to alter your spring config to include:
<mvc:annotation-driven />
From the spring documentation:
The above registers a RequestMappingHandlerMapping, a
RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver
(among others) in support of processing requests with annotated
controller methods using annotations such as #RequestMapping,
#ExceptionHandler, and others.
This also then enables the MappingJackson2HttpMessageConverter if jackson 2 is in your classpath.
References:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-config-enable
https://spring.io/guides/gs/rest-service/
http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/ (This one seems more appropriate for you to get started based on your problem)
With #ResponseBody, Spring will handle the JSON you need. Jackson
library is required too.
#RestController
public class DeveloperRestController {
#RequestMapping("/developer/list")
public #ResponseBody Developer index() {
Developer developer = new Developer("Developername", "developer#yahoo.com");
return developer;
}
}

Spring singleton #autowired service and shared state

I have a controller and a filter in which I inject a particular service.
In that service I have a Hashmap where I try to store certain information. The issue that I am running into is that although it appears that that a single instance of that service is created and injected into my controller and my filter it seems that there an two instances of the Map. I'm at a loss as to why. No matter how I tried to instantiate the map (or inject it) the behavior is still the same.
It turns out the issue is that two instances of the service are created and injected one in the controller and one in the filter. It's not clear to me why this is happening and how to resolve it.
Following is an extract of the code:
#Controller
public MyController {
#Autowired
private MyService myService;
someEndpoint() {
....
myService.putData(key, value);
.....
}
}
public class MyFilter extends GenericFilterBean {
#Autowired
private MyService myService;
public void doFilter(...) {
//this is where I have a problem.
// the reference myService.myMap seems to be pointing to a different instance
// than the service.myMap in the controller which doesn't make any sense to me
// the filter obviously intercepts all requests so I would expect that after that particular
// endpoint is accessed the data will be there for subsequent requests
myService.getData(..);
}
.....
}
#Service
public class MyService {
private Map <String,String> myMap = new HashMap <String,String> ();
public String getData(String key) {
return myMap.get(key);
}
public void putData(String key, String value){
myMap.put(key,value);
}
}
Here is an extract of the app-config.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:security="http://www.springframework.org/schema/security"
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
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<context:component-scan base-package="com.mycompany.myPackage"/>
<context:annotation-config />
.......
<security:http
........
........
<security:custom-filter ref="myFilter" position="FORM_LOGIN_FILTER" />
....
...........
<bean class="com.mycompany.filters.MyFilter" id="myFilter"/>
and the web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Dispatcher Servlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Any help is greatly appreciated.
In your web.xml you set:
<servlet>
<servlet-name>Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
which creates one web application context initiated by your servlet.
Then you also have:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
which also creates a parent root web application context, in your case a duplicate one.
This scheme, properly used, favors the cases where you may have more servlets, each one defining its own isolated context but inherit bean definitions from a common root context (services, datasources etc). It also gives a good practice roadmap for creating layered contexts, i.e. prevent your service beans to have dependencies on your mvc layer.
Unless you have more than one configuration files, you should assign an empty value to the contextConfigLocation of your servlet configuration as :
<servlet>
<servlet-name>Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Be careful. Do not omit the parameter. Spring will infer some default configuration file name based on your servlet and will complain if it does not exist.
GenericFilterBean is not in an application context. I would expect java.lang.InstantiationException in the code above. You can get your bean via the filter's ServletContext. Any other instantiation trick will cause map duplication.
Are you sure that there is only one instance of MyService class created? The simplest way to check this is to provide default constructor implementation and print some text in it. Please check this and let me know, because I have some suspicions.
If this is true, and there are two instances of MyService class, there is possibility that when you put some data to map, you use instance A of MyService and when you get data from the map you use instance B of MyService... I will wait for your response to continue/stop this thinking.

Use Apache cxf with spring mvc in a single application with shared services

I'm currently working a project which based on spring MVC, it's just a standard project using spring MVC template. so I have web.xml and servlet-context.xml.
I'm working on adding Apache cxf web services into this project, and meet some problems on sharing services with existing Spring MVC.
My initial approach was trying to get web services working, so here is my web.xml looks like:
<?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
/WEB-INF/spring/jaxwsServlet/jaxwsServlet-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>
<!-- Process web service requests -->
<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/industryAspectWS</url-pattern>
</servlet-mapping>
<!-- 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 my jaxwsServlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://jax-ws.dev.java.net/spring/core
classpath:spring-jax-ws-core.xsd
http://jax-ws.dev.java.net/spring/servlet
classpath:spring-jax-ws-servlet.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<wss:binding url="/industryAspectWS">
<wss:service>
<ws:service bean="#industryAspectWS"/>
</wss:service>
</wss:binding>
<!-- Web service methods -->
<bean id="industryAspectWS" class="com.example.ws.IndustryAspectWS"></bean>
<context:component-scan base-package="com.example" />
<beans:import resource="../HibernateTransaction.xml" />
<beans:import resource="../JaxbMarshaller.xml" />
</beans>
I copied the context:component-scan beans:import sections from servlet-context.xml
This configuration works okay since I was able to boot up the server, and call Web services and also access servlet and jsp. However, I notice that since I quoted the hibernateTransaction.xml in both context xml files, there are two session factories.
I want to share all services (such as hibernate) between Apache cxf and Spring MVC controllers, so I tried to put settings in root-context.xml, it didn't work. I also tried to search this online, but didn't find any complete examples on shared services. Is it possible that we can put a setting to share services among the two?
=================================================
I had experimented some settings after I post this, and figured that if I put the lines of
<context:component-scan base-package="com.example" />
and
<tx:annotation-driven transaction-manager="txManagerExample" />
in both servlet-context.xml and jaxwsServlet-context.xml, it will work just fine. all other settings can stay in the shared root-context.xml
WSSpringServlet is not CXF. It is Metro. I would recommend using CXF. In that case you will have a CXFServlet but then you would set up CXF in your main Spring context (the one created by ContextLoaderListener.
It would work as follows: your main context would have all of the shared beans including CXF. Your Servlet context would have just your controllers. Since the servlet context is a child of the main context your controllers would also have access to everything in the main context.
See the Embedding CXF inside of Spring page, the CXF Servlet Transport Page, and my answer to this question about sharing beans between servlet context and main context.
Thanks to https://stackoverflow.com/a/30758664/2615824:
Two dispatchers (Spring MVC REST Controller and CXF JAX-WS) with one Spring Context, Java Config (no xml stuff...) example:
WebApplicationInitializer:
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(MyServiceConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.setParent(rootContext);
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("REST dispatcher", new DispatcherServlet(webContext));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/api/*");
ServletRegistration.Dynamic cxfDispatcher = servletContext.addServlet("CXF dispatcher", CXFServlet.class);
cxfDispatcher.setLoadOnStartup(1);
cxfDispatcher.addMapping("/services/*");
}
Config:
#Configuration
#ComponentScan("my.root.package")
#ImportResource(value = {"classpath:META-INF/cxf/cxf.xml"})
#PropertySource("classpath:app-env.properties")
#PropertySource("classpath:app.properties")
#EnableWebMvc
public class MyServiceConfig {
#Autowired
private Bus cxfBus;
#Autowired
private CxfEndpointImpl cxfEndpoint;
#Bean
public Endpoint cxfService() {
EndpointImpl endpoint = new EndpointImpl(cxfBus, cxfEndpoint);
endpoint.setAddress("/CxfEndpointImpl");
endpoint.setWsdlLocation("classpath:CxfService/CxfService-v1.0.wsdl");
endpoint.publish();
return endpoint;
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Sample CXF Endpoint (WSDL first):
#Component
#WebService(
endpointInterface = ".....v1_0.CxfServicePort",
targetNamespace = "http://..../service/CxfService/v1_0",
serviceName = "CxfService",
portName = "CxfServicePort",
wsdlLocation = "classpath:CxfService/CxfService-v1.0.wsdl")
#MTOM(enabled = true)
#SchemaValidation(type = SchemaValidationType.BOTH)
#InInterceptors(classes = NoBinaryContentLoggingInInterceptor.class)
#OutInterceptors(classes = NoBinaryContentLoggingOutInterceptor.class)
#EndpointProperty(key = "ws-security.callback-handler", ref = "cxfEndpointSecurityHandler")
public class CxfEndpointImpl implements CxfServicePort {
//...
}
Sample REST Controller:
#RestController
#RequestMapping(value = "/system", produces = MediaType.APPLICATION_JSON_VALUE)
public class RestController {
//...
}
CXF Endpoint deployment address:
ip:port/tomcat-context/services/CxfEndpointImpl?wsdl
Spring REST Controller deployment address:
ip:port/tomcat-context/api/system

Resources