Spring + Apache CXF: SearchContextProvider not initialized - spring

I'm integrating Spring Boot with Apache CXF. Everyhthing is OK, but I cannot get the SearchContext to work inside the controllers:
#Context
private SearchContext context;
public #ResponseBody List<Users> getAll(#Context SearchContext context, #RequestParam String search){
....
}
The SearchContext is not correctly injected, as is not created by the SearchContextProvider in the package org.apache.cxf.jaxrs.ext.search.
I'm launching the CXF Servlet with this Bean:
#Bean
public ServletRegistrationBean cxfServlet() {
CXFServlet cxf = new CXFServlet();
ServletRegistrationBean registration = new ServletRegistrationBean(cxf, "/api/*");
return registration;
}
I'm using a Java-based configuration, no XML.
In an XML based configuration, it seems that this tag is required:
<jaxrs:providers>
<bean class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider"/>
</jaxrs:providers>
How can I declare the provider in a Java based configuration of the servlet?

In your main config class, add:
#ComponentScan("org.apache.cxf.jaxrs")
Since the class (SearchContextProvider) is already annotated with #Provider annotation, Spring will be able to pick it up if it is being scanned. Assuming that you are already doing component-scan on your own package, you can just add the jaxrs package like:
#ComponentScan({ "com.something", "org.apache.cxf.jaxrs" })

Related

ServletRegistrationBean not working with Spring

I'm trying to register servlets using ServletRegistrationBean in Spring (not Spring Boot) using following code:
#configuration
public class MyConfiguration {
#Bean
public ServletRegistrationBean<HttpServlet> customServlet() {
ServletRegistrationBean<HttpServlet> bean = new ServletRegistrationBean<>(new CustomServlet(), "/custom");
bean.setLoadOnStartUp(1);
return bean;
}
}
I have confirmed the bean is being created, and the servlet CustomServlet is not registered. BTW, the web.xml registers some other servlets and they are fully functional.
What could be the cause of this?
ServletRegistrationBean can only work with Spring Boot?
ServletRegistrationBean cannot mix with web.xml?
I missed something?
I googled this but couldn't find any related question.

Spring boot MessageDispatcherServlet overriding DispatcherServlet. how to skip overriding and register both DispatcherServlet?

in a single application, I m trying to use soap as well as rest web service. and each servlet is given different URI, below is the code of config class.
The question is: only soap service URL is working fine but for the rest on getting 405 error.
#EnableWs
#Configuration
public class WebServiceConfig {
#Bean
public ServletRegistrationBean RsRegistrationBean(ApplicationContext applicationContext) {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(applicationContext);
return new ServletRegistrationBean(servlet,"/rest/*");
}
#Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(
ApplicationContext context) {
MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet();
messageDispatcherServlet.setApplicationContext(context);
messageDispatcherServlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(messageDispatcherServlet,"/");
}
}
Remove your WebServiceConfig class, as both are auto-configured by Spring Boot already (as of Spring Boot 1.4). Add the following to your application.properties
spring.mvc.servlet.path=/rest
spring.webservices.path=/
Now you leverage the Spring Boot proivded infrastructure instead of fighting with it.

Avoid automatic servlet mapping for a Servlet created as a #Bean in Spring Boot

I have a servlet to which I need to supply dependencies via autowiring (it's a class from an external library, I cannot change its code). I try to register it as a bean and later register it using programmatic registration (ServletContextInitializer). Here is what I have:
#Configuration
public class MyConfiguration {
#Bean
public MyServlet myServlet() {
return new MyServlet();
}
}
Also, SpringMVC-related autoconfiguration creates a usual DispatcherServlet and maps it at /.
When I try to start the application, I get the following:
Caused by: java.lang.IllegalStateException: Multiple servlets map to path /: dispatcherServlet[mapped:JAVAX_API:null],myServlet[mapped:JAVAX_API:null]
So it looks like Spring Boot (or Spring itself?) automatically maps the servlet at the default /. I would like to avoid the mapping at all as I just need to create the servlet instance; I will register it myself later.
Can this be done?
you should use a ServletRegistrationBean then you can provide an extra mapping
#Bean
public MyServlet myServlet() {
return new MyServlet();
}
#Bean
public ServletRegistrationBean myServletRegistration(MyServlet myServlet) {
    ServletRegistrationBean registration = new ServletRegistrationBean(myServlet,
"/myservlet/*");
registration.setLoadOnStartup(1);
    return registration;
}

Java configuration for SAAJInInterceptor and WSS4JInInterceptor beans

I have a web application that provides a soap web service using apache cxf and spring boot. So I have no xml file in my classpath to configure my beans, they are all configured in java configuration.I would like to set up authentication with ws-security from cxf.
So I would like to know if there are java configurations for the SAAJInInterceptor and WSS4JInInterceptor beans for example like this:
#Bean
public ServletRegistrationBean cxfServlet() {
ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*");
servlet.setLoadOnStartup(1);
return servlet;
}
You just have to add the interceptor when you create your endpoint :
Map<String,Object> interceptorConfig = new HashMap<String,Object>();
// set the properties of you WSS4J config
// ...
WSS4JInInterceptor myInterceptor = new WSS4JInInterceptor(interceptorConfig);
myEndpoint.getInInterceptors().add(myInterceptor);
Another solution is by using annotation with #InInterceptors

Ldap Query - Configuration using Spring Boot

I have a Spring boot application that needs to perform LDAP queries. I'm trying to take the following recommendation from the Spring boot documentation:
"Many Spring configuration examples have been published on the
Internet that use XML configuration. Always try to use the equivalent
Java-base configuration if possible."
In a Spring XML configuration file, I would have used:
<ldap:context-source
url="ldap://localhost:389"
base="cn=Users,dc=test,dc=local"
username="cn=testUser"
password="testPass" />
<ldap:ldap-template id="ldapTemplate" />
<bean id="personRepo" class="com.llpf.ldap.PersonRepoImpl">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
How would I configure this using a Java-based configuration? I need to be able to change URL, base, username, and password attributes of ldap:context-source without a code rebuild.
The <ldap:context-source> XML tag produces an LdapContextSource bean and the <ldap:ldap-template> XML tag produces an LdapTemplate bean so that's what you need to do in your Java configuration:
#Configuration
#EnableAutoConfiguration
#EnableConfigurationProperties
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
#ConfigurationProperties(prefix="ldap.contextSource")
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
return contextSource;
}
#Bean
public LdapTemplate ldapTemplate(ContextSource contextSource) {
return new LdapTemplate(contextSource);
}
#Bean
public PersonRepoImpl personRepo(LdapTemplate ldapTemplate) {
PersonRepoImpl personRepo = new PersonRepoImpl();
personRepo.setLdapTemplate(ldapTemplate);
return personRepo;
}
}
To allow you to change the configuration without a rebuild of your code, I've used Spring Boot's #ConfigurationProperties. This will look in your application's environment for properties prefixed with ldap.contextSource and then apply them to the LdapContextSource bean by calling the matching setter methods. To apply the configuration in the question, you can use an application.properties file with four properties:
ldap.contextSource.url=ldap://localhost:389
ldap.contextSource.base=cn=Users,dc=test,dc=local
ldap.contextSource.userDn=cn=testUser
ldap.contextSource.password=testPass

Resources