How to log HttpClient requests, response including body? - jetty

Jersey provides an excellent client-side logging facility that looks like this:
INFO: 1 * Server has received a request on thread grizzly-http-server-0
1 > GET http://localhost:9998/helloworld
1 > accept: text/plain
1 > accept-encoding: gzip,deflate
1 > connection: Keep-Alive
1 > host: localhost:9998
1 > user-agent: Jersey/3.0-SNAPSHOT (Apache HttpClient 4.5)
INFO: 1 * Server responded with a response on thread grizzly-http-server-0
1 < 200
1 < Content-Type: text/plain
Hello World!
We see the worker thread, request method, URI, headers and the response code, headers, and body.
Is there an equivalent functionality for Jetty? Or do we need to roll our own?

I ended up implementing this myself, with slight variations on the Jetty format:
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicLong;
import static org.bitbucket.cowwoc.requirements.core.Requirements.requireThat;
/**
* Logs HttpClient request/response traffic.
*
* #author Gili Tzabari
*/
public final class RequestLogger
{
/**
* {#code true} if request values should be grouped together, and response values should be grouped together to improve readability.
* {#code false} if events should be logged as soon as they arrive (useful when diagnosing performance problems).
*/
private static final boolean IMPROVED_READABILITY = true;
private final AtomicLong nextId = new AtomicLong();
private final Logger log = LoggerFactory.getLogger(RequestLogger.class);
/**
* Attaches event listeners to a request.
*
* #param request the request to listen to
* #return the request
* #throws NullPointerException if {#code request} is null
*/
public Request listenTo(Request request)
{
requireThat("request", request).isNotNull();
if (IMPROVED_READABILITY)
improvedReadability(request);
else
correctTiming(request);
return request;
}
/**
* Group events for improved readability.
*
* #param request the request to listen to
*/
private void improvedReadability(Request request)
{
long id = nextId.getAndIncrement();
StringBuilder group = new StringBuilder();
request.onRequestBegin(theRequest -> group.append("Request " + id + "\n" +
id + " > " + theRequest.getMethod() + " " + theRequest.getURI() + "\n"));
request.onRequestHeaders(theRequest ->
{
for (HttpField header : theRequest.getHeaders())
group.append(id + " > " + header + "\n");
});
StringBuilder contentBuffer = new StringBuilder();
request.onRequestContent((theRequest, content) ->
contentBuffer.append(ByteBuffers.toString(content, getCharset(theRequest.getHeaders()))));
request.onRequestSuccess(theRequest ->
{
if (contentBuffer.length() > 0)
{
group.append("\n" +
contentBuffer.toString());
}
log.debug(group.toString());
contentBuffer.delete(0, contentBuffer.length());
group.delete(0, group.length());
});
request.onResponseBegin(theResponse ->
{
group.append("Response " + id + "\n" +
id + " < " + theResponse.getVersion() + " " + theResponse.getStatus());
if (theResponse.getReason() != null)
group.append(" " + theResponse.getReason());
group.append("\n");
});
request.onResponseHeaders(theResponse ->
{
for (HttpField header : theResponse.getHeaders())
group.append(id + " < " + header + "\n");
});
request.onResponseContent((theResponse, content) ->
contentBuffer.append(ByteBuffers.toString(content, getCharset(theResponse.getHeaders()))));
request.onResponseSuccess(theResponse ->
{
if (contentBuffer.length() > 0)
{
group.append("\n" +
contentBuffer.toString());
}
log.debug(group.toString());
});
}
/**
* Log events as they come in.
*
* #param request the request to listen to
*/
private void correctTiming(Request request)
{
long id = nextId.getAndIncrement();
request.onRequestBegin(theRequest -> log.debug(id + " > " + theRequest.getMethod() + " " + theRequest.getURI()));
request.onRequestHeaders(theRequest ->
{
for (HttpField header : theRequest.getHeaders())
log.debug(id + " > " + header);
});
request.onRequestContent((theRequest, content) -> log.debug(id + " >> " +
ByteBuffers.toString(content, getCharset(theRequest.getHeaders()))));
request.onResponseBegin(theResponse ->
{
StringBuilder line = new StringBuilder(id + " < " + theResponse.getVersion() + " " + theResponse.getStatus());
if (theResponse.getReason() != null)
line.append(" " + theResponse.getReason());
log.debug(line.toString());
});
request.onResponseHeaders(theResponse ->
{
for (HttpField header : theResponse.getHeaders())
log.debug(id + " < " + header);
});
StringBuilder responseBody = new StringBuilder();
request.onResponseContent((theResponse, content) ->
responseBody.append(ByteBuffers.toString(content, getCharset(theResponse.getHeaders()))));
request.onResponseSuccess(theResponse -> log.debug(id + " << " + responseBody));
}
/**
* #param headers HTTP headers
* #return the charset associated with the request or response body
*/
private Charset getCharset(HttpFields headers)
{
String contentType = headers.get(HttpHeader.CONTENT_TYPE);
if (contentType == null)
return StandardCharsets.UTF_8;
String[] tokens = contentType.toLowerCase(Locale.US).split("charset=");
if (tokens.length != 2)
return StandardCharsets.UTF_8;
// Remove semicolons or quotes
String encoding = tokens[1].replaceAll("[;\"]", "");
return Charset.forName(encoding);
}
}
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import static org.bitbucket.cowwoc.requirements.core.Requirements.requireThat;
/**
* ByteBuffer helper functions.
*
* #author Gili Tzabari
*/
public final class ByteBuffers
{
/**
* #param buffer a {#Code ByteBuffer}
* #param charset the character set of the bytes
* #return the {#code String} representation of the bytes
*/
public static String toString(ByteBuffer buffer, Charset charset)
{
requireThat("buffer", buffer).isNotNull();
byte[] bytes;
if (buffer.hasArray())
bytes = buffer.array();
else
{
bytes = new byte[buffer.remaining()];
buffer.get(bytes, 0, bytes.length);
}
return new String(bytes, charset);
}
/**
* Prevent construction.
*/
private ByteBuffers()
{
}
}
Usage:
Request request = new HttpClient().newRequest("http://www.test.com/");
new RequestLogger().listenTo(request).send();

Related

How to start the stream processor in Amazon Rekognition

I followed the AWS Rekognition Developer Guide and wrote a stream processor using CreateStreamProcessor in Java.
import com.amazonaws.services.rekognition.AmazonRekognition;
import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder;
import com.amazonaws.services.rekognition.model.*;
public class StreamProcessor {
private String streamProcessorName;
private String kinesisVideoStreamArn;
private String kinesisDataStreamArn;
private String roleArn;
private String collectionId;
private float matchThreshold;
private AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.defaultClient();
public void createStreamProcessor() {
KinesisVideoStream kinesisVideoStream = new KinesisVideoStream().withArn(kinesisVideoStreamArn);
StreamProcessorInput streamProcessorInput = new StreamProcessorInput().withKinesisVideoStream(kinesisVideoStream);
KinesisDataStream kinesisDataStream = new KinesisDataStream().withArn(kinesisDataStreamArn);
StreamProcessorOutput streamProcessorOutput = new StreamProcessorOutput().withKinesisDataStream(kinesisDataStream);
FaceSearchSettings faceSearchSettings = new FaceSearchSettings().withCollectionId(collectionId)
.withFaceMatchThreshold(matchThreshold);
StreamProcessorSettings streamProcessorSettings = new StreamProcessorSettings().withFaceSearch(faceSearchSettings);
CreateStreamProcessorResult createStreamProcessorResult = rekognitionClient.createStreamProcessor(
new CreateStreamProcessorRequest().withInput(streamProcessorInput).withOutput(streamProcessorOutput)
.withSettings(streamProcessorSettings).withRoleArn(roleArn).withName(streamProcessorName));
System.out.println("StreamProcessorArn - " +
createStreamProcessorResult.getStreamProcessorArn());
}
public void startStreamProcessor() {
StartStreamProcessorResult startStreamProcessorResult = rekognitionClient.startStreamProcessor(
new StartStreamProcessorRequest().withName(streamProcessorName));
}
public void stopStreamProcessorSample() {
StopStreamProcessorResult stopStreamProcessorResult = rekognitionClient.stopStreamProcessor(
new StopStreamProcessorRequest().withName(streamProcessorName));
}
public void deleteStreamProcessorSample() {
DeleteStreamProcessorResult deleteStreamProcessorResult = rekognitionClient.deleteStreamProcessor(
new DeleteStreamProcessorRequest().withName(streamProcessorName));
}
public void describeStreamProcessorSample() {
DescribeStreamProcessorResult describeStreamProcessorResult = rekognitionClient.describeStreamProcessor(
new DescribeStreamProcessorRequest().withName(streamProcessorName));
System.out.println("Arn - " + describeStreamProcessorResult.getStreamProcessorArn());
System.out.println("Input kinesisVideo stream - " + describeStreamProcessorResult.getInput()
.getKinesisVideoStream().getArn());
System.out.println("Output kinesisData stream - " + describeStreamProcessorResult.getOutput()
.getKinesisDataStream().getArn());
System.out.println("RoleArn - " + describeStreamProcessorResult.getRoleArn());
System.out.println("CollectionId - " + describeStreamProcessorResult.getSettings().getFaceSearch()
.getCollectionId());
System.out.println("Status - " + describeStreamProcessorResult.getStatus());
System.out.println("Status message - " + describeStreamProcessorResult.getStatusMessage());
System.out.println("Creation timestamp - " + describeStreamProcessorResult.getCreationTimestamp());
System.out.println("Last updatClient rekognitionClient = new AmazonRekognitionClient()e timestamp - "
+ describeStreamProcessorResult.getLastUpdateTimestamp());
}
public void listStreamProcessorSample() {
ListStreamProcessorsResult listStreamProcessorsResult = rekognitionClient.listStreamProcessors(
new ListStreamProcessorsRequest().withMaxResults(100));
for (com.amazonaws.services.rekognition.model.StreamProcessor streamProcessor :
listStreamProcessorsResult.getStreamProcessors()) {
System.out.println("StreamProcessor name - " + streamProcessor.getName());
System.out.println("Status - " + streamProcessor.getStatus());
}
}
}
But I can't figure out how to start the stream processor? Do I have to simply write the main method and call createStreamProcessor() function? Or do I have to do something else: like the guide mentioned something as StartStreamProcessor?
Yes, you have to start the stream preprocessor by using following API:
https://docs.aws.amazon.com/rekognition/latest/dg/API_StartStreamProcessor.html
rekognitionClient.startStreamProcessor(name= "my-stream-1")

How to prevent < converted to < when using web service proxy class in JDeveloper

I am calling a BPM web service that sends HTML email. I generated a web service proxy in JDeveloper 11.1.1.7. The type of the body of the email is xsd:string which should map to java String. I understand that certain characters, for example < > &, are reserved and converted during the xml document creation during the proxy operation.
Using SOAPUI to call the service, I can pass the body as <h1>My Heading</h1> and service responds correctly, sending the email with HTML as expected. When doing the same from a POJO that calls the proxy, <h1> is converted to <h1>My heading</h1>.
I have tried passing the body as a CDATA section but this makes no difference. I have tried converting the body to bytes then back to a UTF-8 string before the call but still no difference. I have access to the BPM service code. Is there a way I can send html to the service from a proxy, that retains the special characters?
I figured this out finally. While the JDeveloper web service proxy generator is useful most of the time, in this case it was not since I needed to send xml special characters to the service. Perhaps there is a way to manipulate the proxy code to do what you want but I couldn't figure it out.
Of particular help was this AMIS blog entry. And if you ever need to handle special characters during JAXB marshalling, this entry will help you too. A great summary of the steps to use the java URLConnection class is here and that answer points to a library that would probably make life even easier.
So here is the raw wrapper code below. The particular BPM email service we wrote also writes to a log and that explains the complex types in the raw xml input. Naturally I will populate the email values from a passed in POJO object in the main sendMail wrapper method.
package com.yourdomain.sendmail.methods;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import oracle.adf.model.connection.url.URLConnectionProxy;
import oracle.adf.share.ADFContext;
public class SendMailWrapper {
public SendMailWrapper() {
super();
}
public static void main(String[] args) throws MalformedURLException, IOException {
SendMailWrapper w = new SendMailWrapper();
w.sendMail();
}
public void sendMail() throws MalformedURLException, IOException {
String xmlInput =
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:sen=\"http://xmlns.oracle.com/bpmn/bpmnProcess/SendEmailProcess\" " +
"xmlns:ema=\"http://www.wft.com/BPM/SendEmail/Email\">\n" +
"<soapenv:Header/>" +
"<soapenv:Body>\n" +
"<sen:start>\n" +
"<ema:emailInput>\n" +
"<ema:emailContent>\n" +
"<ema:toAddr>your.name#yourdomain.com</ema:toAddr>\n" +
"<ema:fromAddr></ema:fromAddr>\n" +
"<ema:ccAddr></ema:ccAddr>\n" +
"<ema:bccAddr></ema:bccAddr>\n" +
"<ema:subject>SendMail HTML</ema:subject>\n" +
"<ema:body><h1>My Heading</h1><p>Text</p></ema:body>\n" +
"<ema:contentType>text/html</ema:contentType>\n" +
"</ema:emailContent>\n" +
"<ema:emailHistory>\n" +
"<ema:projectName>Soap Test</ema:projectName>\n" +
"<ema:reqID></ema:reqID>\n" +
"<ema:compositeID></ema:compositeID>\n" +
"<ema:processID></ema:processID>\n" +
"<ema:processName></ema:processName>\n" +
"<ema:activityName></ema:activityName>\n" +
"<ema:insertDate></ema:insertDate>\n" +
"<ema:insertByID></ema:insertByID>\n" +
"<ema:insertByName></ema:insertByName>\n" +
"<ema:commentType></ema:commentType>\n" +
"<ema:commentInfo></ema:commentInfo>\n" +
"</ema:emailHistory>\n" +
"</ema:emailInput>\n" +
"</sen:start>\n" +
"</soapenv:Body>\n" +
"</soapenv:Envelope>\n";
System.out.println(xmlInput);
String wsURL = getWsdlUrl();
URL url = new URL(wsURL);
URLConnection connection = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection)connection;
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[xmlInput.length()];
buffer = xmlInput.getBytes();
bout.write(buffer);
byte[] b = bout.toByteArray();
String SOAPAction = "start"; //this is the method in the service
httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
httpConn.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");
//some other props available but don't need to be set...
//httpConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
//httpConn.setRequestProperty("Host", "your.host.com:80");
//httpConn.setRequestProperty("Connection", "Keep-Alive");
//httpConn.setRequestProperty("User-Agent", "Apache-HttpClient/4.1.1 (java 1.5)");
httpConn.setRequestProperty("SOAPAction", SOAPAction);
httpConn.setRequestMethod("POST");
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
OutputStream out = httpConn.getOutputStream();
out.write(b);
out.close();
//check response code...
int status = httpConn.getResponseCode();
String respMessage = httpConn.getResponseMessage();
System.out.println("RESPONSE CODE: " + status + " RESPONSE MESSAGE: " + respMessage);
//check response headers...
for (Map.Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
//check error stream - this helps alot when debugging...
InputStream errorStream = ((HttpURLConnection)connection).getErrorStream();
if (errorStream != null) {
System.out.println("Error Stream: " + convertStreamToString(errorStream));
}
//if there was an expected response, you need to parse it...
/* String responseString = "";
String outputString = "";
InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
BufferedReader in = new BufferedReader(isr);
while ((responseString = in.readLine()) != null) {
outputString = outputString + responseString;
}
isr.close();
System.out.println("OUT: " + outputString); */
}
static String convertStreamToString(InputStream is) {
Scanner s = new Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
private static String getWsdlUrl() {
String result = null;
try {
URLConnectionProxy wsConnection = (URLConnectionProxy)ADFContext.getCurrent().getConnectionsContext().lookup("SendMailProxyConnection");
result = wsConnection.getURL().toExternalForm();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
Happy coding.

Warning message when calling a SOAP webservice

I'm getting this warning message when trying to call a SOAP webservice
May 28, 2014 10:25:39 AM com.sun.xml.ws.transport.http.HttpAdapter fixQuotesAroundSoapAction
INFO: Received WS-I BP non-conformant Unquoted SoapAction HTTP header: /performAction
Can someone tell me how to fix it?
Below is the code responsible for this warning,
/**
*
* #param con
* #param codec
* #return
* #throws IOException
* ExceptionHasMessage exception that contains particular fault message
* UnsupportedMediaException to indicate to send 415 error code
*/
private Packet decodePacket(#NotNull WSHTTPConnection con, #NotNull Codec codec) throws IOException {
String ct = con.getRequestHeader("Content-Type");
InputStream in = con.getInput();
Packet packet = new Packet();
packet.soapAction = fixQuotesAroundSoapAction(con.getRequestHeader("SOAPAction"));
packet.wasTransportSecure = con.isSecure();
packet.acceptableMimeTypes = con.getRequestHeader("Accept");
packet.addSatellite(con);
packet.transportBackChannel = new Oneway(con);
packet.webServiceContextDelegate = con.getWebServiceContextDelegate();
if (dump) {
ByteArrayBuffer buf = new ByteArrayBuffer();
buf.write(in);
in.close();
dump(buf, "HTTP request", con.getRequestHeaders());
in = buf.newInputStream();
}
codec.decode(in, ct, packet);
return packet;
}
/**
* Some stacks may send non WS-I BP 1.2 conformant SoapAction.
* Make sure SOAPAction is quoted as {#link Packet#soapAction} expectsa quoted soapAction value.
*
* #param soapAction SoapAction HTTP Header
* #return
*/
private String fixQuotesAroundSoapAction(String soapAction) {
if(soapAction != null && (!soapAction.startsWith("\"") || !soapAction.endsWith("\"")) ) {
LOGGER.warning("Received WS-I BP non-conformant Unquoted SoapAction HTTP header: "+ soapAction);
String fixedSoapAction = soapAction;
if(!soapAction.startsWith("\""))
fixedSoapAction = "\"" + fixedSoapAction;
if(!soapAction.endsWith("\""))
fixedSoapAction = fixedSoapAction + "\"";
return fixedSoapAction;
}
return soapAction;
}
The SOAP Action consists of the namespace and the actual method needs to call.
Furthermore, the SOAP Action needs to be encapsulated in " " to work.
Below helper method can be used to generate SOAP Action:
public String getSoapAction(String method) {
return "\"" + NAMESPACE + method + "\"";
}
Hope this will answer your question.

Receiving a Version Mismatch SOAP Fault even if Correct namespaces are used

I am using apache commons httpclient version 4.2 to execute a simple web service based on SOAP 1.2. I am able to fire the web service properly through SOAP UI but I am unable to do the same using Java.
Following is the method I'm using to invoke the service.
private static byte[] callSOAPServer(String body, String SOAP_ACTION,
String SERVER_URL) {
byte[] result = null;
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 15000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 35000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters);
/*
* httpclient.getCredentialsProvider().setCredentials( new
* AuthScope("os.icloud.com", 80, null, "Digest"), new
* UsernamePasswordCredentials(username, password));
*/
HttpPost httppost = new HttpPost(SERVER_URL);
httppost.setHeader("soapaction", SOAP_ACTION);
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
System.out.println("executing request" + httppost.getRequestLine());
// now create a soap request message as follows:
final StringBuffer soap = new StringBuffer();
soap.append("\n");
soap.append("");
// this is a sample data..you have create your own required data BEGIN
soap.append(" \n");
soap.append(" \n");
soap.append("" + body);
soap.append(" \n");
soap.append(" \n");
/* soap.append(body); */
// END of MEssage Body
soap.append("");
System.out.println("SOAP Request : " + soap.toString());
// END of full SOAP request message
try {
HttpEntity entity = new StringEntity(soap.toString(), HTTP.UTF_8);
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);// calling
// server
HttpEntity r_entity = response.getEntity(); // get response
System.out.println("Reponse Header:Begin..."); // response headers
System.out.println("Reponse Header StatusLine:"
+ response.getStatusLine());
Header[] headers = response.getAllHeaders();
for (Header h : headers) {
System.out.println("Reponse Header " + h.getName() + ": "
+ h.getValue());
}
System.out.println("Reponse Header END...");
if (r_entity != null) {
result = new byte[(int) r_entity.getContentLength()];
if (r_entity.isStreaming()) {
DataInputStream is = new DataInputStream(
r_entity.getContent());
is.readFully(result);
}
}
} catch (Exception E) {
System.out.println("Exception While Connecting " + E.getMessage());
E.printStackTrace();
}
httpclient.getConnectionManager().shutdown(); // shut down the
// connection
return result;
}
Following is my SOAP Request as well as the end point.
String soapRequest = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:typ=\"http://skash.service.sahaj.com/types/\">"
+ "<soap:Header/>"
+ "<soap:Body>"
+ "<typ:remoteSKASHDeductionElement>"
+ "<typ:vleId>?</typ:vleId>"
+ "<typ:paidAmt>?</typ:paidAmt>"
+ "<typ:refTxnId>?</typ:refTxnId>"
+ "</typ:remoteSKASHDeductionElement>"
+ "</soap:Body>"
+ "</soap:Envelope>";
String soapEndPoint = "http://xxx.xxx.xxx.xxx:xxxx/skashws/remoteSKASHDeductionSoap12HttpPort";
String soapAction = "http://xxx.xxx.xxx.xxx:xxxx//remoteSKASHDeduction";
// executeSOAPRequest(soapRequest, soapEndPoint, soapAction);
byte[] resp = callSOAPServer(soapRequest, soapAction, soapEndPoint);
System.out.println(IOUtils.toString(resp));
I can see that the namespace set to Envelope tag is for SOAP 1.2 and is well set. I am not sure where I'm going wrong. I am receiving the following version mismatch error.
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<env:Upgrade>
<env:SupportedEnvelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" qname="soap12:Envelope"/>
</env:Upgrade>
</env:Header>
<env:Body>
<env:Fault xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<faultcode>env:VersionMismatch</faultcode>
<faultstring>Version Mismatch</faultstring>
<faultactor>http://schemas.xmlsoap.org/soap/actor/next</faultactor>
</env:Fault>
</env:Body>
you may use this code block
public class GenericSoapMessageFactory extends SaajSoapMessageFactory implements InitializingBean {
#Override
public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
setMessageFactoryForRequestContext(soap11);
if (inputStream instanceof TransportInputStream) {
TransportInputStream transportInputStream = (TransportInputStream) inputStream;
if (soapProtocolChooser.useSoap12(transportInputStream)) {
setMessageFactoryForRequestContext(soap12);
}
}
SaajSoapMessageFactory mf = getMessageFactoryForRequestContext();
return mf.createWebServiceMessage(inputStream);
}
}
And web.xml params
<servlet>
<servlet-name>spring-ws2</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>messageFactoryBeanName</param-name>
<param-value>genericSoapMessageFactory</param-value>
</init-param>
</servlet>
I saw this error once and I changed the following line;
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
to
httppost.setHeader("Content-Type", "application/soap+xml;charset=UTF-8;");
and it fixed the issue. Try it.

Unable to read the SharePoint List using java

Here i am trying to read the list of sharepoint. For this i have done the following:
I have downloaded the WSDL file which i got from The URL like: sharepointsite.com/_vti_bin/Lists.asmx?WSDL.
and i have executed the following command to generate the classes in the directory
“C:\Program Files\Java\jdk1.6.0_12\bin\wsimport.exe” -p com.microsoft.schemas.sharepoint.soap -keep -extension Lists.wsdl.
Imported those classes in my eclipse IDE java application.
and i have written the following code
/* Creates a port connected to the SharePoint Web Service given.
* Authentication is done here. It also prints the authentication details
* in the console.
* #param userName SharePoint username
* #param password SharePoint password
* #return port ListsSoap port, connected with SharePoint
* #throws Exception in case of invalid parameters or connection error.
*/
public static ListsSoap sharePointListsAuth(String userName, String password) throws Exception {
ListsSoap port = null;
if (userName != null && password != null) {
try {
Lists service = new Lists();
port = service.getListsSoap();
System.out.println("Web Service Auth Username: " + userName);
((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName);
((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, password);
} catch (Exception e) {
throw new Exception("Error: " + e.toString());
}
} else {
throw new Exception("Couldn't authenticate: Invalid connection details given.");
}
return port;
}
/**
* Creates a string from an XML file with start and end indicators
* #param docToString document to convert
* #return string of the xml document
*/
public static String xmlToString(Document docToString) {
String returnString = "\n-------------- XML START --------------\n";
try {
//create string from xml tree
//Output the XML
//set up a transformer
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans;
trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult streamResult = new StreamResult(sw);
DOMSource source = new DOMSource(docToString);
trans.transform(source, streamResult);
String xmlString = sw.toString();
//print the XML
returnString = returnString + xmlString;
} catch (TransformerException ex) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
}
returnString = returnString + "-------------- XML END --------------";
return returnString;
}
/**
02
* Connects to a SharePoint Lists Web Service through the given open port,
03
* and reads all the elements of the given list. Only the ID and the given
04
* attributes (column names) are displayed, as well as a dump of the SOAP
05
* response from the Web Service (for debugging purposes).
06
* #param port an already authentificated SharePoint Online SOAP port
07
* #param listName original name of the Sharepoint list that is going to be read
08
* #param listColumnNames arraylist containing the various names of the Columns
09
* of the SharePoint list that are going to be read. If the column name isn't
10
* found, then an exception will be thrown
11
* #param rowLimit limits the number of rows (list items) that are going to
12
* be returned
13
* #throws Exception
14
*/
public static void displaySharePointList(ListsSoap port, String listName, ArrayList<String> listColumnNames, String rowLimit) throws Exception {
if (port != null && listName != null && listColumnNames != null && rowLimit != null) {
try {
//Here are additional parameters that may be set
String viewName = "";
GetListItems.ViewFields viewFields = null;
GetListItems.Query query = null;
GetListItems.QueryOptions queryOptions = null;
String webID = "";
//Calling the List Web Service
GetListItemsResponse.GetListItemsResult result = port.getListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, webID);
Object listResult = result.getContent().get(0);
if ((listResult != null) && (listResult instanceof ElementNSImpl)) {
ElementNSImpl node = (ElementNSImpl) listResult;
//Dumps the retrieved info in the console
Document document = node.getOwnerDocument();
System.out.println("SharePoint Online Lists Web Service Response:" + Manager.xmlToString(document));
//selects a list of nodes which have z:row elements
NodeList list = node.getElementsByTagName("z:row");
System.out.println("=> " + list.getLength() + " results from SharePoint Online");
//Displaying every result received from SharePoint, with its ID
for (int i = 0; i < list.getLength(); i++) {
//Gets the attributes of the current row/element
NamedNodeMap attributes = list.item(i).getAttributes();
System.out.println("******** Item ID: " + attributes.getNamedItem("ows_ID").getNodeValue()+" ********");
//Displays all the attributes of the list item that correspond to the column names given
for (String columnName : listColumnNames) {
String internalColumnName = "ows_" + columnName;
if (attributes.getNamedItem(internalColumnName) != null) {
System.out.println(columnName + ": " + attributes.getNamedItem(internalColumnName).getNodeValue());
} else {
throw new Exception("Couldn't find the '" + columnName + "' column in the '" + listName + "' list in SharePoint.\n");
}
}
}
} else {
throw new Exception(listName + " list response from SharePoint is either null or corrupt\n");
}
} catch (Exception ex) {
throw new Exception("Exception. See stacktrace." + ex.toString() + "\n");
}
}
}
public static void main(String[] args) {
try {
//Authentication parameters
String userName = "domain\\username";
String password = "pass";
//Opening the SOAP port of the Lists Web Service
ListsSoap port = Manager.sharePointListsAuth(userName, password);
/*
* Lists Web service parameters
* The list names below must be the *original* names of the list.
* if a list or column was renamed from SharePoint afterwards,
* these parameters don't change.
*/
String listName = "listname";
String rowLimit = "2";
ArrayList<String> listColumnNames = new ArrayList<String>();
listColumnNames.add("Name");
listColumnNames.add("ID");
//Displays the lists items in the console
Manager.displaySharePointList(port, listName, listColumnNames, rowLimit);
} catch (Exception ex) {
System.err.println(ex);
}
}
I am getting following exception :
Web Service Auth Username: "domain\username"
java.lang.Exception: Exception. See stacktrace.javax.xml.ws.soap.SOAPFaultException: Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown.
It would be helpfull if i get the specific exception from the server.With this expection i am unable to track my pgm.
I dont know where did i go wrong? am i missing anything ? any configuration is required ?
Thanks in advance for your help
I had the same problem, try with an Authenticator :
new BasicAuthentication(userName,password).authenticate();
My BasicAuthentication class :
import java.net.Authenticator;
import java.net.PasswordAuthentication;
public class BasicAuthentication extends Authenticator
{
private String username;
private String password;
public BasicAuthentication(String username, String password)
{
this.username = username;
this.password = password;
}
public PasswordAuthentication getPasswordAuthentication()
{
return (new PasswordAuthentication(username,password.toCharArray()));
}
public void authenticate()
{
Authenticator.setDefault(this);
}
}