how to send attached via email using SES and lambda in Java - amazon-web-services

I am trying to send the files stored in s3 via email using AWS SES and lambda in java. Mail has send successfully but when i am trying to open the file getting error "Excel cannot open the file 'filename.xlsx' because file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."
Code Snippet in java :
public class EmailNotification {
static LambdaLogger logger = null;
private static String SENDER=null;
private static String RECIPIENT=null;
private static String SUBJECT=null;
private static String BODY_TEXT=null;
private static String filekey=null;
public void verifyEmailNotification(Context context) throws Exception {
LambdaLogger logger = null;
try {
logger = context.getLogger();
String bucket_name = "bucket_name";
String key_name = "path/";
String file_name ="file_name.xlsx";
filekey = key_name + file_name;
AmazonS3 s3client = GetAWSClients.getS3();
boolean isFileExists=Utility.checkIfFileExists(bucket_name, filekey);
logger.log("isFileExists " + isFileExists);
if (isFileExists)
filekey = key_name + file_name;
else
logger.log("file not available");
InputStream stream = s3client.getObject(bucket_name, filekey).getObjectContent();
XSSFWorkbook workbook = new XSSFWorkbook(stream);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
ByteArrayInputStream contentsAsStream = new ByteArrayInputStream(bos.toByteArray());
ObjectMetadata md = new ObjectMetadata();
md.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
md.setSSEAlgorithm(ObjectMetadata.AES_256_SERVER_SIDE_ENCRYPTION);
md.setContentLength(bos.toByteArray().length);
SENDER = "sender email";
RECIPIENT = "receiver email";
SUBJECT = "subject";
BODY_TEXT = "Body text";
Session session = Session.getDefaultInstance(new Properties());
MimeMessage message = new MimeMessage(session);
message.setSubject(SUBJECT);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
MimeMultipart msg_body = new MimeMultipart("alternative");
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8");
msg_body.addBodyPart(textPart);
MimeBodyPart att = new MimeBodyPart();
DataSource fds = new ByteArrayDataSource(bos.toByteArray(), "application/octet-stream");
att.setDataHandler(new DataHandler(fds));
att.setFileName(TemplateFile);
message.setContent(msg_body);
msg_body.addBodyPart(att);
try {
System.out.println("Attempting to send an email through Amazon SES "
+"using the AWS SDK for Java...");
AmazonSimpleEmailService client = GetAWSClients.getSES();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage);
client.sendRawEmail(rawEmailRequest);
System.out.println("Email sent!");
workbook.close();
} catch (Exception ex) {
System.out.println("Email Failed");
System.err.println("Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
catch(Exception ex) {
System.out.println("Email Failed");
System.err.println("Error message: " + ex.getMessage());
ex.printStackTrace();
}
}
}

Used POI and workbooks concept and resolved the issue.
public void verifyEmailNotification(Context context) throws IOException, MessagingException {
String bucketName = "bucketName";
String key = "prefix";
String fileName = "fileName.xlsx";
String keyName = key + fileName;
S3Object fullObject = null;
try {
SENDER = "sender email";
RECIPIENT = "receiver email";
SUBJECT = "Subject msg";
BODY_TEXT = "Hi";
logger = context.getLogger();
AmazonS3Client s3Client = (AmazonS3Client) AmazonS3ClientBuilder.defaultClient();
InputStream stream = s3Client.getObject(new GetObjectRequest(bucketName, keyName)).getObjectContent();
// Preparing input-stream as spreed sheet.
XSSFWorkbook workbook = new XSSFWorkbook(stream);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
logger.log("Read success\n");
Session session = Session.getDefaultInstance(new Properties());
MimeMessage message = new MimeMessage(session);
message.setSubject(SUBJECT);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(RECIPIENT));
MimeMultipart msg_body = new MimeMultipart("alternative");
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(BODY_TEXT, "text/plain; charset=UTF-8");
msg_body.addBodyPart(textPart);
// Preparing the attachment from the spread sheet
MimeBodyPart att = new MimeBodyPart();
DataSource fds = new ByteArrayDataSource(bos.toByteArray(), "application/octet-stream");
att.setDataHandler(new DataHandler(fds));
att.setFileName(fileName);
msg_body.addBodyPart(att);
message.setContent(msg_body);
logger.log("attachment prepared\n");
AmazonSimpleEmailServiceClientBuilder.standard().withRegion(Regions.US_EAST_1).build();
AmazonSimpleEmailService client = GetAWSClients.getSES();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage);
client.sendRawEmail(rawEmailRequest);
System.out.println("Email sent!");
} catch (AmazonServiceException e) {
// The call was transmitted successfully, but Amazon S3 couldn't process
// it, so it returned an error response.
e.printStackTrace();
} catch (SdkClientException e) {
// Amazon S3 couldn't be contacted for a response, or the client
// couldn't parse the response from Amazon S3.
e.printStackTrace();
}
}

Related

S3 bukcet getobject throws error Method not found: 'Amazon.Runtime.Internal.Transform.UnmarshallerContext

I am tring to read my s3 bucket object from EKS cluster application method as listed below.
[HttpGet("ReadFromS3")]
[ProducesResponseType(typeof(ApiResponse<string>), 200)]
[ProducesResponseType(500)]
public async Task<String> ReadFromS3()
{
AmazonS3Config config = new AmazonS3Config { RegionEndpoint = RegionEndpoint.EUWest2 };
string aws_tokenFile = Environment.GetEnvironmentVariable("AWS_WEB_IDENTITY_TOKEN_FILE");
string aws_rolw_arn = Environment.GetEnvironmentVariable("AWS_ROLE_ARN");
string logs = string.Empty;
using (var stsClient = new AmazonSecurityTokenServiceClient(new AnonymousAWSCredentials()))
{
logs += "AmazonSecurityTokenServiceClient";
var assumeRoleResult = await stsClient.AssumeRoleWithWebIdentityAsync(new AssumeRoleWithWebIdentityRequest
{
WebIdentityToken = System.IO.File.ReadAllText(Environment.GetEnvironmentVariable("AWS_WEB_IDENTITY_TOKEN_FILE")),
RoleArn = Environment.GetEnvironmentVariable("AWS_ROLE_ARN"),
RoleSessionName = "S3Session",
DurationSeconds = 900
});
if (assumeRoleResult != null)
{
logs += " -> assumeRoleResult";
var credentials = assumeRoleResult.Credentials;
var basicCredentials = new BasicAWSCredentials(credentials.AccessKeyId,
credentials.SecretAccessKey);
logs += " -> BasicAWSCredentials";
using (client = new AmazonS3Client(basicCredentials, RegionEndpoint.EUWest2) )
{
logs += " -> AmazonS3Client";
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = keyName
};
GetObjectResponse response = await client.GetObjectAsync(request);
logs += " -> GetObjectAsync";
Stream responseStream = response.ResponseStream;
StreamReader reader = new StreamReader(responseStream);
logs += " -> ResponseStream";
return await reader.ReadToEndAsync();
}
catch (Exception ex)
{
return "Exception in ReadFromS3 :" + ex.Message + logs;
}
}
}
else
{
return "Unable to Connect";
}
}
}
I am getting error at line GetObjectResponse response = await client.GetObjectAsync(request);
Method not found: 'Amazon.Runtime.Internal.Transform.UnmarshallerContext Amazon.Runtime.Internal.Transform.ResponseUnmarshaller.CreateContext

com.amazonaws.SdkClientException: Unable to calculate MD5 hash: /home/bharath/Documents/demo/demo.txt (No such file or directory)

By taking the reference of this Question link below
How to solve 'Client is immutable when created with the builder'?
I do have a similar code structure wherein which am getting an error saying
Unable to calculate MD5 hash
public class LambdaFunctionS3 implements RequestHandler<Object, String> {
#Override
public String handleRequest(Object input, Context context) {
context.getLogger().log("Input: " + input);
String clientRegion = "ap-south-1";
String bucketName = "Bucket Name";
String fileObjKeyName = "demo.txt";
String fileName = "/home/bharath/Documents/demo/demo.txt";
try {
System.out.println("Uploading a new file to s3 bucket...");
File file = new File(fileName);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
.withRegion(clientRegion)
.withCredentials(new ProfileCredentialsProvider())
.build();
PutObjectRequest request = new PutObjectRequest(bucketName, fileObjKeyName,file);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("plain/text");
metadata.addUserMetadata("x-amz-meta-title", "myFunction");
request.setMetadata(metadata);
s3Client.putObject(request);
System.out.println("File uploaded.");
return "Success";
} catch(AmazonServiceException e) {
System.err.println(e.getErrorMessage());
System.exit(1);
e.printStackTrace();
} catch(SdkClientException e) {
e.printStackTrace();
}
return "Hello from Lambda!"; }
Though I have a file with the correct path. Am using aws lambda function in order to upload a file in s3.
Any help?

Send SMS using AWS SNS - .Net Core

I'm trying to use AWS world wide messaging service using C#/.Net Core.
However I do not receive the message in my phone number. Below is the code:
public static async Task<PublishResponse> sendSMS()
{
string accessKey = "my Key";
string secretAccessKey = "my secret key";
var client = new AmazonSimpleNotificationServiceClient(accessKey,
secretAccessKey, RegionEndpoint.USEast1);
string phoneNumber = "my number";
PublishRequest req = new PublishRequest();
req.Message = "Hellloooo from core";
req.PhoneNumber = "+2" + phoneNumber;
PublishResponse res = await client.PublishAsync(req);
return res;
}
And I invoke this method in the main function:
public static void Main(string[] args)
{
var respond = sendSMS();
}
I appreciate if anyone could help me with this. thanks in advance
public static async Task<PublishResponse> SendMessageToMobileAsync(string countryCode, string mobileNumber, string message)
{
var accessKey = "xxx";
var secretKey = "xxx";
var client = new AmazonSimpleNotificationServiceClient(accessKey, secretKey, RegionEndpoint.USEast1);
var messageAttributes = new Dictionary<string, MessageAttributeValue>();
var smsType = new MessageAttributeValue
{
DataType = "String",
StringValue = "Transactional"
};
messageAttributes.Add("AWS.SNS.SMS.SMSType", smsType);
PublishRequest request = new PublishRequest
{
Message = message,
PhoneNumber = countryCode + mobileNumber,
MessageAttributes = messageAttributes
};
return await client.PublishAsync(request);
}
the following function worked for me.
make sure that the account liked to credential you provided has SNS full access in AWS IAM Console
public static async Task SendSMS(AWSCredentials basicCred, string phoneNum, string message, string smsType= "Promotional")
{
AmazonSimpleNotificationServiceClient snsClient = new AmazonSimpleNotificationServiceClient(basicCred, Amazon.RegionEndpoint.APSoutheast2);
PublishRequest pubRequest = new PublishRequest();
pubRequest.Message = message;
// add optional MessageAttributes, for example:
pubRequest.MessageAttributes.Add("AWS.SNS.SMS.SenderID", new MessageAttributeValue
{ StringValue = "SSystems", DataType = "String" });
pubRequest.MessageAttributes.Add("AWS.SNS.SMS.MaxPrice", new MessageAttributeValue
{ StringValue = "0.50", DataType = "Number" });
pubRequest.PhoneNumber = phoneNum;
pubRequest.MessageAttributes.Add("AWS.SNS.SMS.SMSType", new MessageAttributeValue
{ StringValue = smsType, DataType = "String" });
PublishResponse pubResponse = await snsClient.PublishAsync(pubRequest);
Console.WriteLine(pubResponse.MessageId);
Console.ReadLine();
}
For new Comers
If you are using Aws toolkit for visual studio as I suppose
Nuget Packages:
AWSSDK.CORE
AWSSDK.Extensions.NETCore.Setup
AWSSDK.SimpleNotificationService
In your program.cs (.net core 6)
using Amazon.SimpleNotificationService;
and add your extensions
builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions());
builder.Services.AddAWSService<IAmazonSimpleNotificationService>(builder.Configuration.GetAWSOptions());
builder.Services.AddSingleton<ISMSSender, SMSSender>();
In appsettings
"AWS": {
"Profile": "aws toolkit profile name",
"Region": "aws region"
}
an ISMSSender interface for dependency injection:
public interface ISMSSender
{
Task<PublishResponse> SendSMSAsync(string phone, string subject, string Message);
}
Lastly your implementation:
public class SMSSender : ISMSSender
{
IAmazonSimpleNotificationService _SES;
public SMSSender(IAmazonSimpleNotificationService SES)
{
_SES = SES;
}
public Task<PublishResponse> SendSMSAsync(string phone, string subject, string Message)
{
var messageAttributes = new Dictionary<string, MessageAttributeValue>();
MessageAttributeValue senderID = new MessageAttributeValue();
senderID.DataType = "String";
senderID.StringValue = "sendername";
MessageAttributeValue sMSType = new MessageAttributeValue();
sMSType.DataType = "String";
sMSType.StringValue = "Transactional";//or Promotional according to AWS setup you choosed
MessageAttributeValue maxPrice = new MessageAttributeValue();
maxPrice.DataType = "Number";
maxPrice.StringValue = "0.5";
messageAttributes.Add("AWS.SNS.SMS.SenderID", senderID);
messageAttributes.Add("AWS.SNS.SMS.SMSType", sMSType);
messageAttributes.Add("AWS.SNS.SMS.MaxPrice", maxPrice);
var sendRequest = new PublishRequest()
{
Subject = subject,
Message = Message,
PhoneNumber =phone,
MessageAttributes = messageAttributes
};
try
{
Console.WriteLine("Sending SMS using AWS SES...");
var response = _SES.PublishAsync(sendRequest);
Console.WriteLine("The SMS was sent successfully.");
return response;
}
catch (Exception ex)
{
Console.WriteLine("The SMS was not sent.");
Console.WriteLine("Error message: " + ex.Message);
}
throw new NotImplementedException();
}
}
For usage use dependency injection into your Controller or class
private readonly ISMSSender _smsSender;
public MyController(ISMSSender smsSender)
{
_smsSender = smsSender;
}
and then Send Sms:
try
{
var result = await _smsSender.SendSMSAsync(
phoneNumber,
"Title",
"Message");
}
catch (Exception)
{
//handle failure
}
In order to send sms from your Ec2 or elastic Beanstalk app go to IAM roles and for role aws-elasticbeanstalk-ec2-role add permission AWSElasticBeanstalkRoleSNS and for role aws-elasticbeanstalk-service-role add permission AmazonSNSFullAccess

Cannot genetrate java client for file upload webservice

I have a simple file upload web service as a small part of my project.
This is what I have done so far on the server side :
#POST
#Path("/file")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(List<Attachment> attachments,#Context HttpServletRequest request) {
System.out.println("Got an attachment!");
for(Attachment attr : attachments) {
DataHandler handler = attr.getDataHandler();
try {
InputStream stream = handler.getInputStream();
MultivaluedMap map = attr.getHeaders();
OutputStream out = new FileOutputStream(new File("/home/yashdosi/s/" + getFileName(map))); //getFileName is a seperate private function..
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
stream.close();
out.flush();
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
return Response.ok("file uploaded").build();
}
It works perfectly well when requests come from html forms...when I try to send a request from a java client it simply doesnt work..!!
Any ideas about on creating a java client for this code..
Here is the code I tried with...maybe there is a simple error in this code but..I dont see it...also as I said this code simple wont work...no errors or anything else....when I tried printing something on the server console to see if the service is invoked...it did NOT print anything..so I think I am unable to contact the service for some reason...
public static void uploadPhoto()
{
String url = "http://localhost:8080/fileupload-ws/services/postdata";
String output = null;
PostMethod mPost = new PostMethod(url);
HttpClient client = new HttpClient();
try
{
File imageFile = new File("/home/yashdosi/1.jpg");
BufferedImage image = ImageIO.read(imageFile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
byte[] encodedImage = Base64.encodeBase64(baos.toByteArray());
String data = " " + " " + "" + "image/jpeg" + " " + "" + new String(encodedImage) + " " + "";
mPost.setRequestBody(data);
mPost.setRequestHeader("Content-Type", "text/xml");
client.executeMethod( mPost );
output = mPost.getResponseBodyAsString( );
mPost.releaseConnection( );
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(output);
}
Finally got a client working!!
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost httppost = new HttpPost("http://localhost:8080/fileupload-ws/services/postdata");
FileBody img = new FileBody(new File("/home/yashdosi/1.jpg"));
FileBody html = new FileBody(new File("/home/yashdosi/hotmail.html"));
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("image", img);
reqEntity.addPart("html", html);
httppost.setEntity(reqEntity);
httppost.setHeader("Content-Type", "multipart/form-data");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
}
catch(Exception e)
{
e.printStackTrace();
}
finally {
try { httpclient.getConnectionManager().shutdown(); } catch (Exception ignore) {}
}

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.