I am using netbeans 6.9. I have made a JAX-WS service that returns a complex type, I have also made a JAX-WS client to consume it.
The JAX-WS system automaticly creates a class for the client, inferred from the WSDl spec. I want to make my own class for this using JAXB annotations, so that I can add some extra functions to it.
How do I go about replacing the autogenerated file with my own one? Could I also use the same class in the service to control how it is transmitted?
Thanks!
Why replace the generated class?
From your description, it sounds like a good case for using the Decorator design pattern.
I have done this on a JAX-RPC project, and it worked very well.
Related
As far as I got into Apache Camel, I understood that an Endpoint can be created using an URI.
from("jms:queue:myqueue").to("seda:myseda");
While I understand this pattern, I'm asking myself and you, is there a way to build those URIs using type-safe (or just safe) Java objects?
The usecase is obviously inside a custom RouteBuilder.
I know an Endpoint can also be retrieved using the endpoint method inherited from BuilderSupport
final SedaEndpoint seda = endpoint("seda:myseda", SedaEndpoint.class)
But that's just like writing the pure String.
Are there other ways to build Endpoints?
ParameterConfiguration or ComponentConfiguration classes/interfaces are deprecated, but without pointing to an alternative or saying there is none.
You can build those endpoints via plain Java with the new constructor, and then call the setter/getters. Its a bit cumbersome to do, and the vast majority of the Camel users use the URI style.
We have on the roadmap for Camel 3 to generate type-safe fluent builder for all the endpoints, for all the out of the box components, and provide this as a maven tooling plugin so 3rd party component developers can do this as well.
This is about using JAX-WS with EclipseLink MOXy and my problem of not being able to use MOXy's external mapping documents in this combination. (The same actually seems to apply to JAX-RS as well, but I'm limiting the details to JAX-WS to keep this from becoming even longer than it already is).
I first describe (in some detail) the context of my requirements and the test code I've written to try and solve them. The actual question follows at the end of the post.
The context:
In some legacy parts of our project, we use JAX-WS directly on top of a simple server-side POJO model. The model is part of an API that we use for direct Java calls, but we also provide a SOAP layer implementing the same Java interface as our direct implementation, i.e. we have an IManager interface using our model, and the caller doesn't care whether his IManager instance is the local implementation or a SOAP client that calls the JAX-WS server wrapper for the local implementation.
Back when we started implementing the model, we didn't know much about JAXB, so the model has no JAXB annotations and everything is auto-deduced by JAX-WS. From the JAX-WS annotated server classes, we create a client using wsgen and wsimport. But since the model is part of our API, and the model generated by wsimport is separate set of classes (albeit with identical signatures), we have to wrap all client calls with methods that copy between these two models. Copying from one model to the other is implemented manually and has to be updated manually for every tiny change in the API model.
Since both server and client are under our control, we'd like to use the same set of (hand-written) model classes in the server and the client implementation. I've spent the past few weeks playing around with a test project that works, but doesn't completely satisfy me yet.
I built my test project in three steps:
Step 1: Implement a simple test API consisting of a model and a manger interface. Then create a simple implementation.
In my case, the model consists mainly of and IPerson and an IBook interface, and the IModelManager has methods to get, store/update and delete persons and books. The interface also provides a factory for creating new persons and books, so client projects only need the API at compile time (and the implementation at runtime).
Step 2: Provide modules for serialization to and from XML and JSON.
Because of its support of external mapping documents, I played around with EclipseLink MOXy. This allowed me to take my model from step 1 and add XML binding declarations in my separate serialization project. I could also write my serialization utility classes in such a way that the client code calling them only knows about the API, i.e. all method signatures rely only on the model interfaces and not the implementation classes. All this without touching the classes from step 1 - all the serialization stuff was cleanly layered on top of the Java implementation project.
Step 3: Provide SOAP and REST layers via JAX-WS and JAX-RS.
Now I wrote server classes for SOAP and REST, using JAX-WS and JAX-RS annotations. From the JAX-WS classes I generated a client with wsgen and wsimport and wrapped that in a client-side IModelManager implementation which simply redirects the calls to the client class generated by wsimport. For the JAX-RS classes I used Jersey with annotations in my sever class and wrote a IModelManager implementation which uses the Jersey client classes to call the REST service.
This is where I lost some of the nice functionality from step 2.
Using the JAX-WS EclipseLink plugin, all the JAX-WS code uses MOXy for serializing and deserializing the model (or at least I think it does). But I couldn't find a way to specify my external binding files. I had to add annotations to my actual model implementation from step 1 (and even to the API, because the model also includes an enum referenced from the interfaces and the enum needs JAXB annotations as well). I also had to change my JAX-WS server class to use the model implementation classes instead of the interfaces (for now I simply use casts where necessary, assuming there will never be another model implementation).
Using the WSDL and schema generated from the updated model by wsgen, I can call wsimport with a custom JAXB bindings XML to generate a client that maps all the types from the generated XSD to my existing model classes instead of generating new ones. The result is a client interface that accepts and returns the model interfaces from my API and always uses the standard implementation. I just have to write simple wrappers and cast my model implementation classes to API interfaces in several places, which is a massive improvement over our legacy code with its duplicate (and triplicate) models and loads of copying logic.
The question:
I'm not happy with having to annotate all my model classes directly (and even the enums in the API), especially considering that I had a working serialization/deserialization pipeline without annotations in step 2. Presumably, if I could provide wsimport and the code that starts up the sever-side JAX-WS implementation with my MOXy mapping documents, I could do without any annotations just like in step 2. It even seems to me that if I could provide wsgen with the mapping files, I could use my API interfaces (instead of implementation classes) in the server-side JAX-WS methods and do without all the casts, and perhaps even without the JAXB bindings file that manually maps the wsgen created XSD types to my existing classes.
But I haven't been able to find a way to provide JAX-WS with the MOXy mappings, neither the wsgen and wsimport tools nor the client or server side code. Is there something I'm missing, or if not, is this indeed a gap in JAX-WS's MOXy bridge, and is there a chance to fill it to get the full MOXy functionality in a future version? Or did I make a fundamental error in my line of thinking and there either cannot be a solution or there already is one? (Hence my detailed description of my test project)
The target platform is plain Java 8, either as a standalone application (with Jetty, using javax.xml.ws.Endpoint to publish the SOAP service and Jersey for the REST service), or Tomcat with Jersey. My tests run directly in JUnit using Endpoints and JerseyTest, plus manual tests in Tomcat.
I want to generate service implementation from WSDL (Top down approach) in Java but I dont want to use any tool. For example If we want to create stubs we can use wsimport.
Please let me know if this is a duplicate question.
Thanks
If you don't want to use any tool to generate code or stubs, maybe you would like to use Spring WebServices. This way you only create an EndPoint able to process WS messages, that is, you only worry about implementing server logic.
With this approach you can define beans to marshalling, using jaxb2 (or another), and the EndPoint brings you functionality to receive not XML payload, but Java Objects instead.
If you don't want to genereta code or stubs, I think Spring WS is nice for you.
If you don't want to use any tool at all, then sorry for my answer, but I believed what you didn't want is to generate code.
Below is the Maven plugins which create Java from WSDL:
Axis :
Axis plugin
CXF
CXF plugin
At work, we currently have a WSDL interface as well as a semi-RESTful interface that we're looking to expand upon and take it to the next level.
The main application runs using Servlets + JSPs as well as Spring.
The idea is that the REST and WSDL are interfaces for an API that will be designed. These (and potentially other things in future) are simply a method through which clients will be able to integrate with the interface.
I'm wondering if there are any suggestions or recommendations on frameworks / methodologies, etc for implementing that under-lying API or does it make sense simply to create some Spring beans which is called either by WSDL or REST?
Hope that makes sense.
Have a look at Eunicate it is great . You are using spring , Spring has had support of SOAP for a while and Spring 3 has support of REST (Creating and Consuming).
Your approach makes sense. Probably the most important advice is to make the external API layer as thin as possible. You can use Axis, Apache CXF, Jersey, etc. to handle the implementation of the REST or SOAP protocols, but the implementation of those services should just load the passed in data into a common request object, and pass that into a separate service that handles the request and returns a response object which the external API layer will marshall into the correct format for you.
This approach works especially well when you have a competitor providing similar services and you want to make it easy for their customers to switch. You just build a new external API that mirrors the competitors, and simply translates their format to your internal api model and provided your services are functionally equivalent, you're done.
This is a really late response, but I have a different view on this topic. The traditional way as we know it is to unmarshall xml to java and marshall java to xml. However if the wsdl changes then it would effectively be a structural change in the code which would again require a deployment.
Instead of the above approach if we list the fields mentioned in the wsdl in a presistent store, load the mappings in memory and prepare our structures based on these mappings we would have to have many less changes for this..Thus IMO instead of using existing libraries a configurable approach to unmarshalling and marshalling should be taken.
I'm developing a webapp with Java backend and Flash (pure ActionScript) frontend using BlazeDS.
I'm using the RemoteObject stuff to send objects, using custom serialization, where I need to implement Externalizable (Java) and IExternalizable (AS) interfaces. This works fine so far.
But now I need to send objects from Java to Flash, whose classes are generated with JAXB/XJC. Of course these generated Java classes don't implement the Externalizable interface, so it seems that I can't use my approach here.
One possibility seems to be writing a XJC plugin which makes the classes implement Externalizable. But this looks like a tough job...
Does anyone have a good idea how to solve this problem?
A couple of options:
build a set of objects on top of your JAXB generated classes. I would choose this option.
build a proxy on top of your JAXB generated classes which will serialize/deserialize accordingly each object. If your objects are implementing the Externalizable interface you can use the Dynamic Proxy API from Java, no need for dynamic code generation
modify the blazeds distribution. I would stay away from it, but it is doable.
I finally developed a JAXB/XJC plugin. (If someone's interested, just contact me.)
Works fine now.