SOAP Debug message not getting printed - web-services

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?

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?

how to get Soap action from wsdl and generated java files. as my wsdl imports another wsdl which has #webmethod in it

i have a wsdl which is importing another wsdl in it.
i wanted to call the webservice from java client code, i have configured my java class as follows
package test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
#Configuration
public class WeConfig {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("test");
return marshaller;
}
#Bean
public WeatherClient1 weatherClient(Jaxb2Marshaller marshaller) {
WeatherClient1 client = new WeatherClient1();
client.setDefaultUri("*******");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
I have my acessing method as follows
GetDataResponse response = (GetDataResponse) getWebServiceTemplate()
.marshalSendAndReceive(
"*******",
request,
new SoapActionCallback("*******"));
My webservice would be something like
https://abcde.handling.com/celebrity/Confi?wsdl
Kindly let me know , what i have to input in setdefaultUri in configuration and soapcallbackaction. soap Ui gives me a method "GetData" for request
Thanks in advance..
Please help ..
After a long struggle , the answer for this query will be as follows;
DefaultUri = (Full WSDL) https://abcde.handling.com/celebrity/Confi?wsdl
there was no call back action for my request so:
GetDataResponse response = (GetDataResponse) getWebServiceTemplate()
.marshalSendAndReceive(
"Imported wsdl's URI",
request);

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

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);
}

Disable auto generated JAX-WS Status Page

When I deploy and run my web service developed with JAX-WS I can see a summary page with some info on it, something like in this picture:
http://www.mkyong.com/webservices/jax-ws/deploy-jax-ws-web-services-on-tomcat/
For the final implementation we would like to remove this page so that a custom or a blank page is returned while still having access to the web service endpoint.
We are currently running on Tomcat.
There is a field on the WSServlet class that might do what you are looking for: JAXWS_RI_PROPERTY_PUBLISH_STATUS_PAGE (it's value is com.sun.xml.ws.server.http.publishStatusPage).
Looking at the source code from a JAX-WS download it seems that you need to set it as a context parameter in your web.xml file:
<web-app>
<context-param>
<param-name>com.sun.xml.ws.server.http.publishStatusPage</param-name>
<param-value>false</param-value>
</context-param>
...
Seems that HttpAdapter had something similar on it but was taken from an environment variable:
setPublishStatus(
System.getProperty(HttpAdapter.class.getName() + ".publishStatusPage")
.equals("true"));
The code on HttpAdapter is marked deprecated in the javadoc so the context parameter seems the way to go.
I have been trying to solve this for two days, Glassfish 3.1.2.
The only solution was to have
-Dcom.sun.xml.ws.transport.http.HttpAdapter.publishStatusPage=false
I know its old, but wantd to maintain the knowledge. Hope this helps any one with this issue.
I have completed the same task for WebLogic recently.
It was requested to hide/show a status page of a public web service depending on a target environment i.e. hide for production, show for dev.
Nothing of the previous answers worked for me.
The success solution is based on implementation of javax.servlet.Filter.
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.HttpMethod;
#WebFilter(urlPatterns = { "/WeblogicWebService" })
public class FilterStatusSoapPage implements Filter {
#Value("${soap.status.page.disabled}")
private boolean flagDisablePublishStatusPage;
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpRes = (HttpServletResponse) response;
String queryString = httpReq.getQueryString();
if(flagDisablePublishStatusPage)
if(queryString == null || queryString.trim().isEmpty())
if(HttpMethod.GET.matches(httpReq.getMethod())) {
httpRes.setStatus(HttpServletResponse.SC_OK);
httpRes.getWriter().write("Access to status page of Web
Service is not allowed");
httpRes.getWriter().flush();
httpRes.getWriter().close();
return;
}
} catch (Exception e) {
System.err.println("Error on FilterStatusSoapPage filter");
chain.doFilter(request, response);
return;
}
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {}
public void destroy() {}
}

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.