How to generate request and response classes from wsdl? - java

I have a Spring Boot app built with Maven. Now, I plan to make requests to the SOAP service from this app. SOAP service is defined by WSDL. I am able to make requests and get responses with this method:
private String makeSoapRequest(String request, String action) throws IOException {
URL url = new URL("http://localhost/");
URLConnection urlConnection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;
InputStream is = new ByteArrayInputStream(request.getBytes());
baos = new ByteArrayOutputStream();
copy(is, baos);
is.close();
byte[] bytes = baos.toByteArray();
httpURLConnection.setRequestProperty("Content-Length", String.valueOf( bytes.length ) );
httpURLConnection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
httpURLConnection.setRequestProperty("SOAPAction", action);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
OutputStream out = httpURLConnection.getOutputStream();
out.write(bytes);
out.close();
InputStreamReader isr = new InputStreamReader(httpURLConnection.getInputStream());
BufferedReader in = new BufferedReader(isr);
String inputLine;
StringBuilder sb = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
ab.append(inputLine);
}
return sb.ToString();
}
However, my request and response here are XML strings. How can I generate my request and response classes from WSDL, so I can use them to make requests with HttpURLConnection?
Using Apache CXF did not help, as I should use HttpURLConnection. It is one of the requirements of the consumed service.
I can generate classes with JAXB or JAX-WS, but sending generated appropriate classes as request body gave me 400 Bad Request error.

You should use a code generator. You can find more information on WSDL2Java in the CXF documentation: https://cxf.apache.org/docs/how-do-i-develop-a-client.html

Related

How to decode JSON from Java REST API request?

I'm sending data to an API from Java using POST.
What I'm trying to do is send a particular variable to the API in the POST request, and then use the value of it. But currently the value is empty. The API is definitely being called.
My Java looks like this:
String line;
StringBuffer jsonString = new StringBuffer();
try {
URL url = new URL("https://www.x.com/api.php");
String payload = "{\"variable1\":\"value1\",\"variable2\":\"value2\"}";
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
writer.write(payload);
writer.close();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = br.readLine()) != null) {
jsonString.append(line);
}
br.close();
connection.disconnect();
}
This is based on: How to send Request payload to REST API in java?
Currently the value isn't being read correctly. Am I sending it correctly in Java? Do I have to do something to decode it?
The $_POST variable is not set for all HTTP POST requests, but only for specific types, e.g application/x-www-form-urlencoded.
Since you are posting a request containing JSON entity (application/json), you need to access it as follows.
$json = file_get_contents('php://input');
$entity= json_decode($json, TRUE);
You can try to use the following code instead of your String variable payload:
List<NameValuePair> payload = new ArrayList<NameValuePair>();
payload.add(new BasicNameValuePair("variable1", "value1");
That worked for me

IOException when trying to read http connection response

I'm submitting the request below in Java via a Websphere Portlet.
It works fine when I submit manually using postman (chrome extension) but cannot get it to succeed via java.
What am I missing?
I imported the SSL cert from remote host into Websphere, so SSL connections are not the issue.
Exception in logs ..
[7/15/14 23:06:39:993 BST] 00000170 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service CWSRV0014E: Uncaught service() exception root cause MyApp: java.io.IOException: Server returned HTTP response code: 500 for URL: https://server.com/msg
This is the java code invoking the request and trying to read the response ..
URL url = new URL("https://server.com/msg");
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String body = URLEncoder.encode("{\"x\": \"hello\"}", "UTF-8");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(body);
out.close();
// Exception occurs here ..
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();
This was solution, to not URLEncoder.encode() the POST body ..
URL url = new URL(queries.getQuery(sessionBean.getSelectedQuery()));
URLConnection connection = url.openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
String json = "{\"x\": \"hello\"}";
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(json);
out.close();
BufferedReader rd2 = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = rd2.readLine()) != null) {
result += line;
}
rd2.close();

Getting JSON response as part of Rest call in Java

I am trying to make Rest service call in Java. I am new to web and Rest service. I have Rest service which returns JSON as response. I have the following code but I think it's incomplete because I don't know how to process output using JSON.
public static void main(String[] args) {
try {
URL url = new URL("http://example.com:7000/test/db-api/processor");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/json");
OutputStream os = connection.getOutputStream();
//how do I get json object and print it as string
os.flush();
connection.getResponseCode();
connection.disconnect();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
I am new to Rest services and JSON.
Since this is a PUT request you're missing a few things here:
OutputStream os = conn.getOutputStream();
os.write(input.getBytes()); // The input you need to pass to the webservice
os.flush();
...
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream()))); // Getting the response from the webservice
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output); // Instead of this, you could append all your response to a StringBuffer and use `toString()` to get the entire JSON response as a String.
// This string json response can be parsed using any json library. Eg. GSON from Google.
}
Have a look at this to have a more clear idea on hitting webservices.
Your code is mostly correct, but there is mistake about OutputStream.
As R.J said OutputStream is needed to pass request body to the server.
If your rest service doesn't required any body you don't need to use this one.
For reading the server response you need use InputStream(R.J also show you example) like that:
try (InputStream inputStream = connection.getInputStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
byte[] buf = new byte[512];
int read = -1;
while ((read = inputStream.read(buf)) > 0) {
byteArrayOutputStream.write(buf, 0, read);
}
System.out.println(new String(byteArrayOutputStream.toByteArray()));
}
This way is good if you don't want to depends on third-part libraries. So I recommend you to take a look on Jersey - very nice library with huge amount of very useful feature.
Client client = JerseyClientBuilder.newBuilder().build();
Response response = client.target("http://host:port").
path("test").path("db-api").path("processor").path("packages").
request().accept(MediaType.APPLICATION_JSON_TYPE).buildGet().invoke();
System.out.println(response.readEntity(String.class));
Since your Content-Type is application/json, you could directly cast the response to a JSON object for example
JSONObject recvObj = new JSONObject(response);
JsonKey jsonkey = objectMapper.readValue(new URL("http://echo.jsontest.com/key/value/one/two"), JsonKey.class);
System.out.println("jsonkey.getOne() : "+jsonkey.getOne())

Manually hitting a SOAP Service in Java, getting IO.FileNotFound exception

I need to access a .Net SOAP Service manually. All the importers have issues with its WSDL, so I'm just manually creating the XML message, using HttpURLConnection to connect, and then parsing the results. I've wrapped the Http/SOAP call into a function that is supposed to return the results as a string. Here's what I have:
//passed in values: urlAddress, soapAction, soapDocument
URL u = new URL(urlAddress);
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("SOAPAction", soapAction);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","[star]/[star]");
connection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
//helper function that gets a string from a dom Document
String xmldata = XmlUtils.GetDocumentXml(soapDocument);
wout.write(xmldata);
wout.flush();
wout.close();
// Response
int responseCode = connection.getResponseCode();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String responseString = "";
String outputString = "";
//Write the SOAP message response to a String.
while ((responseString = rd.readLine()) != null) {
outputString = outputString + responseString;
}
return outputString;
My problem is on the line BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); I get a "java.io.FileNotFoundException" with the address that I'm using (i.e. urlAddress). If I paste that address into a browser, it pulls up the Soap Service webpage just fine (address is http://protectpaytest.propay.com/API/SPS.svc). From what I've read, the FileNotFoundException is if the HttpURLConnection returns a 400+ error message. I added the line getResponseCode() just to see what the exact code was, and it's 404. I added the User-Agent and Accept headers from some other pages saying they were needed, but I'm still getting 404.
Are there other headers I'm missing? What else do I need to do to get this call to work (since it works in a browser)?
-shnar

Send HTTP Post Payload with Java

I'm trying to connect to the grooveshark API, this is the http request
POST URL
http://api.grooveshark.com/ws3.php?sig=f699614eba23b4b528cb830305a9fc77
POST payload
{"method":'addUserFavoriteSong",'parameters":{"songID":30547543},"header":
{"wsKey":'key","sessionID":'df8fec35811a6b240808563d9f72fa2'}}
My question is how can I send this request via Java?
Basically, you can do it with the standard Java API. Check out URL, URLConnection, and maybe HttpURLConnection. They are in package java.net.
As to the API specific signature, try sStringToHMACMD5 found in here.
And remember to CHANGE YOUR API KEY, this is very IMPORTANT, since everyone knows it know.
String payload = "{\"method\": \"addUserFavoriteSong\", ....}";
String key = ""; // Your api key.
String sig = sStringToHMACMD5(payload, key);
URL url = new URL("http://api.grooveshark.com/ws3.php?sig=" + sig);
URLConnection connection = url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
OutputStream os = connection.getOutputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));
pw.write(payload);
pw.close();
InputStream is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
String response = sb.toString();
You could look into the Commons HttpClient package.
It is fairly straight forward to create POST's, specifically you could copy the code found here: http://hc.apache.org/httpclient-3.x/methods/post.html:
PostMethod post = new PostMethod( "http://api.grooveshark.com/ws3.php?sig=f699614eba23b4b528cb830305a9fc77" );
NameValuePair[] data = {
new NameValuePair( "method", "addUserFavoriteSong..." ),
...
};
post.setRequestBody(data);
InputStream in = post.getResponseBodyAsStream();
...
Cheers,

Categories