Reputation: 257
I am trying to do a simple SOAP webserver with Clojure and jax-ws
(ns test-ws.routes.home
(:import (javax.jws WebMethod WebService)
(javax.xml.ws Endpoint)))
(defprotocol Calculator (add [this a b]))
(deftype ^{WebService {:targetNamespace "test.seltzer" }}
CalcWeb [] Calculator (^{WebMethod []} add [this a b] (+ a b)))
(def endpoint (Endpoint/publish "http://localhost:8080/calcWeb" (CalcWeb.)))
After that WSDL is available at http://localhost:8080/calcWeb?wsdl
but when I am trying to call it from SOAP-UI I got:
com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to java.lang.Number
My idea was that clojure cannot map SOAP request to number so I added annotation
(defprotocol Calculator (add [this ^Integer a ^Integer b]))
(deftype ^{WebService {:targetNamespace "test.seltzer" }}
CalcWeb [] Calculator (^{WebMethod []} add [this ^Integer a ^Integer b] (+ a b)))
Now on compile time I have the following error: Can't find matching method: add, leave off hints for auto match.
I also tried this
(defprotocol Calculator (add [this ^Integer a ^Integer b]))
(deftype ^{WebService {:targetNamespace "test-ws.routes.home"}}
CalcWeb [] Calculator (^{WebMethod []} add [this
#^{WebParam {:name "param0"} :tag Integer} a
#^{WebParam {:name "param1"} :tag Integer} b] (+ a b)))
I gave me same error.
Am I missing something ?
Upvotes: 2
Views: 1564
Reputation: 83
Looks like you were using my code in the example from Japila's blog. I've posted my full source with directions:
https://gist.github.com/seltzer1717/f67e77bb5b47d08612fd7f636832a4ff
Upvotes: 0
Reputation: 257
I really was close to solve the problem. The trick was to use interface instead of protocol. I hope that this will be useful for some one:
(ns wstest.core
(:import (javax.jws WebMethod WebService WebParam)
(javax.xml.ws Endpoint)
(wstest.java Person)))
(definterface IFooService
(^int add [^int a ^int b])
(^String sayHi [^String name])
(^wstest.java.Person makePerson [^String firstName ^String lastName])
(^String sayHiTo [^wstest.java.Person person]))
(deftype ^{WebService {:targetNamespace "o.m.g"}} FooService []
IFooService
(^int ^{WebMethod []} add [this ^int #^{WebParam {:name "a"}} a ^int #^{WebParam {:name "b"}} b]
(int (+ a b)))
(^String ^{WebMethod []} sayHi [this ^String #^{WebParam {:name "name"}} name]
(str "Hello, " name "!"))
(^wstest.java.Person ^{WebMethod []} makePerson [this ^String #^{WebParam {:name "firstName"}} firstName ^String #^{WebParam {:name "lastName"}} lastName]
(doto (wstest.java.Person.)
(.setFirstName firstName)
(.setLastName lastName)))
(^String ^{WebMethod []} sayHiTo [this ^wstest.java.Person #^{WebParam {:name "person"}} person]
(str "Hello, " (.getFirstName person) " " (.getLastName person) "!")))
(def endpoint (atom nil))
(do
(if-not (nil? @endpoint)
(.stop @endpoint))
(reset! endpoint (Endpoint/publish "http://localhost:8080/fooService" (FooService.))))
Person.java:
package wstest.java;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Person")
public class Person {
@XmlElement
protected String firstName;
@XmlElement
protected String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String value) {
this.firstName = value;
}
public String getLastName() {
return lastName;
}
public void setLastName(String value) {
this.lastName = value;
}
}
Upvotes: 1