I am looking for some alternatives of consuming a SOAP web service in java. I am currently using a stub method to consume it and it's too simple for my instructor needs. My instructor said to do a trivial client, what was that suppose to mean?
SOAP is basically the submission of XML to a web server using the POST method. While the XML can get verbose, you should be able to construct the XML using StringBuilder and then use a simple HTTP client, like the Apache HttpClient to construct a POST request to a URL using
the XML string as the body.
That's about as simple as they come.
Here is the simple and lightweight example for consuming the soap api. Steps are below.
You must create the SOAPTestController.java, KflConstants.java And SoapClient.java class.
Then Implement the below code blocks and enjoy it.
Here is the SOAPTestController.java class
#Controller
public class SOAPTestController {
#RequestMapping(value = "/showdate", method = RequestMethod.GET)
public #ResponseBody String getDateAndTime() {
String DateAndTimeSOAPRequest = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
+ "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">\r\n"
+ " <soap12:Body>\r\n" + " <GetDateAndTime xmlns=\"http://tempuri.org/\" />\r\n"
+ " </soap12:Body>\r\n" + "</soap12:Envelope>";
String Fundtion = "GetDateAndTime";
return new SoapClient().ConsumeTheService(DateAndTimeSOAPRequest, "GetDateAndTime");
}
}
This is the KflConstants.java class
public class KflConstants {
public static final String SERVER_IP = "http://192.168.0.222/";
public static final String SERVICE_URL = SERVER_IP + "businesswebserviceNew/service.asmx";
public static final String CONTENT_TYPE_TEXT_XML = "text/xml; charset=utf-8";
public static final String GET_DATE_AND_TIME_URL = SERVICE_URL + "/GetDateAndTime";
}
Here is the SOAPClient.java class
public class SoapClient {
private static Logger log = LogManager.getLogger(SoapClient.class);
/*Input Stream Convert to the String Object*/
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
public String ConsumeTheService(String SOAPXML, String APINAME) {
String Result = null;
try {
/*Create The Connection*/
URL url = new URL(KflConstants.SERVICE_URL);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", KflConstants.CONTENT_TYPE_TEXT_XML);
conn.setRequestProperty(APINAME, KflConstants.GET_DATE_AND_TIME_URL);
log.info("Sending the envelope to server");
/*Send the request XML*/
OutputStream outputStream = conn.getOutputStream();
outputStream.write(SOAPXML.getBytes());
outputStream.close();
/* Read the response XML*/
log.info("Reading the Response");
InputStream inputStream = conn.getInputStream();
Result = convertStreamToString(inputStream);
inputStream.close();
/*INput Stream Convert to the SOAP Message*/
InputStream is = new ByteArrayInputStream(Result.getBytes());
SOAPMessage resposeSOAP = MessageFactory.newInstance().createMessage(null, is);
/*Return Values*/
log.info("Result SOAP:"+resposeSOAP.toString());
log.info("Result String:"+Result);
return Result;
} catch (Exception e) {
e.printStackTrace();
log.error(e);
return e.toString();
}
}
Thanks,
SoapRequestBuilder s = new SoapRequestBuilder();
s.Server = "127.0.0.1"; // server ip address or name
s.MethodName = "ConcatWithSpace";
s.XmlNamespace = "http://tempuri.org/";
s.WebServicePath = "/SimpleService/Service1.asmx";
s.SoapAction = s.XmlNamespace+s.MethodName;
s.AddParameter("one", "David");
s.AddParameter("two", "Hobbs");
String response = s.sendRequest();
Related
I am using restheart to provide a restful interface to mongodb. Get method is working good, I'm getting data from database in respons. But in this instance I'm trying to implementing POST request to write data in base. I'm running following code but I'm getting response with code 415 unsupported media type. My test base db1 have one collection testcoll where I'm trying to write a document with fields "name" and "rating"
public class PostMethodJava {
public static void main(String[] args) throws IOException {
URL url;
try {
url = new URL("http://127.0.0.1:8080/db1/testcoll/");
//url = new URL("http://google.com/");
} catch (Exception et) {
System.out.println("Data URL is broken");
return;
}
HttpURLConnection hc = null;
try {
hc = (HttpURLConnection) url.openConnection();
String login = "admin:12345678";
final byte[] authBytes = login.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
hc.addRequestProperty("Authorization", "Basic " + encoded);
System.out.println("Authorization: " + hc.getRequestProperty("Authorization"));
//hc.setDoInput(true);
hc.setDoOutput(true); //<== removed, otherwise 415 unsupported media type
hc.setUseCaches(false);
hc.setRequestMethod("POST");
//hc.setRequestProperty("Accept-Encoding", "gzip, deflate, sdch");
hc.setRequestProperty("Accept", "application/json");
} catch (Exception et) {
System.out.println("Can't prepare http URL con");
}
System.out.println(hc.toString());
String parameter = "mame=test1&rating=temp";
int plength = parameter.length();
byte[] pdata = parameter.getBytes(StandardCharsets.UTF_8);
try (DataOutputStream out = new DataOutputStream(hc.getOutputStream())){
out.write(pdata);
}
int rc = hc.getResponseCode();
System.out.println("response code: " + rc);
System.out.println("response message: " + hc.getResponseMessage());
}
}
What is wrong and how can I fix it?
Adding a line:
hc.setRequestProperty("Content-Type","application/json");
and writing the string:
String parameter = "{\"name\":\"doubleabc\",\"rating\":\"allright\"}";
fixed my problem.
I need to send Java object from client to Spring controller. I've tried the following. But not working.
My bean class - I have the same package and class in both client and service
public class DataObj implements Serializable {
private String stringData;
private byte[] byteData;
public String getStringData() {
return stringData;
}
public void setStringData(String stringData) {
this.stringData = stringData;
}
public byte[] getByteData() {
return byteData;
}
public void setByteData(byte[] byteData) {
this.byteData = byteData;
}
}
My controller
#RequestMapping(value = "/an/data", method = RequestMethod.POST)
public void subscribeUser(#RequestBody DataObj subscription){
System.out.println("DD");
bytes = subscription.getByteData();
}
My Client - Apache
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost httppost = new HttpPost("http://localhost:8080/contex/an/data");
httppost.setEntity(new SerializableEntity((Serializable) dataObj , false));
httpClient.execute(httppost);
My Client - URLConnection
URL url = new URL("http://localhost:8080/contex/an/data");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
ObjectOutputStream writer = new ObjectOutputStream (conn.getOutputStream());
writer.writeObject(dataObj );
writer.flush();
conn.connect();
writer.close();
System.out.println(conn.getResponseCode());
Both the execution is not working. The controller trying to redirect to access denied page. Correct me, if my understanding is wrong, pardon me, if it is duplicate. JSON wrapping won't help me, since the java object having byte array. So please note that.
UPDATE
I'm receiving the following log
org.apache.tomcat.util.http.Parameters processParameters
INFO: Character decoding failed. Parameter...... [Showing my bean class package and the data in non readable format]
Finally I found the answer, always Servlets are like King. I used the following to make it work
#Autowired
private HttpServletRequest context;
#RequestMapping(value = "/an/data", method = RequestMethod.POST)
#ResponseBody
public String send() {
System.out.println("EEE");
try{
ObjectInputStream obj = new ObjectInputStream(context.getInputStream());
DataObj v = (DataObj )obj.readObject();
System.out.println(v.getStringData());
}catch(Exception e){
e.printStackTrace();
}
return "CAME";
}
I have this error:
"Conectando: http://graph.facebook.com/pivotalsoftware
Consulta: {"PARAM1": "pivotalsoftware"}
Error ocurrido
java.io.IOException: Server returned HTTP response code: 403 for URL: http://graph.facebook.com/pivotalsoftware "
and i can't understand it so help me please!
public class Essai {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://graph.facebook.com/pivotalsoftware");
//Insert your JSON query request
String query = "{'PARAM1': 'pivotalsoftware'}";
//It change the apostrophe char to double colon char, to form a correct JSON string
query=query.replace("'", "\"");
try{
//make connection
URLConnection urlc = url.openConnection();
//It Content Type is so importan to support JSON call
urlc.setRequestProperty("Content-Type", "application/xml");
Msj("Conectando: " + url.toString());
//use post mode
urlc.setDoOutput(true);
urlc.setAllowUserInteraction(false);
//send query
PrintStream ps = new PrintStream(urlc.getOutputStream());
ps.print(query);
Msj("Consulta: " + query);
ps.close();
//get result
BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
String l = null;
while ((l=br.readLine())!=null) {
Msj(l);
}
br.close();
} catch (Exception e){
Msj("Error ocurrido");
Msj(e.toString());
}
}
private static void Msj(String texto){
System.out.println(texto);
// TODO code application logic here
}
Class below should help you
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class userAuthetication {
//5213
public static void userlogin(String usrname, String pwd) throws IOException{
try {
URL url = new URL("http://140.104.135.204:50/Directory-Rest.aspx?Function=Authenticate");
//Insert your JSON query request
String query = "{'Username':'"+ usrname + "',"+ "'Password':'" + pwd + "'}";
//It change the apostrophe char to double colon char, to form a correct JSON string
query=query.replace("'", "\"");
//make connection
URLConnection urlc = url.openConnection();
//It Content Type is so importan to support JSON call
urlc.setRequestProperty("Content-Type", "application/xml");
Msj("Conectando: " + url.toString());
//use post mode
urlc.setDoOutput(true);
urlc.setAllowUserInteraction(false);
//send query
PrintStream ps = new PrintStream(urlc.getOutputStream());
ps.print(query);
Msj("Consulta: " + query);
ps.close();
//get result
BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream()));
String l = null;
while ((l=br.readLine())!=null) {
Msj(l);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Msj("Error ocurrido");
Msj(e.toString());
}
}
private static void Msj(String texto){
System.out.println(texto);
}
}
While it is possible, I'd not recommend to build your own REST Client (incorporating URLConnection or etc. low-level APIs) unless it's really necessary.
There are several ways to do this. I'll draw your attention on some most popular ones:
Spring's RestTemplate, which uses the Jackson JSON processing library to process the incoming data. (updates with Spring WebClient);
JAX-RS (Jersey implementation), which has several ways to consume different Media Types.
These are the easiest and most popular, performing facilities to create REST Client, hence consume REST Resource.
This is all it takes for RestTemplate to consume REST resource:
public static void getRESTResource() {
final String uri = "your host here;
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class); //note, that there are many overloaded methods for different variations of parameters;
CustomType result = restTemplate.getForObject(REST_URI, CustomType.class, params); //to bind incoming data to your CustomType
}
Example of JAX-RS Client can be found here.
import java.net.*;
import java.io.*;
public class sample
{
public static void main (String args[])
{
String line;
try
{
URL url = new URL( "http://localhost:8080/WeighPro/CommPortSample" );
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
line = in.readLine();
System.out.println( line );
in.close();
}
catch (Exception e)
{
System.out.println("Hello Project::"+e.getMessage());
}
}
}
My Servlet is invoking another Jsp page like the below,
RequestDispatcher rd=request.getRequestDispatcher("index.jsp");
rd.forward(request, response);
I am not getting any reaction/output in the browser, where the servlet has to be executed once it is invoked.
Am I missing any basic step for this process? Please Help!!!
If you want to open it in browser try this
java.awt.Desktop.getDesktop().browse(java.net.URI.create("http://localhost:8080/WeighPro/CommPortSample"));
You question is not clear. Do you actually want to invoke a Servlet from the Main method, or do you want to make an HTTP request to your web application?
If you want to make an HTTP request, I can't see any obvious problems with your code above, which makes me believe that the problem is in the Servlet. You also mention that you don't get anything in the browser, but running your program above does not involve a browser.
Do you mean that you don't get a response when you go to
http://localhost:8080/WeighPro/CommPortSample
in a browser?
As Suresh says, you cannot call a Servlet directly from a main method.
Your Servlet should instead call methods on other classes, and those other classes should be callable from the main method, or from Test Cases. You need to architect your application to make that possible.
import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class OutBoundSimul {
public static void main(String[] args) {
sendReq();
}
public static void sendReq() {
String urlString = "http://ip:port/applicationname/servletname";
String respXml = text;
URL url = null;
HttpURLConnection urlConnection = null;
OutputStreamWriter out = null;
BufferedInputStream inputStream = null;
try {
System.out.println("URL:"+urlString);
url = new URL(urlString);
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
System.out.println("SendindData");
out = new OutputStreamWriter(urlConnection.getOutputStream());
System.out.println("Out:"+out);
out.write(respXml);
out.flush();
inputStream = new BufferedInputStream(urlConnection.getInputStream());
int character = -1;
StringBuffer sb = new StringBuffer();
while ((character = inputStream.read()) != -1) {
sb.append((char) character);
}
System.out.println("Resp:"+sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Invoking Servlet with query parameters Form Main method
Java IO
public static String accessResource_JAVA_IO(String httpMethod, String targetURL, String urlParameters) {
HttpURLConnection con = null;
BufferedReader responseStream = null;
try {
if (httpMethod.equalsIgnoreCase("GET")) {
URL url = new URL( targetURL+"?"+urlParameters );
responseStream = new BufferedReader(new InputStreamReader( url.openStream() ));
}else if (httpMethod.equalsIgnoreCase("POST")) {
con = (HttpURLConnection) new URL(targetURL).openConnection();
// inform the connection that we will send output and accept input
con.setDoInput(true); con.setDoOutput(true); con.setRequestMethod("POST");
con.setUseCaches(false); // Don't use a cached version of URL connection.
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
con.setRequestProperty("Content-Language", "en-US");
DataOutputStream requestStream = new DataOutputStream ( con.getOutputStream() );
requestStream.writeBytes(urlParameters);
requestStream.close();
responseStream = new BufferedReader(new InputStreamReader( con.getInputStream(), "UTF-8" ));
}
StringBuilder response = new StringBuilder(); // or StringBuffer if not Java 5+
String line;
while((line = responseStream.readLine()) != null) {
response.append(line).append('\r');
}
responseStream.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace(); return null;
} finally {
if(con != null) con.disconnect();
}
}
Apache Commons using commons-~.jar
{httpclient, logging}
public static String accessResource_Appache_commons(String url){
String response_String = null;
HttpClient client = new HttpClient();
GetMethod method = new GetMethod( url );
// PostMethod method = new PostMethod( url );
method.setRequestHeader("Content-type", "text/xml; charset=ISO-8859-1");
method.setQueryString(new NameValuePair[] {
new NameValuePair("param1","value1"),
new NameValuePair("param2","value2")
}); //The pairs are encoded as UTF-8 characters.
try{
int statusCode = client.executeMethod(method);
System.out.println("Status Code = "+statusCode);
//Get data as a String OR BYTE array method.getResponseBody()
response_String = method.getResponseBodyAsString();
method.releaseConnection();
} catch(IOException e) {
e.printStackTrace();
}
return response_String;
}
Apache using httpclient.jar
public static String accessResource_Appache(String url) throws ClientProtocolException, IOException{
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
URIBuilder builder = new URIBuilder( url )
.addParameter("param1", "appache1")
.addParameter("param2", "appache2");
HttpGet method = new HttpGet( builder.build() );
// HttpPost method = new HttpPost( builder.build() );
// Create a custom response handler
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
#Override
public String handleResponse( final HttpResponse response) throws IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
return entity != null ? EntityUtils.toString(entity) : null;
}
return "";
}
};
return httpclient.execute( method, responseHandler );
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
JERSY using JARS {client, core, server}
public static String accessResource_JERSY( String url ){
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource( url );
ClientResponse response = service.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);
if (response.getStatus() != 200) {
System.out.println("GET request failed >> "+ response.getStatus());
}else{
String str = response.getEntity(String.class);
if(str != null && !str.equalsIgnoreCase("null") && !"".equals(str)){
return str;
}
}
return "";
}
Java Main method
public static void main(String[] args) throws IOException {
String targetURL = "http://localhost:8080/ServletApplication/sample";
String urlParameters = "param1=value11¶m2=value12";
String response = "";
// java.awt.Desktop.getDesktop().browse(java.net.URI.create( targetURL+"?"+urlParameters ));
// response = accessResource_JAVA_IO( "POST", targetURL, urlParameters );
// response = accessResource_Appache_commons( targetURL );
// response = accessResource_Appache( targetURL );
response = accessResource_JERSY( targetURL+"?"+urlParameters );
System.out.println("Response:"+response);
}
Simply you cannot do that.
A response and request pair will generated by web container. You cannot generate a response object and send to the browser.
By the way which client/browser you are expecting to get the response ? No idea. Right ?
When container receives a request from client then it generates response object and serves you can access that response in service method.
If you want to see/test the response, you have to request from there.
Does anyone know if there is a Google Reader service call that a user can make to get the name/uri of all feeds that fall under a certain label/category? Thanks!
You can use a variation of the code below to get access to the Google Reader system. You need to send the header ("Authorization", "auth=" +myauthvar) with each request. In order to edit items you will need the token which I also demo below. Once you have the auth id you can post (with that header intact) to http://www.google.com/reader/api/0/subscription/list?output=xml in order to return the full subscription listing.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
getAuth();
Console.ReadLine();
}
public static void getAuth()
{
//put in the username and password
string postData = "Email=YOURUSERNAME#gmail.com&Passwd=YOURPASSWORD&service=reader&source=some-uniqueapp-v1";
WebRequest authReq = WebRequest.Create("https://www.google.com/accounts/ClientLogin");
authReq.ContentType = "application/x-www-form-urlencoded";
authReq.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(postData);
authReq.ContentLength = bytes.Length;
Stream os = authReq.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
WebResponse resp = authReq.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string responseContent = sr.ReadToEnd().Trim();
string[] responseSpilt = responseContent.Split('=');
string authticket = responseSpilt[3];
Console.WriteLine("Auth = " + authticket);
sr.Close();
getToken(authticket);
}
public static void getToken(string auth)
{
WebRequest tokenReq = WebRequest.Create("https://www.google.com/reader/api/0/token");
tokenReq.ContentType = "application/x-www-form-urlendcoded";
tokenReq.Method = "GET";
tokenReq.Headers.Add("Authorization", "GoogleLogin auth=" + auth);
WebResponse response = tokenReq.GetResponse();
if (response == null) return;
StreamReader sr = new StreamReader(response.GetResponseStream());
string respContent = sr.ReadToEnd().Trim();
string[] respSplit = respContent.Split('/');
string token = respSplit[2];
Console.WriteLine(" ");
Console.WriteLine("Token = " + token);
sr.Close();
}
}
}