character encoding issue while reading email using java mail api - jakarta-mail

Hi I am reading emil's from a mailbox using Java mail Api.
For an email ,The from Address has Chinese characters and looks as below
(krishna 国际快 <12139#ty.com> ).
After reading the email , When I get the from Address from message using message.getFromAddress();
The from address is some thing like below
?utf-8?Q?Kris=EF=BC=88=E4=BF=9E=E7=94=9F=EF=BC=89?= <12139#ty.com>
How can I get the original from address.

The email address encoding issue while reading the email from a mail box is fixed.
StringBuffer sbFrom =null;
sbFrom = new StringBuffer();
Address[] in = msg.getFrom();
for (Address address : in) {
System.out.println("FROM: " + address.toString());
sbFrom.append(address.toString());
}
I created two solutions for this . Please find them below.
Solution 1:
Created a regular expression and checking the regular expression , If email address matches the regular expression then we decode the email address.
Please check the code below.
String ENCODED_PART_REGEX_PATTERN="=\\?([^?]+)\\?([^?]+)\\?([^?]+)\\?=";
Pattern pattern=Pattern.compile(ENCODED_PART_REGEX_PATTERN);
Matcher m =pattern.matcher(sbFrom.toString());
if(m.find()){
System.out.println("FROM: " +MimeUtility.decodeWord( sbFrom.toString()));
}else{
System.out.println("FROM: " + sbFrom.toString());
}
Solution 2: Written a method which decodes the given email address. If we get javax.mail.internet.ParseException while decoding then it means the email Address do not have any encoded characters , so we return normal string.
Please observe the below method.
public String decodeAddress(String emailId) throws UnsupportedEncodingException{
String string = "";
try{
string = MimeUtility.decodeWord(emailId);
}catch(ParseException e){
System.out.println("ParseException occured so return the same string");
string =emailId;
}
return string;
}

Related

AT command sent SMS received as Flash SMS (Class 0 SMS)

I used this link to send SMS with AT command in WPF.
But when I send SMS with CMGS command, the receiver get the SMS as Flash SMS not usual SMS. My code is as below:
//Check if modem allows you to send and receive SMS messages using AT commands, without the need to decode the binairy PDU field of the SMS first
rval = sp.SendCommand("AT+CMGF=1");
//set Text mode parameters
rval = sp.SendCommand("AT+CSMP=17,167,0,16");
string phonenumber = "xxxxxxxxxxx";
string Message = "test";
rval = sp.SendCommand("AT+CMGS=\"" + phonenumber + "\"");
if (rval.Equals("\r\n> "))
{
rval = sp.SendCommand(Message + char.ConvertFromUtf32(26) );
}
and my SendCommand is as below
public string SendCommand(String commandText)
{
if (!serialPort.IsOpen)
{
try
{
serialPort.Open();
}
catch (Exception ex)
{
LogEvents.InLogFile(ex.Message);
throw new Exception("COM port is busy");
}
}
try
{
serialPort.DiscardOutBuffer();
serialPort.DiscardInBuffer();
buff = "";
serialPort.Write(commandText + "\r");
Thread.Sleep(serialPort.ReadTimeout);
return buff;
}
catch (Exception)
{
throw new Exception("Error connection");
}
}
Can any one help me?
My other references:
developershome,
Sayeda Anila Nusrat
The fourth parameter in AT+CSMP sets the coding scheme, i don't remember in which document i've found the coding of this byte but bit 7 sets whether the message should be discarded after showing it class 0 or stored
You should set this bit to 1 to make it storable, so changing
rval = sp.SendCommand("AT+CSMP=17,167,0,16");
to
rval = sp.SendCommand("AT+CSMP=17,167,0,144");
should do the work
Bit 0 (i.e., the least significant bit) of the fourth parameter of the AT+CSMP command is a flag for whether the SMS will be flashed (when 0) or saved (when 1).
Simply put: An even number for 4th parameter will NOT save the message, while an odd number will.
Change AT+CSMP=17,167,0,16 to AT+CSMP=17,167,0,0.

TextEncodings.Base64Url.Decode vs Convert.FromBase64String

I was working on creating a method that would generate a JWT token. Part of the method reads a value from my web.config that services as the "secret" used to generate the hash used to create the signature for the JWT token.
<add key="MySecret" value="j39djak49H893hsk297353jG73gs72HJ3tdM37Vk397" />
Initially I tried using the following to convert the "secret" value to a byte array.
byte[] key = Convert.FromBase64String(ConfigurationManager.AppSettings["MySecret"]);
However, an exception was thrown when this line was reached ...
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
So I looked into the OAuth code and so another method being used to change a base64 string into a byte array
byte[] key = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["MySecret"]);
This method worked without issue. To me it looks like they are doing the same thing. Changing a Base64 text value into an array of bytes. However, I must be missing something. Why does Convert.FromBase64String fail and TextEncodings.Base64Url.Decode work?
I came across the same thing when I migrated our authentication service to .NET Core. I had a look at the source code for the libraries we used in our previous implementation, and the difference is actually in the name itself.
The TextEncodings class has two types of text encoders, Base64TextEncoder and Base64UrlEncoder. The latter one modifies the string slightly so the base64 string can be used in an url.
My understanding is that it is quite common to replace + and / with - and _. As a matter of fact we have been doing the same with our handshake tokens. Additionally the padding character(s) at the end can also be removed. This leaves us with the following implementation (this is from the source code):
public class Base64UrlTextEncoder : ITextEncoder
{
public string Encode(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return Convert.ToBase64String(data).TrimEnd('=').Replace('+', '-').Replace('/', '_');
}
public byte[] Decode(string text)
{
if (text == null)
{
throw new ArgumentNullException("text");
}
return Convert.FromBase64String(Pad(text.Replace('-', '+').Replace('_', '/')));
}
private static string Pad(string text)
{
var padding = 3 - ((text.Length + 3) % 4);
if (padding == 0)
{
return text;
}
return text + new string('=', padding);
}
}

Loadrunner - concatenation using lr_save_string

Is it possible to concatenate using lr_save_string?
sortoption,next and basket, bookIDs_array are all correctly assigned values.
Code
lr_save_string(lr_eval_string("sortoption={sortoption}&next={next}&basket={basket}"), "BodyString");
for (i=1; i<=lr_paramarr_len("BookIDS_array"); i++) {
lr_save_string(lr_paramarr_idx("BookIDS_array", i), "BookID");
lr_save_string(lr_eval_string("{BodyString}&bookId%5B%5D%3D{BookID}"), "BodyString");
}
lr_output_message("Value: %s", lr_eval_string("{BodyString}"));
However the above seems to just assign the below to BodyString
sortoption={sortoption}&next={next}&basket={basket}
You may want to consider this other thread for a concatenation example in LoadRunner
How to change input soap request as per test data in loadrunner?
I took a look at the XML link and it's very similar to what I wanted to do, but I had some json to update if there was a value. My approach to the issue below:
//Define the object to store.
char ifPhoneThenAdd[100];
...
...
...
//Capture the full part of the address information of the first entry including city, phone, etc. - In my scenario, all I need is the first one from the json response..
web_reg_save_param_json("ParamName=AddressData","QueryString=$.Addresses","SelectAll=No",SEARCH_FILTERS,"Scope=Body",LAST);
...
...
...
web_rest("......",
"URL={App_URL}/details/{userID}",
"Method=GET",
"Snapshot=t999990.inf",
LAST);
...
...
...
//Some explanation of the json output:
//A sample of the json output would look something like this (from the output tab):
//Saving Parameter "AddressData" = [{"Id":"xxxxxxxxxxx","city":"Calgary","street":"123 Santas Workshop","postalCode":"H0H 0H0","country":"CA","region":"AB","email":"baba#oriley.com","phone":"403xxxxxxx"}]"
//Without the phone, it would be:
//[{"Id":"xxxxxxxxxxx","city":"Calgary","street":"123 Santas Workshop","postalCode":"H0H 0H0","country":"CA","region":"AB","email":"baba#oriley.com"}]"
//This part changes the body in case there is a phone number and does not include phone number if there is none in the reply.
sprintf(ifPhoneThenAdd,"");
if (strstr(lr_eval_string("{AddressData}"), "\"phone\"") != NULL)
{
lr_eval_json("Buffer={AddressData}", "JsonObject=json_obj", LAST);
lr_json_get_values("JsonObject=json_obj", "ValueParam=AddressWithPhoneNumber", "QueryString=$..phone", "SelectAll=No", LAST);
sprintf(ifPhoneThenAdd,"%s%s%s",",\r\n\"phoneNumber\":\"",lr_eval_string("{AddressWithPhoneNumber}"),"\"");
}
else
{
//Doesn't make the script fail, but will send an error message.
lr_error_message("No phone number for ID: %s", lr_eval_string("{userID}"));
}
lr_save_string(ifPhoneThenAdd, "ifPhoneThenAddString");
//If there is no phone, then the string ifPhoneThenAddString will be empty and nothing but the empty string will be added to the json output.
//If there is a phone, then the body will get appended with the right json output with the phone number.
...
...
...
web_rest("......",
"URL={App_URL}/updateSomethingNeedingAddress/{userID}",
"Method=POST",
"EncType=raw",
"Snapshot=t999991.inf",
"Body={\r\n"
"\"Id\":\"{userID}\",\r\n"
"\"firstName\":\"{userFirstname}\",\r\n"
"\"lastName\":\"{userLastname}\",\r\n"
"\"streetName\":\"{userStreetName}\",\r\n"
"\"city\":\"{userCity}\",\r\n"
"\"province\":\"{userProvince}\",\r\n"
//This part will add the phone part if there is one after the postalCode. If no phone, the postalCode will be the last part of the json.
"\"postalCode\":\"{userPostalCode}\"{ifPhoneThenAddString}\r\n"
"}",
HEADERS,
"Name=Content-Type", "Value=application/json", ENDHEADER,
LAST);
...
...
...
return 0;

The message content in a line is becomes 2 lines when reading from InputStream

I am using android JavaMail.
I would like to parse the inputStream of the content myself. So I use
InputStreamReader reader = new InputStreamReader(messages[i].getInputStream());
int value;
StringBuilder out = new StringBuilder();
while((value = reader.read()) != -1) {
out.append((char) value);
}
reader.close();
Log.i(TAG, out.toString());
The original string content is :
<body lang=3D"ZH-TW" link=3D"#0563C1" vlink=3D"#954F72" style=3D"text-justify-trim:punctuation">
But when in the printout result is
<body lang=3D"ZH-TW" link=3D"#0563C1" vlink=3D"#954F72" style=3D"text-justi=
fy-trim:punctuation">
There is extra "=" in the line and it breaks into two line.
"=" seems indicate that the line is not ended yet. How did it happen?
If the line actually ends with =, then how can we differentiate?
Bill, I can work with work around problems with broken IMAP servers
according to the https://www.rfc-editor.org/rfc/rfc3501#section-6.4.5
Arguments: sequence set
message data item names or macro
so it seems that we can fetch with UID specified.
When i am using javamail, even though have the API fetch the message by UID.
javax.mail.Message[] messages = folder.getMessagesByUID(localFolderObject.getUIDNext(),
serverFolderObject.getUIDNext());
for (int i = 0; i < messages.length; ++i) {
// Get the message object from the folder
MimeMessage msg = (MimeMessage) messages[i];
// Copy the message by writing into an byte array.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
msg.writeTo(bos);
bos.close();
Log.i(TAG, bos.toString());
}
catch (IOException e) {
e.printStackTrace();
}
}
the fetch issue as
A38 FETCH 1 (BODY[])
1 is message sequence number, not the UID.
The server wants us to fetch with
A5 UID FETCH 291 (BODY[])
Is there any API "UID Fetch" command for getting the message https://www.rfc-editor.org/rfc/rfc3501#section-6.4.8?
I won't retreive all the messages every time. will keep the previous last NextUID and next time retrieve will start from previous save next UID.
Due to fetch by sequence number, the server always return the first sequnce message instead of the one i want.

apache pop3 bufferedreader lines end with = (equals)

I try to receive some messages from a POP3 mail server using the apache POP3 mail client.
I use a BufferedReader to get messages from my POP3 mail server (retreiveMessage(id)). I have some mails with long lines and I read them with a loop like below. My lines are truncated into several lines ending with the equal sign (=), each line with 76 chars plus the =.
import org.apache.commons.net.pop3.POP3Client;
import org.apache.commons.net.pop3.POP3MessageInfo;
...
POP3Client pop = new POP3Client();
pop.setSocketFactory(SSLSocketFactory.getDefault());
pop.setDefaultTimeout(60000);
pop.connect(MAIL_SEREVR, PORT);
String username = USERNAME;
String password = PASSWORD;
isVerified = pop.login(username, password);
POP3MessageInfo[] messages = pop.listMessages();
for (POP3MessageInfo msginfo : messages) {
Date timestamp = new Date();
BufferedReader reader = (BufferedReader) pop
.retrieveMessage(msginfo.number);
if (reader == null) {
System.err.println("Could not retrieve message header.");
pop.disconnect();
System.exit(1);
}
try {
printMessageInfo(reader, msginfo.number, timestamp);
} catch (Exception e) {
e.printStackTrace();
}
pop.deleteMessage(msginfo.number);
}
pop.logout();
pop.disconnect();
So, I print the messages and since a word is too long, it is truncated like this:
this is a short line, it is OK
andThisIsALongLineWithMoreThan76CharactersButThisIsEmpiricalIJustSeeThatThe=
LineIsTruncatedAtThe76thCHAR
is this a normal behavior? can someone help me?
thanks
It doesn't sound like you're using JavaMail. It you aren't, use it, it will make life easier for you. If you are, explain in more detail what you're doing.

Resources