Http Client using JAXRS Client API (POST Request) in Websphere Liberty Profile - web-services

I need to create an Http Client to test a REST web service with JAXRS Client API (lib: javax.ws.rs.client.*) provided by WLP. I'll have to send a String Request (JSON message) using POST method and Receive a String Response (JSON message). I'll be grateful if someone has a similar Java Code (Class) and the necessary imports to do this task.
PS : I started coding the Java Class but I didn't know how to get the response:
Client client = ClientBuilder.newClient();
WebTarget myResource = client.target("http://example.com/webapi");
....
I'm using:
Websphere Liberty profile 16.0.0.2,
jaxrs-2.0 [1.0.0]
jaxrsClient-2.0 [1.0.0]
IDE : RDz

You're almost there. All you need to do is format your request data into an instance of 'Entity' and send it off to your service.
Below is some example code that does this for a very simple JAX-RS service.
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
....
// Set up our client and target our JAX-RS service
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9081/example.jaxrs/test/SimpleService");
// Build our request JSON into an 'Entity'. Replace 'myData' with your JSON
Entity<String> data = Entity.entity("MyData", MediaType.APPLICATION_JSON_TYPE);
// Then send a post request to the target service
String result = target.request(MediaType.APPLICATION_JSON_TYPE).post(data, String.class);

Try the following,
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
Client client = ClientBuilder.newClient();
WebTarget myResource = client.target("http://example.com/webapi");
Invocation.Builder invocationBuilder = myResource.request(MediaType.TEXT_PLAIN_TYPE);
Response getResponse = invocationBuilder.get();
if (getResponse != null && getResponse.getStatus() == 200) {
String responseString = getResponse.readEntity(String.class);
}

Related

401 Unauthorized when calling webservice through javacode

I have to call web service through java. When i hit the web-service URL in browser it asks for user name and password and i can see the result,
But when i am trying to call it using java code i am getting error like
You are not authorized to view this page BODY { font: 8pt/12pt verdana } H1 { font: 13pt/15pt verdana } H2 { font: 8pt/12pt verdana } A:link { color: red } A:visited { color: maroon }You are not authorized to view this pageYou do not have permission to view this directory or page using the credentials that you supplied because your Web browser is sending a WWW-Authenticate header field that the Web server is not configured to accept.Please try the following:Contact the Web site administrator if you believe you should be able to view this directory or page.Click the Refresh button to try again with different credentials.HTTP Error 401.2 - Unauthorized: Access is denied due to server configuration.Internet Information Services (IIS)Technical Information (for support personnel)Go to Microsoft Product Support Services and perform a title search for the words HTTP and 401.Open IIS Help, which is accessible in IIS Manager (inetmgr), and search for topics titled About Security, Authentication, and About Custom Error Messages.
i am not able access the the result using SOAP UI
i am really stuck ,i tried using httpclient/jersey
please help how can i send username and password using java code
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.params.AuthPNames;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.AuthPolicy;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
public class NTLM_TRY2 {
/**
* #param args
*/
public static void main(String[] args) throws Exception{
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpget = new HttpGet("http://10.0.134.114/eBill/bpsWebService.asmx");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY,
new NTCredentials("abc", "acb#578", "", ""));
java.util.List<String> authtypes = new ArrayList<String>();
authtypes.add(AuthPolicy.NTLM);
authtypes.add(AuthPolicy.DIGEST);
authtypes.add(AuthPolicy.BASIC);
httpclient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF,
authtypes);
httpclient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF,
authtypes);
localContext.setAttribute(ClientContext.CREDS_PROVIDER, credsProvider);
HttpResponse response = httpclient.execute(httpget, localContext);
System.out.println("Response code: " + response.getStatusLine());
}
}
If it is basic authentication you have to send the user an password in the header of the request.
See this question in SO.
Http Basic Authentication in Java using HttpClient?

communication between 2 rest web services

I have many rest controllers in my project (developed with spring MVC) and i would like to make them communicate between each other.
what's the best way to make two spring REST controllers exchange messages ?
Supposed you have 2 controllers:
#RestController
#RequestMapping("/first")
public class FirstController(){
// your code here
}
and
#RestController
#RequestMapping("/second")
public class SecondController(){
// supposed this is your FirstController url.
String url = "http://localhost:8080/yourapp/first";
// create request.
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
// execute your request.
HttpResponse response = client.execute(request);
// do whatever with the response.
}
For reference, have a look at this: http://www.mkyong.com/java/apache-httpclient-examples/
Used library: https://hc.apache.org/httpcomponents-client-ga/

SOAP Debug message not getting printed

I set -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true in my client VM arguments. I am using JAX-WS client. But inspite of that SOAP Message is not getting printed in the console. Any reason?
This is my client code.
package com.helloworld.client;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.helloworld.ws.HelloWorld;
public class HelloWorldClient{
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9999/ws/hello?wsdl");
//1st argument service URI, refer to wsdl document above
//2nd argument is service name, refer to wsdl document above
QName qname = new QName("http://ws.helloworld.com/", "HelloWorldImplService");
Service service = Service.create(url, qname);
HelloWorld hello = service.getPort(HelloWorld.class);
System.out.println(hello.getHelloWorldAsString("Test String"));
}
}
My server is I published using Endpoint.publish and is running locally.
on Server
com.sun.xml.ws.transport.http.HttpAdapter.dump=true
You can also use #HandlerChain(file = "....") annotation
More about Jax-WS Handlers here and here
This is the correct VM argument -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true. Are you using any IDEA?

Grails RESTFUL web service api

I am currently developing a web app which should do restful service calls to existing web service api.
What I have is the base URL and the API names.
Any help on how do I start working on it?
I suppose I need to use httpbuilder for the base url I have, then followed by /api name. But how do I test it on grails if its working?
When I paste the base url on the browser it does return some xml information, so what I need is to do it on grails instead.
XML response when I paste the url through browser
<ns1:createNewUserResponse>
<userId>21</userId>
</ns1:createNewUserResponse>
So I need to be able to get this response through my web-app (grails) instead of pasting it on the browser.
EDIT*
this is a good example I found useful
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
def http = new HTTPBuilder( 'http://ajax.googleapis.com' )
// perform a GET request, expecting JSON response data
http.request( GET, JSON ) {
uri.path = '/ajax/services/search/web'
uri.query = [ v:'1.0', q: 'Calvin and Hobbes' ]
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
// response handler for a success response code:
response.success = { resp, json ->
println resp.statusLine
// parse the JSON response object:
json.responseData.results.each {
println " ${it.titleNoFormatting} : ${it.visibleUrl}"
}
}
// handler for any failure status code:
response.failure = { resp ->
println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
}
}
but i do not understand the query part and how do I alter it to my need?
the URL I have contains credential of username and password, the response should return a securityToken which I need to get it out from the results. Any help would be greatly appreciated!
You can start with groovy-wslite, it provides both SOAP and REST webservice clients.
To make a call to a resfull service look at Groovy HttpBuidler - http://groovy.codehaus.org/HTTP+Builder

Build Soap web service client using wsdl documents in Eclipse

I need to create web service client in Java using Eclipse the consumes the onvif wsdl.
I spent several hours without finding a how to do that, this the first time I am using soap, my experience was in REST.
I tried many tutorials like this to create web service client, but when I am trying to choose the wsdl file from my local disk, eclipse shows the an error Could not retrieve the WSDL file ..., the link structure I used for the file was file:/C:/ONVIF/media.wsdl.
I need to use any Java framework that support WS-Notification to implement my client.
Can you please tell me how to implement client web service that consumes the WSDL files.
Do I need web server to implement soap web service client?
If yes, why?
Here is a complete code and guide on how to consume one of ONVIF's wsdl files (devicemgmt.wsdl) and how to use it to connect to a device:
package test;
import java.io.IOException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.onvif.ver10.device.wsdl.Device;
import org.onvif.ver10.schema.DateTime;
import org.onvif.ver10.schema.SystemDateTime;
import org.onvif.ver10.schema.Time;
import com.sun.org.apache.xml.internal.security.utils.Base64;
public class OnvifTest {
private static TimeZone utc = TimeZone.getTimeZone("UTC");
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
static {
sdf.setTimeZone(utc);
}
private static long serverTime = 0;
private static long clientTime = 0;
private static final String ip = "...";
private static final String user = "...";
private static final String pass = "...";
// Some cameras (e.g. Axis) require that you set the user/pass on the ONVIF section in it's web interface
// If the camera is reset to factory defaults and was never accessed from the web, then
// either no user/pass is needed or the default user/pass can be used
#SuppressWarnings("rawtypes")
public static void main(String[] args) throws IOException {
// The altered wsdl file
URL url = new URL("file://"+System.getProperty("user.home")+"/onvif/devicemgmt.wsdl");
// This file was downloaded from the onvif website and added a mock service in order to make it complete:
// <wsdl:service name="DeviceService">
// <wsdl:port name="DevicePort" binding="tds:DeviceBinding">
// <soap:address location="http://localhost/onvif/device_service"/>
// </wsdl:port>
// </wsdl:service>
// The altered file was then used to generate java classes using $JAVA_HOME/bin/wsimport -Xnocompile -extension devicemgmt.wsdl
QName qname = new QName("http://www.onvif.org/ver10/device/wsdl", "DeviceService");
Service service = Service.create(url, qname);
Device device = service.getPort(Device.class);
BindingProvider bindingProvider = (BindingProvider)device;
// Add a security handler for the credentials
final Binding binding = bindingProvider.getBinding();
List<Handler> handlerList = binding.getHandlerChain();
if (handlerList == null)
handlerList = new ArrayList<Handler>();
handlerList.add(new SecurityHandler());
binding.setHandlerChain(handlerList);
// Set the actual web services address instead of the mock service
Map<String, Object> requestContext = bindingProvider.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://"+ip+"/onvif/device_service");
// Read the time from the server
SystemDateTime systemDateAndTime = device.getSystemDateAndTime();
// Mark the local time (no need for an actual clock, the monotone counter will do just fine)
clientTime = System.nanoTime()/1000000;
// Generate the server time in msec since epoch
DateTime utcDateTime = systemDateAndTime.getUTCDateTime();
org.onvif.ver10.schema.Date date = utcDateTime.getDate();
Time time = utcDateTime.getTime();
Calendar c = new GregorianCalendar(utc);
c.set(date.getYear(), date.getMonth()-1, date.getDay(), time.getHour(), time.getMinute(), time.getSecond());
System.out.println(sdf.format(c.getTime()));
serverTime = c.getTimeInMillis();
// Now try and read something interesting
Holder<String> manufacturer = new Holder<String>();
Holder<String> model = new Holder<String>();
Holder<String> firmwareVersion = new Holder<String>();
Holder<String> serialNumber = new Holder<String>();
Holder<String> hardwareId = new Holder<String>();
device.getDeviceInformation(manufacturer, model, firmwareVersion, serialNumber, hardwareId);
System.out.println(manufacturer.value);
System.out.println(model.value);
System.out.println(firmwareVersion.value);
System.out.println(serialNumber.value);
System.out.println(hardwareId.value);
}
// Calcualte the password digest from a concatenation of the nonce, the creation time and the password itself
private static String calculatePasswordDigest(byte[] nonceBytes, String created, String password) {
String encoded = null;
try {
MessageDigest md = MessageDigest.getInstance( "SHA1" );
md.reset();
md.update( nonceBytes );
md.update( created.getBytes() );
md.update( password.getBytes() );
byte[] encodedPassword = md.digest();
encoded = Base64.encode(encodedPassword);
} catch (NoSuchAlgorithmException ex) {
}
return encoded;
}
// Calculate what time is it right now on the server
private static String localToGmtTimestamp() {
return sdf.format(new Date(System.nanoTime()/1000000 - clientTime + serverTime));
}
// This handler will add the authentication parameters
private static final class SecurityHandler implements SOAPHandler<SOAPMessageContext> {
#Override
public boolean handleMessage(final SOAPMessageContext msgCtx) {
// Indicator telling us which direction this message is going in
final Boolean outInd = (Boolean) msgCtx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// Handler must only add security headers to outbound messages
if (outInd.booleanValue() && clientTime!=0 && user!=null && pass!=null) {
try {
// Create the timestamp
String timestamp = localToGmtTimestamp();
// Generate a random nonce
byte[] nonceBytes = new byte[16];
for (int i=0 ; i<16 ; ++i)
nonceBytes[i] = (byte)(Math.random()*256-128);
// Digest
String dig=calculatePasswordDigest(nonceBytes, timestamp, pass);
// Create the xml
SOAPEnvelope envelope = msgCtx.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
if (header == null)
header = envelope.addHeader();
SOAPElement security =
header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse");
SOAPElement username =
usernameToken.addChildElement("Username", "wsse");
username.addTextNode(user);
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
password.addTextNode(dig);
SOAPElement nonce =
usernameToken.addChildElement("Nonce", "wsse");
nonce.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonce.addTextNode(Base64.encode(nonceBytes));
SOAPElement created = usernameToken.addChildElement("Created", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
created.addTextNode(timestamp);
} catch (final Exception e) {
e.printStackTrace();
return false;
}
}
return true;
}
// Other required methods on interface need no guts
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
#Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}
}
I would recommend using wsimport command to generate the web service client to consume the web services.
The command can be executed from cmd prompt,
wsimport -d D:\WS-Client -extension -keep -XadditionalHeaders http://path-to-your-webserbice-wsdl-file/sampleWSDL?wsdl
After execution of the above command all the generated .class files and .java (source) files will be placed inside D:\WS-Client folder with proper package structure as mentioned in the wsdl file.
just ignore the .class files and copy entire package folder and include it in your consumer project to use it.
It will be like, you have the deployed web services in your source code. Just call the methods from the service classes and ohhla :)
The WSDL you were provided is invalid. Most likely due to the extensive documentation tags that were used in it. You can verify this by trying to load it in SoapUI. Your best bet is to contact the vendor to find out if they have a cleaner version of the WSDL they can provide you.
first you want to deploy your web service project on any server means tomcat or other.
after that use the running server WSDL file URL for create the client.