How can I access the ApplicationContext from within a JAX-WS web service?
Asked Answered
S

5

10

Similar to How can I access the ServletContext from within a JAX-WS web service?, is there a way to access applicationContext, easier than this?

import javax.annotation.Resource;
import javax.jws.WebService;
import javax.servlet.ServletContext;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

@WebService
public class MyWebService {
    // boilerplate code begins :(

    @Resource
    private WebServiceContext context;
    private WebApplicationContext webApplicationContext = null;

    /**
     * @return
     * @throws IllegalStateException
     */
    private WebApplicationContext getWebApplicationContext()
            throws IllegalStateException {
        if (webApplicationContext != null)
            return webApplicationContext;
        ServletContext servletContext =
                (ServletContext) context.getMessageContext().get(
                        MessageContext.SERVLET_CONTEXT);
        webApplicationContext =
                WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
        return webApplicationContext;
    }
}
Steatopygia answered 2/3, 2009 at 13:16 Comment(0)
B
1

I don't think that the web service should have to know about web or servlet contexts or its application context. I don't see why it should have to know any of that. Shouldn't it be far more passive? Inject what it needs and let it do its work. The service interactions with a client should be based on a contract defined up front. If it has to get unknown values from a context of some kind, how will clients know what needs to be set or how to set it?

I'd go further and say that a web service should be a wrapper for a Spring service interface. It's just one more choice among all the possible ways to expose it. Your web service should do little more than marshal and unmarshal the XML request/response objects and collaborate with Spring services.

Bufordbug answered 2/3, 2009 at 14:8 Comment(6)
Well, then how can I collaborate with Spring services, if I cannot say: appContext.getBean('myBean')?Steatopygia
Inject it in via setter or constructor. Dependency injection means "don't call us; we'll call you." Your objects don't have to have the app context to get what they need.Bufordbug
You cannot. If I test my web service under glassfish, a new webservice is created, and it is not configured :-o That was a one-day-long debugging to get this knowledge :(Steatopygia
I'm writing Spring web services that I'm deploying under WebLogic, and I don't have to supply the application context. They're working fine for me - SOAP UI clients have no problems working with them. I think you're doing something else wrong.Bufordbug
So, you autowired the required beans in your Service class?Steatopygia
Boy, a simple example of what you mean would be really helpful.Subroutine
G
8
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;


@WebService( 
    endpointInterface = "Bla", 
    targetNamespace = "http://bla/v001", 
    wsdlLocation = "WEB-INF/wsdl/bla.wsdl",    
    serviceName = "BlaService",
    portName = "BlaPort")
public class BlaWs extends SpringBeanAutowiringSupport implements BlaPort {

  @Autowired
  @Qualifier("dao") 
  private Dao dao;
  ...
}
Grammalogue answered 3/12, 2009 at 1:8 Comment(2)
+1 Thanks for pointing me in the direction of SpringBeanAutowiringSupport. I had been struggling with getting Glassfish to relinquish its management of JAX-WS and letting Spring to it. This is a much easier solution and lets Spring stay focused on the things that it is good at.Headdress
I've been trying to get the solution to work but SpringBeanAutowiringSupport just doesn't seem to have an effect on my web service. #12869514Majuscule
B
1

I don't think that the web service should have to know about web or servlet contexts or its application context. I don't see why it should have to know any of that. Shouldn't it be far more passive? Inject what it needs and let it do its work. The service interactions with a client should be based on a contract defined up front. If it has to get unknown values from a context of some kind, how will clients know what needs to be set or how to set it?

I'd go further and say that a web service should be a wrapper for a Spring service interface. It's just one more choice among all the possible ways to expose it. Your web service should do little more than marshal and unmarshal the XML request/response objects and collaborate with Spring services.

Bufordbug answered 2/3, 2009 at 14:8 Comment(6)
Well, then how can I collaborate with Spring services, if I cannot say: appContext.getBean('myBean')?Steatopygia
Inject it in via setter or constructor. Dependency injection means "don't call us; we'll call you." Your objects don't have to have the app context to get what they need.Bufordbug
You cannot. If I test my web service under glassfish, a new webservice is created, and it is not configured :-o That was a one-day-long debugging to get this knowledge :(Steatopygia
I'm writing Spring web services that I'm deploying under WebLogic, and I don't have to supply the application context. They're working fine for me - SOAP UI clients have no problems working with them. I think you're doing something else wrong.Bufordbug
So, you autowired the required beans in your Service class?Steatopygia
Boy, a simple example of what you mean would be really helpful.Subroutine
D
1

Make your web service bean extend a spring bean.

like this

Dyeing answered 20/8, 2009 at 14:23 Comment(0)
A
0

I would install a Filter that saves ServletContext before chaining in a ThreadLocal

Appulse answered 2/3, 2009 at 13:31 Comment(0)
B
0

According to the JavaDoc for the SpringBeanAutowiringSupport class, see: http://docs.spring.io/autorepo/docs/spring-framework/3.0.x/api/org/springframework/web/context/support/SpringBeanAutowiringSupport.html

Read the NOTE: at the end of the javadoc.

The original question, may in fact, be the way that this should be implemented.

Ballentine answered 3/9, 2014 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.