I'm trying to develop a client for onvif which has wsdl as in:
http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
The wsdl2java runs fine and code is generated. However, because there is no element in the wsdl, it doesn't generate a service class for me to use. It only generate an interface for the element.
The webservice's endpoint URI will be different for each device where the service is provided. My question is, given that URI, how am I supposed to get an instance of the portType interface, so that I could use the interface to interact with the webservice?
Thanks
You don't really need it to create a service class to utilize the generated stub. It is possible to use something similar to the following:
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
...
protected <T> T getService(final Class<T> serviceClass, final boolean useSoap12) {
final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(serviceClass);
factory.setAddress(endpoint);
if (useSoap12) {
factory.setBindingId("http://schemas.xmlsoap.org/wsdl/soap12/");
}
return serviceClass.cast(factory.create());
}
Where serviceClass is the annotated interface CXF created.
Related
I have an http endpoint redirecting to a REST Java web service.
I am receiving a application/x-www-form-urlencoded request with some attributes embedded within the body of the request.
Inside the web service I would like to update the mule message status with those attributes.
Since RequestContext.getEventContext() is now deprecated and Doc says to implement Callable instead, however seems not working to me.The onCall method is never invoked.
Any idea ?
Below my code:
enter code here
#Path("/restClass")
public class HelloREST implements Callable{
private String industry;
private String lob;
private String nuixlegalentity;
private org.apache.log4j.Logger log = Logger.getLogger(LoadClass.class);
#POST
#Path("/setPayload")
#Consumes("application/x-www-form-urlencoded")
public void setMessage(#FormParam("industry") String industryParam, #FormParam("lob") String lobParam,#FormParam("nuixlegalentity") String nuixlegalentityParam){
log.debug("**************INSIDE SETMESSAGE******************");
industry=industryParam;
lob=lobParam;
nuixlegalentity=nuixlegalentityParam;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception{
log.debug("**************INSIDE ONCALL******************");
eventContext.getSession().setProperty("industry","industry");
eventContext.getSession().setProperty("lob",lob);
eventContext.getSession().setProperty("nuixlegalentity",nuixlegalentity);
return eventContext.getMessage();
}
}
}
I assume you're using this class as a resource with the Jersey transport. In that case, Mule will call the JAX-RS annotated methods, based on the incoming request, and thus will not call onCall. Therefore implementing Callable is of no use.
Using RequestContext.getEventContext() is the only way possible to get the EventContext in a Jersey-handled resource.
To this date, MuleSoft hasn't provided a workable replacement for cases like this one so, even if RequestContext.getEventContext() is deprecated, you unfortunately have no other choice than using it.
Am pretty new to web services and have been trying to implement Soap Faults. I used Apache Axis2 to generate webservice in the following manner.
public interface XYZ{
public String myMethod(User[] user)
}
Here I have created a User class with some variables so that I can generate User object at .Net environment to pass User[] of objects.
Public class Webservice implements XYZ
{
Public String myMethod(User[] user){
//My implementation
}
}
Now, I created a dynamic project using Eclipse and with the help of Axis2 plugin I created webservice for my "Webservice" class which generates wsdl file. I deployed the webcontent in the Tomcat folder and able to access the WSDL file in the .Net environment. I am able to pass array of objects (User[]) from .Net to Java and able to do my task. Now, I need to implement Soap Faults in Java which I am not sure how to implement.
Can anyone help me with an example or tutorial ?
Your best bet is to Google for something like "jax-ws faults". For example:
http://www.ibm.com/developerworks/webservices/library/ws-jaxws-faults/index.html
You can also implement an error handler, as discussed under "Using handlers in JAX-WS Web services" here:
http://axis.apache.org/axis2/java/core/docs/jaxws-guide.html#BottomUpService
Most frameworks will trigger a SOAP fault when you throw an Exception in the method implementing your operation. That will not give you much control on the SOAP fault content though.
See here for some details on Axis
Generally, You don't need any specific coding for implementing SOAP fault.. Whenever there is any exception thrown by the method (here myMethod in your example.), axis will automatically generate SOAPFault element in the resulting response. The exception is actually wrapped into AxisFault exception and sent to the client.
See here a i.
I get this exception when I try to call a .NET web service:
javax.xml.bind.JAXBException: class com.pixelware.mdv.tramites.TramiteXML nor any of its super class is known to this context.
The client is a Java library created with the CFX JAX-WS frontend (Classes precreated with WSDL)
The method I'm trying to call accepts (nested in another object) an Object (anyType in the WSDL)
Looks like the JAXB engine inside CXF is unable to marshall (serialize to XML) my class. That's because JAXB is unable to serialize a class if it is not registered in it's context and the class being passed it's part of the main program, not the client library.
The CXF documentation shows a lot of configuration options, and it looks like it can be done adding the property additionalContextClasses to the service properties.
I can't add this property by configuration because my client is a separated library with the CFX generated classes.
I tried to add the property programmatically with this code:
Map<String, Object> ctx = (BindingProvider)ws.getWSSoap()).getRequestContext();
ctx.put("jaxb.additionalContextClasses", new Class[] {TramiteXML.class});
But it doesn't work. Looks like maybe this configuration has to be done before creating the client.
I've also found this post, whit the same (or very similar) problem, and the proposed solutions are far from easy.
Shouldn't it be much more simple? Maybe I'm missing something.
Any suggestions?
Well, I found it.
I got it to work using the "raw" DIspatcher API that CXF provides.
I created a method like this:
public ReturnType registrar(RequestType request)
{
// That's the call that didn't worked. Registrar is the name of the method
// return serviceCLient.registrar(user, password, request);
try {
JAXBContext context = JAXBContext.newInstance(RequestType.class, ReturnType.class,
request.geGenericContent().getClass());
Dispatch<Object> registrarDispatch = service.createDispatch(
RegistroElectronico.RegistroElectronicoSoap, context, Mode.PAYLOAD);
registrarDispatch.getRequestContext().put(Dispatch.SOAPACTION_USE_PROPERTY, Boolean.TRUE );
registrarDispatch.getRequestContext().put(Dispatch.SOAPACTION_URI_PROPERTY, "http://pixelware.com/RegistroTelematico/Registrar" );
Registrar registrar = new Registrar();
registrar.setLogin(this.user);
registrar.setPassword(this.password);
registrar.setSolicitud(request);
RegistrarResponse response = (RegistrarResponse) registrarDispatch.invoke(registrar);
return response.getRegistrarResult();
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
Finally, the Dispatcher API was easier to use than I thought (Fortunately, there is a class for every web service method call).
The trick was to add my dynamic object type to the JAXBContext.
Anyway, I wonder why something like this couldn't be already done automatically by the CXF framework
I am trying to create a dynamic proxy that would wrap an EJB around a web service because the application server does not support creating an EJB based web service without a proprietary router project generation.
My thought was to create a dynamic proxy, and some how just start it using an InitServlet. Right now I am kind of stuck on figuring out how to set the annotations dynamically so that I won't get the following error.
class $Proxy0 has neither #WebSerivce nor #WebServiceProvider annotation
at com.sun.xml.internal.ws.server.EndpointFactory.verifyImplementorClass(EndpointFactory.java:277)
at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.getPrimaryWsdl(EndpointImpl.java:273)
at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:213)
at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:143)
Recently I have had the same problem. It seems that most people say is not possible. See http://softwarecarnival.blogspot.be/2009/02/java-annotations-and-proxies.html
If the interface that you have is:
interface XXXInterface{
Result doStuff1(String param1)
}
then a workaround is to create a delegator to the proxy that will also implement the web service.
#WebService
public class WebServiceDelegateToXXXServer implements XXXInterface{
public WebServiceDelegateToXXXServer(XXXInterface actualImplementor){
this.actualImplementor = actualImplementor;
}
public Result doStuff1(String param1){
return actualImplementor.doStuff1(param1);
}
}
Then you will publish
XXXInterface proxy = createProxyAsXXXInterface();
Endpoint.publish(url, new WebServiceDelegateToXXXServer(proxy));
When defining a simple web service in Java (Eclipse) and consuming the service in Visual Studio, the generated code contains a request and response structure for each service method. The generated client interface has methods that accept the request structure and return the value from the response structure.
For instance, if I have a service class SimpleTest with a method add(int a, int b), I get the following generated interface (annotations removed):
public interface ISimpleTest
{
MyNamespace.WebServiceProxy.addResponse add(
MyNamespace.WebServiceProxy.addRequest request);
}
However, if I create essentially the same class as a WCF web service, the code generates the following interface:
public interface ISimpleTest
{
int Add(int a, int b);
}
I'd like to figure out if there's a way to avoid using the wrapper classes when consuming a Java service. Would defining datatypes in an XSD allow this or will .NET always generate these wrappers when consuming a non-.NET service? We'd like to bypass the generated client and implement the interface ourselves (without the wrappers). Is this possible?
You can definitely do this using WCF. You should be able to define your interface on the client side like so:
[ServiceContract]
public interface ISimpleTest
{
[OperationContract]
int Add(int a, int b);
}
From there, you can configure the implementation of your client through the client config or through code.
If I had to guess it is because Visual Studio for an external web service (Java, Perl, Ruby, etc) needs to go download the WSDL from that service and then generate the .NET stubs based on the WSDL which is the interface of all web services.
With a WCF Web Service it already has access to the classes etc for proxying so it doesn't need to generate the stubs and skeletons to call the web service.
This is just a guess though...
The only way to do it without the wrapper is if you created all the SOAP requests responses yourself and sent them over raw HTTP to the web service. This is messy code and the whole reason the .NET wrapper generator exists to shield you from that mess!