Spring RestTemplate credential/Authorization in header getting 401-unauthorized, where in postman it is working fine - postman

using postman, for a GET request with header values for user name and password
and successfully hitting a rest service and getting response 200.
But when trying to access same request by java code using spring RestTemplate getting 401-unauthorized issue.
this is the code
final String uri = "http://<host>:<port>/services/arecord";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("username", "admin");
String password = "admin";
map.add("password", password);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
try {
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET,
new HttpEntity(createHeaders("admin", "admin")), String.class);
String body = response.getBody();
} catch (HttpClientErrorException e) {
logger.info("****** ERROR *********** " + e.getMostSpecificCause());
return true;
}

I haven't tested it, but try something like this:
final String uri = "http://<host>:<port>/services/arecord";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("username", "admin");
headers.set("password", "admin");
HttpEntity entity = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
try {
ResponseEntity<String> response = restTemplate.exchange(
uri, HttpMethod.GET, entity, String.class);
String body = response.getBody();
} catch (HttpClientErrorException e) {
logger.info("****** ERROR *********** " + e.getMostSpecificCause());
return true;
}

Related

How can I read result of web api call from Dynamics 365?

I try to retrieve a record from Dynamics 365 Sales. I created an app registration in Azure and I can get tokens based on this app.
Also, I can call the HTTP client. But I couldn't figure out how to read the result of the HTTP call.
Microsoft published only WhoAmIRequest sample, but I couldn't find a sample of other entities.
Here is my sample code. I try to read body object.
try
{
string serviceUrl = "https://****.crm4.dynamics.com/";
string clientId = "******";
string clientSecret = "*******";
string tenantId = "*******";
A***.Library.Utility.MSCRM mscrm = new Library.Utility.MSCRM(serviceUrl, clientId, clientSecret, tenantId);
var token = await mscrm.GetTokenAsync();
Console.WriteLine(token);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(serviceUrl);
client.Timeout = new TimeSpan(0, 2, 0); //2 minutes
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "/api/data/v9.0/accounts");
// Set the access token
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
HttpResponseMessage response = client.SendAsync(request).Result;
if (response.IsSuccessStatusCode)
{
// Get the response content and parse it.
var responseStr = response.Content.ReadAsStringAsync();
JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
}
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
Here is the result of body object.
You can use either of these syntax to read values. Read more
JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
// Can use either indexer or GetValue method (or a mix of two)
body.GetValue("obs_detailerconfigid");
body["obs_detailerconfigid"];

SoapFaultClientException: username and/or/password cannot be null

I have build a client, that should fetch data from a remote, wsdl-based webservice (using SOAP).
But everytime I try to connect (with a call of a function) with the service I get the following exception:
org.springframework.ws.soap.client.SoapFaultClientException: Username and/or Password cannot be null
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38) ~[spring-ws-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:826) ~[spring-ws-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:621) ~[spring-ws-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) ~[spring-ws-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) ~[spring-ws-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
at com.test.adminUI.myPartners.client.MyPartnersServiceClient.sendSoapRequest(MyPartnersServiceClient.java:113) [bin/:na]
at com.test.adminUI.myPartners.client.MyPartnersServiceClient.findUser(PartnersServiceClient.java:70) [bin/:na]...
If I put a wrong password for example, the service registered it, an throws a Unauthorized 401 ERROR
So that mean, it actually validates my useraccount details.
my client:
public class MyServiceClient extends WebServiceGatewaySupport {
#Autowired
private ObjectFactory factory;
#Autowired
private SoapProperties adProperties;
private static final String WS_ADDRESSING_URI = "http://www.w3.org/2005/08/addressing";
private static final String TO_TAG = "To";
private static final String ACTION_TAG = "Action";
private static final String WSA_PREFIX = "wsa";
private static final String SOAP_ACTION_FIND_IFXPERSON = adProperties.getsoapURL();
public List<Person> findUser(String email, String globalID) {
List<Person> list = null;
FindPerson findperson = new FindPerson();
try {
findperson.setGlobalID(factory.createGlobalID(globalID));
findperson.setServiceUsername(factory.createServiceUsername(adProperties.getServiceUser()));
findperson.setServicePassword(factory.createServicePassword(adProperties.getServicePassword()));
FindPersonResponse response = (FindPersonResponse) sendSoapRequest(
SOAP_ACTION_FIND_PERSON, findperson);
list = response.getFindPersonResult().getValue();
} catch (Exception ex) {
log.error("could not find Person: ", ex);
}
return null;
}
private Object sendSoapRequest(final String soapAction, Object payLoad) {
Object response = null;
try {
Credentials auth = new NTCredentials(adProperties.getAuthUser(),
adProperties.getAuthPassword(), null, adProperties.getAuthDomain());
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(AuthScope.ANY, auth);
clientBuilder.setDefaultCredentialsProvider(credsProvider);
RemoveSoapHeadersInterceptor interceptor = new RemoveSoapHeadersInterceptor();
clientBuilder.addInterceptorFirst(interceptor);
HttpClient httpClient = clientBuilder.build();
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
messageSender.setHttpClient(httpClient);
messageSender.setCredentials(auth);
messageSender.afterPropertiesSet();
getWebServiceTemplate().setMessageSender(messageSender);
SaajSoapMessageFactory messageFactory = new SaajSoapMessageFactory(
MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL));
getWebServiceTemplate().setMessageFactory(messageFactory);
response = getWebServiceTemplate().marshalSendAndReceive(
adProperties.getServiceEndpoint(), payLoad, new SoapActionCallback(soapAction) {
public void doWithMessage(WebServiceMessage message) {
try {
SaajSoapMessage soapMessage = (SaajSoapMessage) message;
SOAPMessage saajMessage = soapMessage.getSaajMessage();
SOAPEnvelope envelope = saajMessage.getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
QName wsaToQName = new QName(WS_ADDRESSING_URI, TO_TAG, WSA_PREFIX);
SOAPHeaderElement wsaTo = header.addHeaderElement(wsaToQName);
wsaTo.setTextContent(adProperties.getServiceEndpoint());
QName wsaActionQName = new QName(WS_ADDRESSING_URI, ACTION_TAG,
WSA_PREFIX);
SOAPHeaderElement wsaAction = header
.addHeaderElement(wsaActionQName);
wsaAction.setTextContent(soapAction);
} catch (Exception e) {
log.error("", e);
}
}
});
} catch (Exception ex) {
log.error(ex);
}
return response;
}
}
Configuration:
#Configuration
public class MyPartnersServiceConfiguration {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.test.adminUI.myPartners.wsdl");
return marshaller;
}
#Bean
public IFXPartnersServiceClient iFXPartnersServiceClient(Jaxb2Marshaller marshaller) {
IFXPartnersServiceClient client = new IFXPartnersServiceClient();
client.setDefaultUri("http://test.idms.partnersservice");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
Does anybody know what i have to do?
Thanks in advance!
UPDATE
I forgot to mention, that I also get a warning in my console:
o.a.http.impl.auth.HttpAuthenticator: NEGOTIATE authentication error: No valid credentials provided (Mechanism level: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt))
Is this the problem? What do I have to do in this case?
#Bean
public IFXPartnersServiceClient iFXPartnersServiceClient(Jaxb2Marshaller marshaller) {
IFXPartnersServiceClient client = new IFXPartnersServiceClient();
client.setDefaultUri("http://test.idms.partnersservice");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
//Set messageSender to client
client.setMessageSender(httpComponentsMessageSender());
return client;
}

Cookies in Robospice

I want to use cookies in Robospice, I have spice service:
public class JsonSpiceService extends SpringAndroidSpiceService {
public RestTemplate createRestTemplate() {
RestTemplate restTemplate = new RestTemplate();
MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter();
FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
final List<HttpMessageConverter<?>> listHttpMessageConverters = restTemplate.getMessageConverters();
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
restTemplate.setRequestFactory( httpRequestFactory );
listHttpMessageConverters.add(jsonConverter);
listHttpMessageConverters.add(formHttpMessageConverter);
listHttpMessageConverters.add(stringHttpMessageConverter);
restTemplate.setMessageConverters(listHttpMessageConverters);
return restTemplate;
}
public CacheManager createCacheManager(Application application) throws CacheCreationException {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
classCollection.add(User.class);
JacksonObjectPersisterFactory jacksonObjectPersisterFactory = new JacksonObjectPersisterFactory(application);
cacheManager.addPersister(jacksonObjectPersisterFactory);
return cacheManager;
}
}
and my Request class:
public class Request extends SpringAndroidSpiceRequest<HttpModel> {
private Context context;
private HttpMethod httpMethod;
private MultiValueMap<String, String> body;
private String link;
private String what;
private Object object;
public Request(Context context, HttpMethod httpMethod, MultiValueMap<String, String> body, String link, String what, Object object) {
super(HttpModel.class);
this.context = context;
this.httpMethod = httpMethod;
this.body = body;
this.link = link;
this.what = what;
this.object = object;
}
#Override
public HttpModel loadDataFromNetwork() throws Exception {
HttpModel httpModel;
HttpHeaders headers = new HttpHeaders();
HttpEntity<?> requestEntity;
if (!what.equals(LOGIN)) {
headers.setContentType(MediaType.APPLICATION_JSON);
} else {
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
}
requestEntity = new HttpEntity<Object>(body, headers);
ResponseEntity<HttpModel> responseEntity = getRestTemplate().exchange(link, httpMethod, requestEntity, HttpModel.class);
httpModel = responseEntity.getBody();
return httpModel;
}
}
How can i get cookie from response?I try add CookieManager to my Request class, but dont'work:
final CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
In postman Cookie look like this:
enter link description here
CookieManager is used only for managing cookies in your application's WebViews.
You can use responseEntity.getHeaders().get(COOKIE). You can also try SET_COOKIE or SET_COOKIE2 keys instead of COOKIE, depending on your server's response.

Why is httpclient is refreshing the jsession id for every request?

I am trying to hit a url(login screen), get the jsessionid(J2EEJSESSIONID) and add it in the cookie store and in turn in to the context and hit the same url with credentials. I am expecting a login successful screen.
However i am bounced with the login screen again.
And, i printed the response header for both the hits. I am expecting both the response with the same J2EESESSIONID to maintain the session. Instead both the session ids are different. Pls help.
Pls find the code below:
HttpEntity entity = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
try{
// Initialization
HttpPost httpPost = new HttpPost("https://yyyyy.xxx.com/enl");
HttpClientExample httpClientExample = new HttpClientExample();
CookieStore cookieStore = new BasicCookieStore();
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpGet = new HttpGet("https://yyyyy.xxx.com/enl");
// Execute Get
HttpResponse httpResponse = httpClient.execute(httpGet, httpContext);
// Print the header for 1st url
org.apache.http.Header[] headers = httpResponse.getAllHeaders();
System.out.println("##### Header length::"+headers.length);
for(int i=0;i<headers.length; i++)
{
System.out.println("Header Name::"+headers[i].getName());
System.out.println("Header Val::"+headers[i].getValue());
}
// update Cookie for the next hit
org.apache.http.Header[] cookieHeaders = httpResponse.getHeaders("Set-Cookie");
String html = EntityUtils.toString(httpResponse.getEntity());
cookieStore = httpClientExample.updateCookieStore(cookieHeaders, cookieStore);
httpClient.setCookieStore(cookieStore);
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
// Setting the redirects since i received 302 error
httpClient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return false;
}
});
// Added because i received Circular redirect error
httpClient.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
// Execute Post with credentials
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://yyyyy.xxx.com", 443),
new UsernamePasswordCredentials("usr", "pswd"));
httpPost.setHeader("Cookie", "JSESSIONID="+ getSessionId(cookieHeaders));
HttpResponse response = httpClient.execute(httpPost, httpContext);
// Print the response
entity = response.getEntity();
InputStream content1 = (InputStream)entity.getContent();
System.out.println("############### 2nd #####################"+response.getStatusLine().getStatusCode());
BufferedReader in1 =
new BufferedReader (new InputStreamReader (content1));
String line1;
while ((line1 = in1.readLine()) != null) {
System.out.println(line1);
}
// Print the header for 2nd url
org.apache.http.Header[] headers1 = response.getAllHeaders();
System.out.println("##### Header length 2 ::"+headers1.length);
for(int i=0;i<headers1.length; i++)
{
System.out.println("Header Name 2 ::"+headers1[i].getName());
System.out.println("Header Val 2 ::"+headers1[i].getValue());
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally{
try {
EntityUtils.consume(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httpClient.getConnectionManager().shutdown();
}
}
private static String getSessionId(org.apache.http.Header[] headers) {
// TODO Auto-generated method stub
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
if(strArray[0].startsWith("J2EEJSESSION"))
{
System.out.println("cookieValueArray[0]:"+cookieValueArray[0]);
return cookieValueArray[0];
}
}
return null;
}
protected CookieStore updateCookieStore(org.apache.http.Header[] headers, CookieStore cookieStore)
{
for(int i=0;i<headers.length; i++)
{
String str = headers[i].getValue();
String[] strArray = str.split("=");
String[] cookieValueArray = strArray[1].split(";");
System.out.println(strArray[0]+"|"+cookieValueArray[0]);
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);
/*if(strArray[0].startsWith("J2EEJSESSION"))
{
cookie.setDomain("yyyyy.xxx.com");
}
else
{
cookie.setDomain(".xxx.com");
}*/
cookie.setDomain(".xxx.com");
cookie.setPath("/");
cookieStore.addCookie(cookie);
if(strArray[0].startsWith("J2EEJSESSION"))
{
BasicClientCookie cookie1 = new BasicClientCookie("JSESSIONID", "A"+cookieValueArray[0]);
cookie1.setDomain(".xxx.com");
cookie1.setPath("/");
cookieStore.addCookie(cookie1);
}
}
return cookieStore;
}
Another observation:
When i remove the "A" concat from the below snippet, i am not getting the J2EESESSIONID in the 2nd hit:
BasicClientCookie cookie = new BasicClientCookie(strArray[0], "A"+cookieValueArray[0]);
Found the answer on the same day I posted this question.. thought of sharing..
The answer is very simple.. For some reasons the authentication wasn't successful, hence the new jsessionId was created. Replaced "httpClient.getCredentialsProvider().setCredentials()" with "BasicNameValuePair" and it worked :)

SOAPConnection not handling gzip response

I am using SOAPConnection to to invoke a SOAP based web service. The request is sent with "Accept-Encoding: gzip,deflate" in the header.
I used fiddler to grab the response, it is gzipped compressed, but while deserializing the message, the SOAPConnection is giving an error saying "invalid utf-8" message.
I tried normal http post and the http response is able to unzip the response correctly. Do I need to set some attributes on SOAPConnection to get it to handle the gzip message?
I found this snippet doing the job
SOAPMessage response = conn.call(finalRequest, aUrl);
// The response is gzip encoded, so decompress the response.
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.writeTo(out);
byte[] barr = out.toByteArray();
InputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(barr));
Reader decoder = new InputStreamReader(gzipStream, "UTF-8");
BufferedReader buffered = new BufferedReader(decoder);
int n = 0;
char[] cbuf = new char[1024];
Writer w = new StringWriter();
while ((n = buffered.read(cbuf)) != -1) {
w.write(cbuf,0,n);
}
// the writer now contains unzipped message.
System.out.println(w.toString());
GZIP Request,Response form Server:
If the server is enable with GZip then the server sends gzip-compress text data. For this we need over a request with Http headers as:
Request: We must send a HTTP request containing the Accept-Encoding: gzip header.
Response: If gzip is enabled, the server should return the Content-Encoding: gzip header.
Soap WebServies:
a - Grahical Weather Endpoint HTTPS and its WSDL URL OnlineClient
Response Headers:
Content-Type:text/xml; charset=ISO-8859-1
Vary:Accept-Encoding
Content-Encoding:gzip
Plain Response - DemoOnline Webserice HTTP. for example see stackpostResponse Headers: Content-Type:application/soap+xml; charset=utf-8
Request the WebService using SOAPConnectiona and get response in GZIP compressed format:
public static String getGZIP(byte[] zipBytes) {
try {
GZIPInputStream gzipInput = new GZIPInputStream( new ByteArrayInputStream(zipBytes) );
return IOUtils.toString(gzipInput);
} catch (IOException e) {
throw new UncheckedIOException("Error while decompression!", e);
}
}
public static void getSOAPConnection(SOAPMessage soapMsg) throws Exception {
System.out.println("\n===== SOAPConnection =====");
MimeHeaders headers = soapMsg.getMimeHeaders();
headers.addHeader("SoapBinding", serverDetails.get("SoapBinding") );
headers.addHeader("MethodName", serverDetails.get("MethodName") );
headers.addHeader("SOAPAction", serverDetails.get("SOAPAction") );
headers.addHeader("Content-Type", serverDetails.get("Content-Type")); // InBound
headers.addHeader("Accept-Encoding", serverDetails.get("Accept-Encoding")); // OutBound
if (soapMsg.saveRequired()) soapMsg.saveChanges();
/*SOAPMessage message = MessageFactory.newInstance().createMessage(headers, new ByteArrayInputStream(TSOXML.getBytes()));*/
SOAPConnectionFactory newInstance = SOAPConnectionFactory.newInstance();
javax.xml.soap.SOAPConnection connection = newInstance.createConnection();
SOAPMessage resp = connection.call(soapMsg, getURL( serverDetails.get("SoapServerURI") ));
MimeHeaders mimeHeaders = resp.getMimeHeaders();
String[] header = mimeHeaders.getHeader("Content-Encoding");
String contentEoncoding = "";
if (header != null && header.length > 0) contentEoncoding = header[0].toString();
System.out.println("Content:"+contentEoncoding);
if (contentEoncoding.equalsIgnoreCase("GZIP")) {
System.out.println("SOAP Message in GZIP");
ByteArrayOutputStream out = new ByteArrayOutputStream();
resp.writeTo(out);
byte[] zipBytes = out.toByteArray();
String gZipString= getGZIP(zipBytes);
System.out.println("Response:"+ gZipString);
SOAPMessage soapMessage = getSOAPMessagefromDataXML(gZipString);
System.out.println("SOAP Message Object:\n"+soapMessage);
getSOAPXMLasString(soapMessage);
} else {
getSOAPXMLasString(resp);
}
}
Requesting SOAP WS using HTTPCline. The way SOAPUI requests:
public static void getHttpURLConnection_Core(SOAPMessage soapMsg) throws Exception {
System.out.println("\n===== java.net.HttpURLConnection =====");
URL url = new URL(null, serverDetails.get("SoapServerURI"));
String protocol = url.getProtocol();
System.out.println("Protocol: "+protocol);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT));
HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
connection.setReadTimeout(5 * 1000);
connection.setConnectTimeout(5 * 1000);
connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(true);
//String authString = username + ":" + password; // Authorization: Basic ZW9uMDE5XzAxOkVsaWFfMTIz
//String authMsg = "Basic " + Base64.encode(authString.getBytes());
//connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.AUTHORIZATION, authMsg);
((HttpURLConnection) connection).setRequestMethod("POST");
connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.ACCEPT, "text/xml");
connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.9");
connection.setRequestProperty("MethodName", serverDetails.get("MethodName") );
connection.setRequestProperty("SOAPAction", serverDetails.get("SOAPAction") );
connection.setRequestProperty("HTTP_ACCEPT_ENCODING", "gzip, deflate, br");
connection.setRequestProperty("Accept-Encoding", serverDetails.get("Accept-Encoding"));
String soapxmLasString = getSOAPXMLasString(soapMsg);
connection.setRequestProperty(javax.ws.rs.core.HttpHeaders.CONTENT_TYPE, "text/xml");// serverDetails.get("Content-Type")
connection.setRequestProperty( "Content-Length", String.valueOf(soapxmLasString.length()));
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
try {
dataOutputStream.writeBytes(soapxmLasString);
} finally {
dataOutputStream.close();
}
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(Calendar.getInstance().getTime());
System.out.println("TIme taken Date:"+date+", Time:"+ (end-start));
String contentEncoding = connection.getContentEncoding();
System.out.println("Encoding:"+ contentEncoding);
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
System.out.println("Response Code: " + responseCode + " " + responseMessage);
String xmlRply = null ;
String requestStatus = "Fail";
if (responseCode == HttpURLConnection.HTTP_OK) {
requestStatus = "Pass";
InputStream inputStream = connection.getInputStream();
xmlRply = getStreamContent(inputStream, contentEncoding);
} else { // Response Code: 500 Internal Server Error
InputStream errorStream = connection.getErrorStream();
xmlRply = getStreamContent(errorStream, contentEncoding);
}
System.out.println("Reply: " + xmlRply);
System.out.println("Request Status:"+ requestStatus);
}
public static String getStreamContent(InputStream input, String encoding) throws IOException {
byte[] httpRply;
String rply;
httpRply = IOUtils.toByteArray(input);
System.out.println("Byte Array:"+httpRply.toString());
if (encoding == null) {
rply = new String(httpRply);
} else if ( encoding.equalsIgnoreCase("GZIP") ) {
rply = getGZIP(httpRply);
} else { // "ISO-8859-1", ";TF-8"
rply = new String(httpRply, encoding);
}
return rply;
}
Working example where the Server response with GZIP format.
public class SOAP_Weather {
static final String PROXY_ADDRESS = "Proxy_*****.net";
static final int PROXY_PORT = 9400;
static HashMap<String, String> serverDetails = new HashMap<>();
static {
// https://graphical.weather.gov/xml/ : conus
serverDetails.put("SoapServerURI", "https://graphical.weather.gov:443/xml/SOAP_server/ndfdXMLserver.php");
serverDetails.put("SoapWSDL", "https://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php?wsdl");
serverDetails.put("SoapXML", "<ndf:CornerPoints xmlns:ndf=\"https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><sector xsi:type=\"xsd:string\">conus</sector></ndf:CornerPoints>");
serverDetails.put("SoapBinding", "ndfdXMLBinding");
serverDetails.put("MethodName", "CornerPoints");
serverDetails.put("SOAPAction", "https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#CornerPoints");
serverDetails.put("User-Agent", "Apache-HttpClient");
serverDetails.put("Accept-Encoding", "gzip,deflate,sdch");
serverDetails.put("Content-Type", "text/xml;charset=UTF-8");
}
public static void main(String[] args) throws Exception {
callSoapService();
}
public static void callSoapService( ) throws Exception{
String xmlData = serverDetails.get("SoapXML");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
Document docBody = dBuilder.parse(ips);
//docBody.createElementNS(DSIG_NS, "ds");
System.out.println("Data Document: "+docBody.getDocumentElement());
// Protocol 1.1=SOAP-ENV Content-Type:text/xml; charset=utf-8, 1.2=env Content-Type:application/soap+xml; charset=utf-8
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMsg = messageFactory.createMessage();
SOAPPart soapPart = soapMsg.getSOAPPart();
SOAPEnvelope soapEnv = soapPart.getEnvelope();
SOAPBody soapBody = soapEnv.getBody();
soapBody.addDocument(docBody);
// Invoke the webService.
System.out.println("Request SOAP Message:");
soapMsg.writeTo(System.out);
System.out.println("\n");
// Protocol 1.1=SOAP-ENV Content-Type:text/xml; charset=utf-8, 1.2=env Content-Type:application/soap+xml; charset=utf-8
SOAPEnvelope envelope = soapMsg.getSOAPPart().getEnvelope();
if (envelope.getElementQName().getNamespaceURI().equals("http://schemas.xmlsoap.org/soap/envelope/")) {
System.out.println("SOAP 1.1 NamespaceURI: http://schemas.xmlsoap.org/soap/envelope/");
serverDetails.put("Content-Type", "text/xml; charset=utf-8");
} else {
System.out.println("SOAP 1.2 NamespaceURI: http://www.w3.org/2003/05/soap-envelope");
serverDetails.put("Content-Type", "application/soap+xml; charset=utf-8");
}
getSOAPConnection(soapMsg); // Disadvantage 1:
getHttpURLConnection_Core(soapMsg);
}
private static URL getURL(String endPointUrl) throws MalformedURLException {
URL endpoint = new URL(null, endPointUrl, new URLStreamHandler() {
protected URLConnection openConnection(URL url) throws IOException {
URL clone = new URL(url.toString());
URLConnection connection = null;
if (PROXY_ADDRESS != null && PROXY_PORT != 0 ) { // https://stackoverflow.com/a/22533464/5081877
Socket socket = new Socket();
SocketAddress sockaddr = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
socket.connect(sockaddr, 10000);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(socket.getInetAddress(), PROXY_PORT));
if (proxy.address().toString().equals("0.0.0.0/0.0.0.0:80") || proxy.address().toString() != null) {
System.out.println("Connection through proxy ...");
connection = clone.openConnection(proxy);
} else {
connection = clone.openConnection();
}
} else {
connection = clone.openConnection();
}
connection.setConnectTimeout(5 * 1000); // 5 sec
connection.setReadTimeout(5 * 1000); // 5 sec
return connection;
}
});
return endpoint;
}
public static String getSOAPXMLasString(SOAPMessage soapMsg) throws SOAPException, IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
soapMsg.writeTo(out);
// resp.writeTo(System.out);
String strMsg = new String(out.toByteArray());
System.out.println("Soap XML: "+ strMsg);
return strMsg;
}
public static SOAPMessage getSOAPMessagefromDataXML(String saopBodyXML) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setIgnoringComments(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource ips = new org.xml.sax.InputSource(new StringReader(saopBodyXML));
Document docBody = dBuilder.parse(ips);
System.out.println("Data Document: "+docBody.getDocumentElement());
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMsg = messageFactory.createMessage();
SOAPBody soapBody = soapMsg.getSOAPPart().getEnvelope().getBody();
soapBody.addDocument(docBody);
return soapMsg;
}
// SOPAConneciton and HTTPClien connection functions
}
did you see this?
SOAPMessage - SOAPConnection - gzip - how to
Also, if you use AXIS2, it has built-in features to enable compression of base64-encoded binary content using MTOM:
http://axis.apache.org/axis2/java/core/docs/mtom-guide.html
Just to complete that snippet - if you want to work with the decompressed SOAPMessage you need to load it into a new message.
SOAPMessage responseCompressed = connection.call(reqMessage, endpoint);
ByteArrayOutputStream out = new ByteArrayOutputStream();
responseCompressed.writeTo(out);
byte[] barr = out.toByteArray();
InputStream gzipStream = new GZIPInputStream(new ByteArrayInputStream(barr));
Here is the magic line
SOAPMessage response = factory.createMessage(responseCompressed.getMimeHeaders(), gzipStream);
Where factory is your MessageFactory.
Now response will function like it did without the gzip headers. You just drop it in.