Spring Autorwiring on JAXWS Endpoint does not work - java

I am trying to develop a SOAP web servie using JAXWS (from JDK 7). The problem I am facing is with autowiring. I tried with SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext which was suggested in many blogs; but its not working. The autowired beans are still NULL. My environment is:
JDK: 1.7.0_75
Spring: 4.1.7.RELEASE1
JAXWS-API: 2.2.11
JAXWS-RT: 2.2.10
JAXB-API: 2.2.12
web.xml entry
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/wsApplicationContext.xml</param-value>
</context-param>
<listener>
<description>Spring Application Context listener. This must be loaded first</description>
<display-name>Spring Context Config Listener</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<description>JAX-WS Listener. This will initialize Metro web service engine</description>
<display-name>JAX-WS Listener</display-name>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>JAX-WS Servlet</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-WS Servlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
sun-jaxws.xml Entry
<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
<endpoint
name="BookService"
implementation="com.demo.ws.endpoint.BookServiceEndpointImpl"
wsdl="WEB-INF/wsdls/book-service.wsdl"
service="{http://demo.app/services/book}BookService"
port="{http://demo.app/services/book}BookServicePort"
url-pattern="/services/books" />
</endpoints>
classpath:/spring/wsApplicationContext.xml entry
<context:annotation-config />
<context:component-scan base-package="com.demo" />
<aop:aspectj-autoproxy proxy-target-class="true"/>
BookServiceEndpointImpl.java (the web service endpoint)
#WebService(endpointInterface = "com.demo.ws.artifacts.BookServicePort")
public class BookServiceEndpointImpl implements BookServicePort {
#Autowired
#Qualifier(AppConstants.BOOK_SERVICE_BEAN)
private BookService bookService;
#PostConstruct
public void init() {
logger.debug(">>>>>>>>>>>>>>>>>> PostConstruct completed...");
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
logger.debug(">>>>>> bookService --> {}", bookService);
}
// ... The endpoint methods.
}
The above log lines are printed in log file, however the bookService is printed null.
Could someone help how to solve this problem?

Related

Spring Java based configuration for Crystal Reports

Im new to spring with crystal reports I have created my application where I used some java annotation configuration. Now I am trying to integrate with crystal reports where I have to convert xml based web.xml to java based config
here is the web.xml code
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/appServlet/servlet-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/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>
<!-- crystal report in spring -->
<context-param>
<param-name>crystal_image_uri</param-name>
<param-value>/crystalreportviewers</param-value>
</context-param>
<context-param>
<param-name>crystal_image_use_relative</param-name>
<param-value>webapp</param-value>
</context-param>
<servlet>
<servlet-name>CrystalReportViewerHandler</servlet-name>
<servlet-class>com.crystaldecisions.report.web.viewer.CrystalReportViewerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CrystalReportViewerHandler</servlet-name>
<url-pattern>/CrystalReportViewerHandler</url-pattern>
<url-pattern>/faces/CrystalReportViewerHandler</url-pattern>
</servlet-mapping>
</web-app>
I have tried to mix it with java config but it fails,
Thanks in advance
To convert your basic web.xml to java configuration, either create a class by
implement WebApplicationInitializer or
extend AbstractAnnotationConfigDispatcherServletInitializer
regarding your crystal report you can create the Bean of type CrystalReportViewerServlet using #Bean Annotation.
for more information please check
- web.xml to java config
and register secondary servlet in spring
Thanks for to all who looked for a solution. I did the following
#Configuration
#ComponentScan(basePackages = { "t.g.app" })
public class ReportsConfig implements WebApplicationInitializer{
#Override
public void onStartup(ServletContext servletContext) throws ServletException{
servletContext.setInitParameter("crystal_image_uri","/crystalreportviewers");
servletContext.setInitParameter("crystal_image_use_relative", "webapp");
ServletRegistration.Dynamic crystalReportViewerHandler = servletContext
.addServlet("CrystalReportViewerHandler", new CrystalReportViewerServlet());
crystalReportViewerHandler.setLoadOnStartup(1);
crystalReportViewerHandler.addMapping("/CrystalReportViewerHandler");
}
}
There were also some security issues caused by spring security so i added some exceptions in security configuration.

Wire an existing spring ApplicationContext to REST service with JAX-RS

I could start my application with REST endpoints exposed without problem.
However, I have another spring ApplicationContext created elsewhere and would like to be accessible from my REST endpoints.
Currently, I have to use a Singleton to lookup the beans. But is there a way to wire an existing ApplicationContext?
Below is what I have.
web.xml
<web-app>
<context-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>package1.MyJaxRsApplication</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.xml
<beans>
<context:component-scan base-package="package2.rest" />
</beans>
I think u will have to package your service interfaces as a separate jar and use it on other application. Together with that you will have to define service consuming spring configuration use it in you other application
<bean name="/ExposedService.htm" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="exposedService"/>
<property name="serviceInterface" value="com.app.client.ExposedService"/>
</bean>

Initialize spring bean profile through ContextLoaderListener in web.xml

In my web.xml I'm declaring a ContextLoaderListener to configure spring application this way:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
In one of my spring configuration xml files, I'm using different beans profile for development and production.
<beans profile="production">
<bean />
</beans
<beans profile="development">
<bean />
</beans
How I could set the default beans profile in the web.xml? is there something similar to the following when using ContextLoaderListener instead of spring servlet:
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>production</param-value>
</init-param>
You can configure web.xml at the level of ContextLoaderListener with:
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>profileName</param-value>
</context-param>
and the level of DispatcherServlet with:
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>profileName</param-value>
</init-param>
Reference: http://spring.io/blog/2011/02/11/spring-framework-3-1-m1-released/

FIXED: "No mapping found" Trying to set up a RESTfull interface using Spring-MVC

This issue is solved. Someone created a file called mvc-dispatcher.xml and it had an incorrect configuration. That file is loaded automatically because it's called the same as a servlet.
I want to thank everyone who tried to help me fix this issue. I'm keeping this question here, since it actually explains how to create a REST interface. It works perfectly.
I'm trying to set up a RESTful interface with Spring-MVC. The server starts without issue, but any time I try to call the REST interface I get the message:
41 WARN [springframework.web.servlet.PageNotFound] No mapping found for HTTP request with URI [/myweb/rest/asd/aaa] in DispatcherServlet with name 'mvc-dispatcher'
It seems that the URL I am sending (http://localhost:8080/myweb/rest/asd/qwe for example) is not 'captured' by any controller. What am I doing wrong?
I do not know what else I could try. I'm using Java 1.7.0_15, Tomcat 7.0.34 and Spring 3.1.4.RELEASE
In my web.xml:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>MyWeb</display-name>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<!-- Listener for MVC spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- Servlet for MVC spring -->
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Loading web properties -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
In my applicationContext.xml:
<context:component-scan base-package="com.myweb.*" />
<context:annotation-config/>
<tx:annotation-driven/>
<mvc:annotation-driven />
And finally, my controller class:
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class RestController {
private static Logger LOG = Logger.getLogger(RestController.class);
#RequestMapping("/asd/{test}")
public void test(#PathVariable String test) {
LOG.info("You sent "+test);
}
}
Tried changing the method's #RequestMapping but still didn't work:
#RequestMapping(method=RequestMethod.GET)
public void test() {
LOG.info("You sent something");
}
Your mapping is wrong.
You are requesting /rest/asd/aaa but your mapping is for /asd/{test}.
You need to change #RequestMapping("/asd/{test}") to #RequestMapping("/rest/asd/{test}")
Or add #RequestMapping("/rest") to your controller class
Try annotate your controller class also with #RequestMapping("/rest") to handle all requests with url
/webapp/rest/
You should also configure your context via org.springframework.web.context.ContextLoaderListener listener. I think You are not loading applicationContext.xml
Add this part to your web.xml
<!--spring bootstrap listener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Apache CXF and tomcat

I am fairly new to Apache CXF and tomcat. I am trying to build a simple web service and deploy it on tomcat. below is my web.xml
However when I try to access the 'services' folder using my browser it says No services have been found. I tried creating java web service client but it is not able to locate the service either. What could be wrong in this?
<?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">
<display-name>Sample web service provider</display-name>
<listener>
<!-- For Metro, use this listener-class instead:
com.sun.xml.ws.transport.http.servlet.WSServletContextListener -->
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Remove below context-param element if using Metro -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF/cxf/cxf.xml
</param-value>
</context-param>
<servlet>
<servlet-name>WebServicePort</servlet-name>
<!-- For Metro, use this servlet-class instead:
com.sun.xml.ws.transport.http.servlet.WSServlet -->
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebServicePort</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
This means that you don't have any services exposed in your application. Your web.xml seems to be correct but I've just missed one thing, your Spring configuration. Add your Spring config location in your web.xml, for e.g.:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
Also, you have to create a class which will implement your web service interface and expose it as the CXF endpoint in your Spring applicationContext.xml configuration file. For e.g.:
<bean id="candidateImpl" class="some.pckg.CandidateImpl"/>
<jaxws:endpoint id="candidateEndpoint"
implementor="#candidateImpl"
address="/Candidate"
/>
Your CandidateImpl class should have #WebService annotation. For e.g.:
#WebService(targetNamespace = "http://something.com/ws/candidate",
portName = "CandidateService",
serviceName = "Candidate",
endpointInterface = "some.pckg.types.CandidateService",
wsdlLocation = "WEB-INF/wsdl/CandidateService.wsdl")
public class CandidateImpl implements CandidateService {
//Implementation of all methods from CandidateService.
}
If you've done everything correctly you should see that there is one service available under:
http(s)://whateverhost.com:<somePort>/SomeContextPath/services
And you should be able to get the WSDL file like this:
http(s)://whateverhost.com:<somePort>/SomeContextPath/services/Candidate?wsdl
See also:
Writing a Web Service with Spring
You need to set the spring configuration file location to make this work. You can set it as follows.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
You need to configure a servlet in your web.xml. Below an example.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/spring-ws-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
Now you need to define a file named spring-ws-servlet.xml under WEB-INF folder. Below an example of the content of spring-ws-servlet.xml, which contains the actual configuration for your web service. This depends on your logic, of course:
<?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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<context:component-scan base-package="com.sample.service"/>
<!-- JAX-WS Service Endpoint -->
<bean id="personImpl" class="com.sample.service.impl.PersonServiceImpl"/>
<jaxws:endpoint id="personEndpoint"
implementor="#personImpl"
address="/person">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true"/>
</jaxws:properties>
</jaxws:endpoint>
<!-- JAX-WS Service Endpoint End-->
</beans>
With this, you can access your web service under http://localhost:8080/services/person?wsdl
This is taken from this post. It is a tutorial about creating a Cxf service with IntelliJ Idea and Spring
https://aldavblog.wordpress.com/2015/01/22/creating-a-web-service-from-scratch-using-spring-maven-apache-cxf/

Categories