Generating java files from WSDL - test vs prod WSDL - java

I am developing integration with local delivery service and they gave me URL to WSDL files.
One points to test environment and other to the production environment.
test: http://tsteportal.posta.si/Services/eSpremnica.Wcf/eOddaja.svc
production: https://eportal.posta.si/Services/eSpremnica.Wcf/eOddaja.svc
I would like to know if I really need to generate java files from both, or simply put, when deploying application to production, do I really need to generate files from production WSDL?
Isn't there any way to just change endpoint from test to production?
I've also noticed that generated files from Eclipse and wsimport are not the same, for example using Eclipse, it doesn't generate ObjectFactory class.

You can use the same artifacts generated for both services if the only difference is the endpoint.
Example:
import java.net.URL;
public class Main {
public static void main(String[] args) throws Exception{
URL qaWsdl = new URL("http://tsteportal.posta.si/Services/eSpremnica.Wcf/eOddaja.svc");
URL prodWsdl = new URL("https://eportal.posta.si/Services/eSpremnica.Wcf/eOddaja.svc");
boolean isQA = Boolean.valueOf(args[0]);
//Pass whichever WSDL endpoint you need
EchoService service = new EchoService((isQA) ? qaWsdl : prodWsdl);
Echo port = service.getEchoPort();
}
}

Related

creating a simple SOAP server

I have a Java project which talks to a SOAP server. I need to debug my application on my local machine. I do not want my application to get connected to the main SOAP server. I need to have a fake SOAP web server to which my application gets connected.
I want it to be as simple as possible. So, I want the server to returns a specific response for any request it receives! Is there any way by which I can reach my goal?
You don't have to build a real server for testing/debuging your code.
you can use a Mock.
This way:
you don't change your real code,
the testing code is reusable,
you don't need to implement logic, just tell it what is the expected call results
you test only your own class (there might be bugs in the soap server)
The most popular mocking framework is Mockito.
It can be as simple as:
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
#Test
public void test1() {
// create mock
MyClass test = mock(MyClass.class);
// define return value for method createSoapCall()
when(test.createSoapCall()).thenReturn(43);
// use mock in test....
assertEquals(test.createSoapCall(), 43);
}
tutorial:
http://www.vogella.com/tutorials/Mockito/article.html
official site:
http://site.mockito.org/

wsdl file location path setup in java

I'm using wsdl files to generate client & is working fine on my local server since the generated files have path like "C:\path\to\wsdl\Air.wsdl"
I'm trying to replace all the paths as above to the one that work on live server I've found some hints but I'm not so sure how to implement it (I'm new to web services).
Below is how my files currently look like
#WebServiceClient(name = "AirService",
wsdlLocation = "file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl",
targetNamespace = "http://www.travelport.com/service/air_v33_0")
static {
URL url = null;
try {
url = new URL("file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl");
} catch (MalformedURLException e) {
java.util.logging.Logger.getLogger(AirService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl");
}
WSDL_LOCATION = url;
}
This seems to be like it should be changed (I'm not sure about that, found it on googling)
#WebServiceClient(name = "AirService",
wsdlLocation = "classpath:wsdl/air_v33_0/Air.wsdl",
targetNamespace = "http://www.travelport.com/service/air_v33_0")
static {
URL url = AirService.class.getClassLoader().getResource("wsdl/air_v33_0/Air.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(AirService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:wsdl/air_v33_0/Air.wsdl");
}
WSDL_LOCATION = url;
}
But I actually don't understand how that method works.. Can someone please make me understand how can I change the path and where to place the wsdl files in the project so that it works properly on the live server and also the difference between both the codes.
Also I don't want to generate every-time when build is created, I want to generate the files (that are already been generated), place the wsdl somewhere in the project folder from where it can be accessed and then change the path in the Java files (by replacing all the paths at once) as in the above codes.
Few intro points for you:
Wsdl file contains description webmethods callable on the server (in general method names, their input parameters and its types and types of results of this methods). Therefore wsdl file is like contract between client and server - client knows what methods to call on the server, what parameters it will need to send with method name, and what type of result it can expect.
You can download and store wsdl file from server, and then use it for generation of special client class(es) (called stubs). This classes have java methods 1 to 1 corresponding to web service methods described in wsdl file. Source code of these classes is generated automatically by special tool (wsimport) which reads content of wsdl file and generate corresponding methods. From your perspective as developer of client, it is then very simple - you need only in some way create instance of this class (giving it url of wsdl file on the server) and call it's method like you call any other Java class method. (Generated implementation code of this methods cares for serialization of inputs and sending of webservice request to server, and then deserialization of response back to you, so you will obtain normal Java object as a result of call).
Maybe you now ask, why you need to set url to server's wsdl file before call of webservice method. Answer is that client code before calling your webservice automatically download's wsdl from the server and check's if it does not change meantime (if yes it does not call webservice and throws error). It sometimes happen that developer of server changed e.g. parameters of webservice method and you as client developer have still old version of wsdl, therefore validation aspect of this technology saves you a lot of time.
Now real examples:
Look at JAX-WS deployment best practice: WSDL location and client generation question to see client code how webservice method (hello) is called using HelloWorldPOCImpl stub class.
For server side implementation you need only two annotation #Webservice and #WebMethod, please look at chapter 3.1 to see example: https://metro.java.net/getting-started/building-a-simple-metro-application.html
For server, you dont need to create wsdl file manually, server generates wsdl file automatically - based on your code and mentioned annotations.

Publishing multiple Endpoints with built-in Java JAX-WS web server

So I have 2 implementations, Impl1 and Impl2, of a web service interface class. I would like to publish both under the same domain and port but with different URLS:
http://some.domain.asd/ws1 and http://some.domain.asd/ws2
Apparently, I should be able to create a configuration where I have 2 Endpoints, one for each implementation, bound to a single web server instance.
Note that I am not deploying but using the Java 7 internal publishing mechanism.
I noticed that instead of calling
Endpoint.publish(URL, new Implementor());
to directly publish a web service, I can call
Endpoint ep = Endpoint.create(new Implementor());
ep.publish(serverContext);
to publish the Implementor at a specific serverContext. What exactly is such a serverContext and how do I use it? I noticed that the publish method instantiates a javax.xml.ws.spi.Provider class and uses it for publishing purposes. But that is apparently not what I am looking for. Ideally, I would like a solution that resembles something like this:
Object serverContext = new Server(URL);
Endpoint impl1 = Endpoint.create(new Impl1());
Endpoint impl2 = Endpoint.create(new Impl2());
impl1.publish(serverContext);
impl2.publish(serverContext);
Can this even be done with the built-in publishing system, maybe using EndpointReferences objects? Or am I required to use a web service container to deploy my Endpoints seperately?
Publishing multiple Endpoints running on the same port could be achieved with this code :
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
Endpoint.publish("http://localhost:8888/ws/send", new SendServiceImpl());
Endpoint.publish("http://localhost:8888/ws/send23", new SendServiceImpl());
}
}
Running this locally in Eclipse it works , but when you deploy it to another server its broken.
To fix this you can either use http://0.0.0.0:8888 instead of localhost or the correct internal ip-address of the server.
You find it running:
windows: ipconfig
unix: ifconfig
It looks something like this: 192.168.100.55.
I stumbled across this problem today; I kept getting "java.net.BindException: Address already in use" when publishing two different endpoints to the same host+port. The solution is to instantiate the HttpServer yourself and "bind" each endpoint to this server:
package mypackage;
import com.sun.net.httpserver.HttpServer;
import javax.xml.ws.Endpoint;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
public static void main(String[] args) throws IOException {
final HttpServer httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 8080), 16);
final Endpoint fooEndpoint = Endpoint.create(new FooImpl());
fooEndpoint.publish(httpServer.createContext("/Foo"));
final Endpoint barEndpoint = Endpoint.create(new BarImpl());
barEndpoint.publish(httpServer.createContext("/Bar"));
httpServer.start();
}

Java web service client + Axis + Eclipse + Tomcat

I'm new to java web services.
Now i'm trying to create a web service client to access a WSDL based web service. So using eclipse i generated the required client stubs/Binding stubs/Port/Port proxy/ServiceLocator etc.
According to my understanding next step is to create a class with the main method to invoke it. Can anyone help me to write that piece of code or at least some links to refer?
EDITED
Thank you so much for the hint #pavan-kumar. Finally i come up with following code and it works. Thanks again.
package clients;
import requiredClasses;
public class TestClient {
public static void main(String args[]) throws Exception
{
TestPortProxy tProxy = new TestPortProxy();
RequestEntity rEntity = new RequestEntity();
rEntity.setAttribute1(100);
rEntity.setAttribute2("value1");
tProxy.webServiceAction(rEntity);
}
}
You already generated required client files with the WSDL ,so next create your own class in that create an object for proxy class which is generated by WSDL, by using that object you can call web service methods in your application.

Axis2 Web Service Client Generation - Types without modifying the client

Is it possible with Axis2 and Eclipse to generate a Web Service client and have it use java types that you already have in packages instead of creating it's own types. Reason being of course if I have type A already created and it creates it's own Type A I can't just assign variable of type A to variable of type B.
The wsdl is being generated from a Web Service deployed to an application server.
If it's not possible to generate it from that would it be possible to generate a client from the already existing java files.
If you really want to reuse existing classes, you can call the Axis2 API directly without generating a client using wsdl2java. Below is some relatively simple code to call a web service. You just need to fill in the web service endpoint, method QName, expected return Class(es), and arguments to the service. You could reuse your existing classes as the return values or arguments.
If your web service is pretty complicated then you may find that you have to go deeper into the API to get this approach to work.
serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
EndpointReference targetEPR = new EndpointReference("http://myservice");
options.setTo(targetEPR);
QName methodName = new QName("ns","methodName");
Class<?>[] returnTypes = new Class[] { String.class };
Object[] args = new Object[] { "parameter" };
Object[] response = serviceClient.invokeBlocking(methodName, args,
returnTypes);
You are generating the web service client from wsdl, correct?
The only thing that the wsdl2java tool knows about is the information in the wsdl, so it won't know about any types that you have already created.
If you can get the type information into the wsdl you may get it to work, although I have never tried.
If you want an easy way to copy from Type A to Type B then you could try BeanUtils.copyProperties, as long as the setters and getters of Type A and Type B match.
pretty much most java webservices projects go through this. I don't know if the .NET/C# world have a more elegant solution.
It makes sense, as Mike mentioned, to use BeanUtils.copyProperties.
BR,
~A
If you use eclipse as your ide, that is waht you need: http://www.eclipse.org/webtools/. It does beyond other things exactly what you want.
You can directly use ServiceClient class to call web service, which provides call using XML only and returns XML response. For different methods of web service, you have to convert the XML response to some java POJO to use it. Only Response handling needs to be done at your end. that you can do like from XML to Map etc...
So you won't need any other stub classes to call any web service, only needs to handle response XML. You can convert XML to POJO using Castor or JAXB libs.
This is the way you don't need to modify your client every time for diff. web services. You can develop like providing a response handler to client externally. So that for every different web service you will have diff. response handler class which is implementation of you interface.
//common interface for response handlers...
//implement this for diff. web service/methods
public interface WSRespHandler{
public Object getMeResp(Object respData);
}
//pass particular handler to client when you call some WS
public class WebServiceClient {
public Object getResp(WSRespHandler respHandler) {
..
return repHandler.getMeResp(xmlData);
}
}
reference:
http://www.developer.com/java/web/article.php/3863416/Using-Axis2-and-Java-for-Asynchronous-Web-Service-Invocation-on-the-Client-Side.htm
http://www.devdaily.com/blog/post/java/java-web-service-client-read-array-list/
thanks.
www.techlads.com
In case this post is still of any use to someone I read the axis2 generating clients guide: http://axis.apache.org/axis2/java/core/docs/userguide-creatingclients.html.
It seems that the Axis2 Eclipse plugin is configured to call ADB code generation in integrated mode (see http://axis.apache.org/axis2/java/core/docs/adb/adb-howto.html), thus creating inner classes in the Web service stub. I don't know if changing the generation mode to expanded mode (generate data classes out of the stub class) is possible, but you can do it command line using Wsdl2Java:
%AXIS2_HOME%\bin\WSDL2Java -uri <wsdl file path> -p <package name> -u
The -u option tells the ADB code generator to create data classes as separate classes and not inner classes in the stub.

Categories

Resources