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!
Related
The only web services I've ever integrated with or used have been RESTful. I'm now trying to integrate with a 3rd party SOAP service and am awe-struck at how seemingly convoluted SOAP appears to be.
With REST, I use a JAX-RS client called Jersey that makes hitting RESTful endpoints a piece a' cake. For instance, if a service is exposing a POST endpoint at http://api.example.com/fizz (say, for upserting Fizz objects), then in Jersey I might make a service client that looks like this (pseudo-code):
// Groovy pseudo-code
class Fizz {
int type
boolean derps
String uid
}
class FizzClient {
WebResource webResource = initAt("https://api.example.com")
upsertFizz(Fizz fizz) {
webResource.path("fizz").post(fizz)
}
}
But Java-based SOAP clients seem, at first blush, to be fairly more complicated. If I understand the setup correctly, the general process is this:
Obtain an XML document called a WSDL from the service provider; this appears to be a language-agnostic description of all the available endpoints
Run a JDK tool called wsimport on the WSDL which actually generates Java source code, which implements JAX-WS APIs and actually represents my SOAP client
Import those generated source files into my project and use them
First off, if anything I have said about this process is incorrect, please begin by correcting me! Assuming I'm more or less correct, what I don't understand is: why is this necessary if its all an HTTP conversation? Why couldn't I achieve SOAP-based conversations with Jersey, and bypass all this source-generation boilerplate?
For instance, say the same endpoint exists, but is governed by SOAP:
class FizzClient {
WebResource webResource = initAt("https://api.example.com")
FizzSerializer serializer // I take Fizz instances and turn them into XML
FizzDeserializer deserializer // I take XML and turn them into Fizz instances
upsertFizz(Fizz fizz) {
String xmlFizz = serializer.serialize(fizz)
webResource.path("fizz").post(xmlFizz)
}
}
If I understand SOAP correctly, its just a way of utilizing HTTP verbs and request/response entities to send app-specific messages around; it's an HTTP "conversation". So why couldn't I hijack a REST framework like Jersey to HTTP POST messages, and in doing so, bypass this SOAP overhead?
This is going to attract opinion-based answers, but first, you should understand that
jax-rs is much younger than jax-ws (jax-ws had a final draft in 2006, JAX-RS came out in 2008-9).
RESTful webservices standard, for many purposes is quite amorphous - many businesses prefer the comfort of a contract in the form of a WSDL.
Not to mention that JAX-WS, in concert with WS-I provides many other standards that govern security, message reliability and other enterprise-goodies (under the generic "WS-*" banner) that businesses care about. There's a hodge-podge of libraries that are attempting to get that kind of uniformity on to the jax-rs platform, but for now, jax-ws/WS-I is the industry standard
I have a collection of stateless scala/Java APIs, which might look like:
class UserService {
def get(id: UserIDType): User { ... }
def update( user:User): User { ... }
...
}
where User has a set of inspectable bean properties. I'd like to make these same APIs not only available over HTTP (which I know how to do), but also other, more performant non-HTTP protocols (ideally also running in the same process as the HTTP server). And more importantly, automate as much as possible including generation of client APIs that match the original Java API, and the dispatching of method calls following network requests.
I've found Spring's guide on remoting
However, this looks limited to HTTP (text not binary). What I'd really love is a library/other method that:
lets me scan for registered/annotated services and describes methods and parameters as data
lets me easily dispatch method calls (so that I'm in control of the sockets, communication protocols and whatnot and can chose a more performant one than HTTP).
i.e. the kinds of things that Spring's DispatcherServlet does internally, but without the HTTP limitations.
Ideas?
Background
I'd like to make a set of stateless service API calls available as network services with the following goals:
Some of the APIs should be available as REST calls from web pages/mobile clients
A superset of these APIs should be available internally within our company (e.g. from C++ libraries, python libraries) in a way that is as high-performance (read low-latency) as possible, particularly when the service and client are:
co-located in the same process, or
co-located on the same machine.
automate wrapper code for the client and server. If I add a method a service API, or and an attribute to a class, no-one should have to write additional code in client or server. (e.g. I hit a button and a new client API that matches the original Java/scala service is auto-generated).
(1) is easily achievable with Spring MVC. Without duplication of classes I can simply markup the service: (i.e. service is also a controller)
#Controller
#Service
#RequestMapping(...)
class UserService {
#RequestMapping(...)
def get(#PathVariable("id") id: UserIDType): User { ... }
#RequestMapping(...)
def update( #RequestBody user:User): User { ... }
...
}
With tools like Swagger (3) is easily achievable (I can trivially read the Swagger-generated JSON spec and can auto-generate C++ or Python code that mimics the original service class, it's methods, parameter names and the POJO parameter types).
However, HTTP is not particularly performant, so I'd like to use a different (binary) protocol here. Trivially, I can use the this same spec to generate a thrift .idl or even directly generate client code to talk Thrift/ProtocolBuffers (or any other binary protocol) while also providing to the client an API that looks just like the original Java/scala one.
Really -- the only tricky part is getting a description of the service method and then actually dispatching a method calls. So -- are there libraries to help me do that?
Notes:
I'm aware that mixing service and controller annotations disgusts some Spring MVC purists. However, my goal really is to have a logical API, and automate all of the service embodiments of it (i.e. the controller part is redundant boilerplate that should be auto-generated). I'd REALLY rather not spend my life writing boilerplate code.
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've written an an API giving some methods like
runApp();
stopApp();
doSomethingElse();
currently I have a jar file with which I run these methods.
I want to be able to invoke these method by http.
For example, going to : http://localhost:8080/something/runApp
will invoke runApp() method.
I've heard that this should be done with webservices, and particularly REST API.
Is webservices the only way to achieve this?
And if so, can someone summarize the simplest ways to implement this ability, or point me to an existent summary?
Thanks.
Here's a RESTful API example based on your pseudocode, with JAX-RS:
#Path("/something")
public class MyApp {
#GET
#Path("/runApp")
public Response runApp() {
return Response.ok("Running app").build();
}
#GET
#Path("/stopApp")
public Response stopApp() {
return Response.ok("Stopping app").build();
}
#GET
#Path("/doSomethingElse") {
return Response.ok("Doing something else").build();
}
}
Which when built and deployed into any JEE5 or JEE6 web capable container will allow you to access services those services at:
http://localhost:8080/something/runApp
http://localhost:8080/something/stopApp
http://localhost:8080/something/doSomethingElse
Assuming your server is running on localhost:8080, of course. Having said that, nothing in this example is really RESTful, and would be better implemented using JAX-WS.
You've pretty much described exactly what a web service is. Code gets run when you hit a particular URL with a particular type of request.
As to how to build a web service in Java, there's a huge amount of documentation out there on the web (and SO) on that. You should not have any trouble finding useful articles.
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));