consuming a web service - JaxWsPortProxyFactoryBean or Controller not configured right

5.7k Views Asked by At

Java 1.7 Spring 3.1.1 with Spring-WS 2.1.1 Joda Hibernate 3.6 MySQL 5.0.57 Maven 3 Tomcat 7 Eclipse 3.7

So the SOAP web service is up and running.

And my standalone Java app can access it.

Now I'm trying to build a Spring MVC web client to access it. So by my way of thinking I can just replace the standard webapp's service layer with the web service endpoint .

Patterning after this http://ankeetmaini.wordpress.com/2013/03/04/jax-ws-client-consuming-the-jax-ws-webservice after switching his naming conventions to be more canonical I wound up with

FormsEndpointImplService

@WebServiceClient(name = "FormsEndpointImplService", 
                  wsdlLocation = "http://localhost:8080/dept_forms_webservice/formsService?wsdl",
                  targetNamespace = "http://endpoint.web.forms.azdeq.gov/") 
public class FormsEndpointImplService extends Service
{
    public final static URL WSDL_LOCATION;

    public final static QName SERVICE = new QName("http://endpoint.web.forms.azdeq.gov/", "FormsEndpointImplService");
    public final static QName FormsEndpointImplPort = new QName("http://endpoint.web.forms.azdeq.gov/", "FormsEndpointImplPort");
    static {
        URL url = null;
        try {
            url = new URL("http://localhost:8080/dept_forms_webservice/formsService?wsdl");
        } catch (MalformedURLException e) {
            java.util.logging.Logger.getLogger(FormsEndpointImplService.class.getName())
                .log(java.util.logging.Level.INFO, 
                     "Can not initialize the default wsdl from {0}", "http://localhost:8080/dept_forms_webservice/formsService?wsdl");
        }
        WSDL_LOCATION = url;
    }

    public FormsEndpointImplService(URL wsdlLocation) {
        super(wsdlLocation, SERVICE);
    }

    public FormsEndpointImplService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public FormsEndpointImplService() {
        super(WSDL_LOCATION, SERVICE);
    }

    //This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
    //API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
    //compliant code instead.
    public FormsEndpointImplService(WebServiceFeature ... features) {
        super(WSDL_LOCATION, SERVICE, features);
    }

    //This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
    //API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
    //compliant code instead.
    public FormsEndpointImplService(URL wsdlLocation, WebServiceFeature ... features) {
        super(wsdlLocation, SERVICE, features);
    }

    //This constructor requires JAX-WS API 2.2. You will need to endorse the 2.2
    //API jar or re-run wsdl2java with "-frontend jaxws21" to generate JAX-WS 2.1
    //compliant code instead.
    public FormsEndpointImplService(URL wsdlLocation, QName serviceName, WebServiceFeature ... features) {
        super(wsdlLocation, serviceName, features);
    }

    /**
     *
     * @return
     *     returns FormsEndpoint
     */
    @WebEndpoint(name = "FormsEndpointImplPort")
    public FormsEndpoint getFormsEndpointImplPort() {
        return super.getPort(FormsEndpointImplPort, FormsEndpoint.class);
    }

    /**
     * 
     * @param features
     *     A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns FormsEndpoint
     */
    @WebEndpoint(name = "FormsEndpointImplPort")
    public FormsEndpoint getFormsEndpointImplPort(WebServiceFeature... features) {
        return super.getPort(FormsEndpointImplPort, FormsEndpoint.class, features);
    }
}

FormsEndpoint ( the SEI )

@WebService(targetNamespace = "http://endpoint.web.forms.azdeq.gov/", name = "FormsEndpoint")
@XmlSeeAlso({ObjectFactory.class})
public interface FormsEndpoint
{
    @RequestWrapper(localName = "insertCompletedForm", targetNamespace = "http://endpoint.web.forms.azdeq.gov/", className = "gov.azdeq.forms.web.endpoint.InsertCompletedForm")
    @WebMethod
    @ResponseWrapper(localName = "insertCompletedFormResponse", targetNamespace = "http://endpoint.web.forms.azdeq.gov/", className = "gov.azdeq.forms.web.endpoint.InsertCompletedFormResponse")
    public void insertCompletedForm(
        @WebParam(name = "arg0", targetNamespace = "")
        gov.azdeq.forms.web.endpoint.CompletedForm arg0
    );
....    

}

and my servlet-context.xml

...
<bean id="formsWebServiceProxy" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
    <property name="wsdlDocumentUrl"  value="http://localhost:8080/dept_forms_webservice/formsService?wsdl"/>
    <property name="serviceInterface" value="gov.azdeq.forms.web.endpoint.FormsEndpoint"/>
    <property name="serviceName"      value="FormsEndpointImplService"/>
    <property name="portName"         value="FormsEndpointImplPort"/>
    <property name="namespaceUri"     value="http://endpoint.web.forms.azdeq.gov/"/>
    <!-- <property name="endpointAddress" value="http://endpoint.web.forms.azdeq.gov/" />   -->
</bean>

<bean id="baseController"             class="gov.azdeq.forms.web.controller.BaseController">
  <property name="service"            ref="formsWebServiceProxy" />
</bean>

...

and Base Controller

@RequestMapping
@Controller
public class BaseController
{
    private static final Logger logger = Logger.getLogger( BaseController.class);

    @Resource 
    FormsEndpoint service; // should come in from bean
    ...
}

So this all compiles and deploys to Tomcat just fine. But when I click on dept_forms_webclient in localhost:8080/manager it throws this:

org.springframework.beans.NotWritablePropertyException: Invalid property 'service' of bean class [gov.azdeq.forms.web.controller.BaseController]: Bean property 'service' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

Seems like the proxy bean is being injected ok, it seems like I should not be setting it to FormsEndpoint regardless of what various tuts say.

So, more configuration confusion, can anyone spot what's wrong here?

TIA,

Still-learning Stev

1

There are 1 best solutions below

0
On

I got it all working by losing the dependency-injection in the context file and using @Autowired in the controller like so:

<!-- controllers -->      
<bean id="baseController"                   class="gov.azdeq.forms.web.controller.BaseController" />

and

@RequestMapping
@Controller("baseController")
public class BaseController
{
    @Autowired
    @Resource(name="formsWebServicePortProxy")
    FormsEndpoint   formsWebServicePortProxy;

Not sure why using @Autowired works but manual property injection does not. Huh.

Thanks to all who replied, it did give me a bit of insight.

CASE CLOSED

Still-learning Steve