i am tring to extract response data from wsdl url using soapui java code. all are working good, but problem is in response.
in response i am getting ? instead of getting proper data.
Eclipse Console result
but when i am tring to hit wsdl url using soapui it is working fine.
check my code
package src.com;
import com.eviware.soapui.impl.wsdl.WsdlInterface;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.WsdlProject;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlImporter;
import com.eviware.soapui.model.iface.Operation;
public class Test {
public static void main(String[] args) throws Exception {
WsdlProject project = new WsdlProject();
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, "http://localhost:8080/SoapService/services/TestService?wsdl");
WsdlInterface wsdl = wsdls[0];
for (Operation operation : wsdl.getOperationList()) {
WsdlOperation wsdlOperation = (WsdlOperation) operation;
System.out.println("Request:\n"+wsdlOperation.createRequest(true));
System.out.println("\nResponse:\n"+wsdlOperation.createResponse(true));
}
}
}
Check Jars
Within the SoapUI application you are actually making a call out to the web service and getting a response. In your sample java code you are just generating a response XML from the WSDL file instead of actually calling out to the web service and it's defaulting any required values to have a ?. If you generate the same response within the SoapUI application you will see the same ? set for the findAllReturned element.
You can use the java SoapUI's WSDLSubmit class to make a call out to the web service and get a response back.
The answer to this linked question shows a code sample of how you would go about making an actual call out to the web service using the SoapUI java api:
https://stackoverflow.com/a/14814524/8127149
And this link has other examples of using the WSDLSubmit class:
http://www.programcreek.com/java-api-examples/index.php?api=com.eviware.soapui.impl.wsdl.WsdlSubmit
Related
Using Axis 1.4 I built client application that will consume external server services.
The server application response with soap message that include header tag along with body tag.
My problem with the header tag, I am trying to find away to get the header element.
What is done so far:
I found that I need to use a handler that extends BasicHandler using this class I can get the header tag. source: Dealing with SOAP Headers in Axis
But how to make this handler work when consuming web-service? I mean how to invoke this handler when ever I am receiving response from server to get its header.
Some blogs suggest I need to use .wsdd file. I am using Jdeveloper 11g with weblogic 10.3.6 environment where I am only aware of web.xml file for configuration.
Question: How to link those information(handler class, .wsdd file and web.xml) to gather and make the handler works to get the header tags?
The best start was to check Axis guide on: Apache-Axis Reference Guide where you will have an overview of the work flow.
To configure handlers to be trigger from the client side you need to do the following:
1- Create handler class basically something similar to the following:
package mypackge;
import javax.xml.soap.SOAPException;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPHeader;
import org.apache.axis.message.SOAPHeaderElement;
public class SoapHeaderConsumerHandler
extends BasicHandler
{
public void invoke(MessageContext messageContext)
throws AxisFault
{
// Your logic for request or response handling goes here.
// Basically you need to make use of the parameter
// messageContext where you can access the soap header and body tags.
}
}
2- Create the client-config.wsdd file. it will look like the following:
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<globalConfiguration>
<responseFlow>
<handler name="log" type="java:mypackge.SoapHeaderConsumerHandler"/>
</responseFlow>
</globalConfiguration>
<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
</deployment>
You can see that I am using only handlers for the incoming response from the server side. So when ever the client application receive a response from the server the handler class SoapHeaderConsumerHandler will be triggered and the method invoke will be called by default.
Note: if you want to access the outgoing request before send it to the server you need to add extra tag for <requestFlow> to add request handler.
Check Deployment(WSDD) Reference from Axis guide:
3- Where to place the client-config.wsdd file ?
You should place the .wsdd file in the working directory. You can easily find out the working directory location using :
System.out.println("Working Directory = " + System.getProperty("user.dir"));
Source: Getting the Current Working Directory in Java
UPDATE:
I found out that it is not necessary to put the client-config.wsdd file in the working directory. You can specify the path of this file in your code as follow:
System.setProperty("axis.ClientConfigFile", "[Path goes here]\\client-config.wsdd");
You just need to place the .wsdd file there.
Extra Useful Links:
Where to place the client-config.wsdd file in Railo
V Axis handler This is an example for the server side handlers.
Dealing with SOAP Headers in Axis
To avoid file location problems you can programatically configure axis :
ConsultationServiceLocator stub = new ConsultationServiceLocator();
SimpleProvider clientConfig = new SimpleProvider();
SoapHeaderConsumerHandler logHandler = new SoapHeaderConsumerHandler();
SimpleChain reqHandler = new SimpleChain();
SimpleChain respHandler = new SimpleChain();
reqHandler.addHandler(logHandler);
respHandler.addHandler(logHandler);
Handler pivot = new HTTPSender();
Handler transport = new SimpleTargetedChain(reqHandler, pivot, respHandler);
clientConfig.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME, transport);
I am writing a java plugin that I plan to use to test a number of web services. These SOAPs for the web services are located in a properties file, and are grouped under which WSDL they fall under (Subscriber, Network, User, etc...). Also, there are some regexs associated with each web service to test the response against.
Properties Example
#Web services to be tested and regexes to test responses
#List of web service groups used (WSDLs)
webservice.list = SubscriberMgmt,NetworkMgmt
# < -- SubscriberMgmt -- >
#getSubscriberDevices
webservice.subscriber = <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.blah.blah.com"><soapenv:Header/><soapenv:Body><ws:getSubscriberDevices><PhoneNumber></PhoneNumber><LastName></LastName><MACAddress></MACAddress><ExternalId></ExternalId><AccountExternalId>john</AccountExternalId><IPAddress></IPAddress></ws:getSubscriberDevices></soapenv:Body></soapenv:Envelope>
webservice.SubscriberMgmt.regex = subscriberId="(.+?)"
webservice.SubscriberMgmt.regex.1 = externalId="(.+?)"
#getMpegResultsById
webservice.subscriber.1 = <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.blah.blah.com"><soapenv:Header/><soapenv:Body><ws:getMpegResultsById><SubscriberId>100016</SubscriberId><Duration>2880</Duration></ws:getMpegResultsById></soapenv:Body></soapenv:Envelope>
webservice.SubscriberMgmt.1.regex = id="(.+?)"
webservice.SubscriberMgmt.1.regex.1 = externalId="(.+?)"
I currently have code to connect using each WSDL from the properties file, so say when the 'webservicegroup' variable is SubscriberMgmt, I'd like to test the .subscriber web service(s) and check the responses if it contains the corresponding regex(es). (the 'data' variable only corresponds to one SOAP request from the property file at the moment)
//Soap Request
try
{
for(String webservicegroup : webserviceList)
{
URL url = new URL("http://" + server + "/webservices/" + webservicegroup);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction", "\"\"");
String loginEnc = new BASE64Encoder().encodeBuffer((username + ":" + password).getBytes());
loginEnc = loginEnc.replaceAll("\n", "");
conn.setRequestProperty("Authorization", "Basic " + loginEnc);
conn.setConnectTimeout(timeout);
conn.setReadTimeout(timeout);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
//Send request
wr.write(data);
wr.flush();
wr.close();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//Save response
String line;
while ((line = in.readLine()) != null)
{
response += line;
}
in.close();
}
}
Any ideas on the best way of doing this? Any help is greatly appreciated
Assuming your connection and POST/GET code is working:
Step 1: Get the entire response as a string:
String response = new String(ByteStreams.toByteArray(inputStream), "UTF-8");
In the above line of code, the ByteStreams class is part of google's guava library. Similar code can be found in apache commons-io, if you prefer that.
Step 2: Test Regular expressions:
if( response.matches(regex) ) { ... }
Don't reinvent the wheel, building a custom testing software mini empire from scratch.
Use SOAPUI open source version to test web services. It allows you to:
generate SOAP tests from web service endpoint WSDL, saving manual labour
avoid processing "pre-canned" SOAP strings and parsing files
automatically generate mocks of your service endpoints, including ability to programmatically control custom responses.
implement test step logic including loops, branches, invoking other test steps, running scripts, and reading/writing parameters from/to property files and data sources (although you must programatically navigate & modify XmlHolder instances via scripts if you wish to "data-drive" your tests)
Execute SOAP, REST, security & load testing of web services, and also JDBC and HTTP test calls.
Integrates with the common build and continuous integration tools for test automation (TDD & continuous delivery).
Use SOAPUI operations within your IDE, via plugins.
It's considered fairly standard "best practice" for testing web services.
To checks SOAP response messages for valid content, using the open source version of SOAPUI:
you can use XPath or XQuery expressions to validate the XML.
you can use script assertions
E.g. if your SOAP response is:
<soap:Body>
<GetEnumResponse xmlns="http://www.xyz.com/">
<GetEnumResult>
<ErrorCode>0</ErrorCode>
<StatusId>0</StatusId>
</GetEnumResult>
<enumsInformation>
<EnumInformation>
<TransactionId>0</TransactionId>
<ConstraintId>5000006</ConstraintId>
<EnumValue>xyz</EnumValue>
<Index>10</Index>
</EnumInformation>
</enumsInformation>
</GetEnumResponse>
</soap:Body>
You can script:
import com.eviware.soapui.support.XmlHolder
def holder = new XmlHolder(messageExchange.responseContentAsXml)
holder.namespaces["tal"]="http://www.xyz.com/"
def node = holder.getNodeValue("//tal:ConstraintId[1]");
log.info(node);
assert node == "5000006";
You can even use the maximum power of standard java regex processing.
Create java classes that do the regex processing and put them into a jar file and place in soapUIinstallation/bin/ext as explained here.
Or wrap your SOAPUI Test inside a JUnit test method, and add standard java code at end to check regexs. This also eases test automation & allows any non-web service tests to be executed as well. This approach works with SOAPUI open source version, whereas the alternative of using SOAPUI assertion steps requires the Pro version.
Steps:
If you choose, install the SOAPUI plugin in your IDE
Use SOAPUI to create a test suite
Use SOAPUI to create test case(s) within the test suite
Use SOAPUI to create test step(s) within the test suite. This is the core of using SOAPUI.
Create a Java project in your IDE. Within this project, add a JUnit test case.
Add all JARs from SoapUI bin and lib directories to Java Build Path.
Within the Junit Test case, add code to execute a SOAPUI test step
Obtain the MessageExchange object, get the response from it, and then get headers, content or attachments. Run a regex check on result.
The following is indicative only. Not intended to be a working example.
package com.example;
import org.junit.Test;
import com.eviware.soapui.tools.SoapUITestCaseRunner;
public class SoapUIProject {
// runs an entire SOAPUI test suite
#Test
public void soapTest1() throws Exception {
SoapUITestCaseRunner runner = new SoapUITestCaseRunner();
runner.setProjectFile("/path/to/your/W3Schools-Tutorial-soapui-project.xml");
runner.run();
}
// runs a single SOAPUI test step - and checks response matches a regex
#Test
public void soapTest2() throws Exception {
WsdlProject project = new WsdlProject( "src/dist/sample-soapui-project.xml" );
TestSuite testSuite = project.getTestSuiteByName("My Test Suite");
TestCase testCase = testSuite.getTestCaseByName("My Test Case");
TestCaseRunner testCaseRunner = new WsdlTestCaseRunner(testCase,null);
// Must have test step setup as WsdlMessageExchange for cast to work
WsdlMessageExchangeTestStepResult testStepResult = (WsdlMessageExchangeTestStepResult)testStep.runTestStepByName("My Test Step");
// TestStep testStep = testCase.getTestStepByName("My Test Step");
// TestCaseRunContext testCaseRunContext = new WsdlTestRunContext(testStep);
// testStep.prepare(testCaseRunner, testCaseRunContext);
// WsdlMessageExchangeTestStepResult testStepResult = (WsdlMessageExchangeTestStepResult)testStep.run(testCaseRunner, testCaseRunContext);
MessageExchange[] messageExchanges = testStepResult.getMessageExchanges();
for (MessageExchange me : messageExchanges) {
String response = me.getResponseContentAsXML();
// do any desired regex processing
// can use any desired assertions
}
assertEquals( Status.FINISHED, runner.getStatus() );
}
}
Further refs: http://www.soapui.org/Scripting-Properties/tips-a-tricks.html#3-xml-nodes
http://books.google.com.au/books?id=DkWx7xZ263gC&printsec=frontcover#v=onepage&q&f=false
I feel like this should be straight forward. We are implementing a Java webservice using SOAP in Eclipse. We want to know who is calling the webservice. I would have though I could get the referer from the header somehow but am at a loss as to how to do it. We are using Axis 2.
copied from TechNick you can leverage axis2 for this. The fact you're using Eclipse is largely irrelevant, the code below should work fine.
//Import statement to import MessageContext class
import org.apache.axis2.context.MessageContext;
/*
* This method gets the client IP address using axis2 MessageContext
*
* #return Client IP : String
*/
private String getClientIP () {
return (String)(MessageContext.getCurrentMessageContext()).getProperty(MessageContext.REMOTE_ADDR);
}
Getting an error while trying to consume a Restful web service using
POST method(with form param).
I want to consume a REST application using POST method.
Please find below the resource class I want to access.
#Path("/user")
public class User {
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response get(#FormParam("username") String userName,
#FormParam("userid") String userId ){
}
I tried using Jesry Client for accessing.Please find below the code i tried.
I tried adding values to FormParam as shown below.
Trail 1
WebResource webResource = client.resource("baseURL/user");
String input = "userid:1001,username:demo1";
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, input);
I am getting a an error response back "The server encountered an internal error () that prevented it from fulfilling this request".
I think I am not adding the values to FormParam properly.
Trial 2
I also tried adding the form params using the below code
MultivaluedMap formData = new MultivaluedMapImpl();
formData.add("userid", "1001");
formData.add("username", "demo1");
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
This also resulted in the same error.
Trial 3
Form f = new Form();
f.add("userid", "1001D");
f.add("username", "1001D");
ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED_TYPE).post(ClientResponse.class, f);
This also resulted in the same error.
Any help is appreciated.
Since your error indicates "Server encountered an internal error" you need to look at the server (logs) to see what went wrong. Certainly your 3rd client looks fine to reach the service you defined (assuming you are using something real instead of the string "baseURL").
You can easily test your server is working separately from your client by creating a HTML page to reach the service. Create a HTML form using enctype="application/x-www-form-urlencoded" and posting to your service endpoint (what you are calling "baseURL/user") with form parameters userid and username. When you view the HTML form in a browser and hit the submit button, it will call your server - if you get the same error you can be sure it is nothing to do with your client code.
Hope http://yogeshmprajapati.blogspot.in/2011/12/login-to-fb-from-java.html will help you.
A simple question, but could someone provide sample code as to how would someone call a web service from within the JBoss Seam framework, and process the results?
I need to be able to integrate with a search platform being provided by a private vendor who is exposing his functionality as a web service. So, I'm just looking for some guidance as to what the code for calling a given web service would look like.
(Any sample web service can be chosen as an example.)
There's roughly a gajillion HTTP client libraries (Restlet is quite a bit more than that, but I already had that code snippet for something else), but they should all provide support for sending GET requests. Here's a rather less featureful snippet that uses HttpClient from Apache Commons:
HttpClient client = new HttpClient();
HttpMethod method = new GetMethod("http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=restbook&query=HttpClient");
client.executeMethod(method);
import org.restlet.Client;
import org.restlet.data.Protocol;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.restlet.resource.DomRepresentation;
import org.w3c.dom.Node;
/**
* Uses YAHOO!'s RESTful web service with XML.
*/
public class YahooSearch {
private static final String BASE_URI = "http://api.search.yahoo.com/WebSearchService/V1/webSearch";
public static void main(final String[] args) {
if (1 != args.length) {
System.err.println("You need to pass a search term!");
} else {
final String term = Reference.encode(args[0]);
final String uri = BASE_URI + "?appid=restbook&query=" + term;
final Response response = new Client(Protocol.HTTP).get(uri);
final DomRepresentation document = response.getEntityAsDom();
document.setNamespaceAware(true);
document.putNamespace("y", "urn:yahoo:srch");
final String expr = "/y:ResultSet/y:Result/y:Title/text()";
for (final Node node : document.getNodes(expr)) {
System.out.println(node.getTextContent());
}
}
}
}
This code uses Restlet to make a request to Yahoo's RESTful search service. Obviously, the details of the web service you are using will dictate what your client for it looks like.
final Response response = new Client(Protocol.HTTP).get(uri);
So, if I understand this correctly, the above line is where the actual call to the web service is being made, with the response being converted to an appropriate format and manipulated after this line.
Assuming I were not using Restlet, how would this line differ?
(Of course, the actual processing code would be significantly different as well, so that's a given.)