I want to send sms which contain arabic message using java API
mobily provider offers a java api to send sms
I used this code java :
public void sendMessage(String userName,String password,String sender,String message,String numbers){
String para ="mobile=" + userName + "&password=" + password + "&numbers=" + numbers+ "&sender=" + sender + "&msg=" + convertUnicode(message) + "&applicationType=24";
sendURL("http://www.mobily.ws/api/msgSend.php",para,1);
System.out.println(getMessage());
}
public static String convertUnicode(String a) {
int bufSize = 16;
byte[] buffer = new byte[bufSize];
String s = null;
try {
buffer=a.getBytes();
s = bytesToHex(buffer,0,buffer.length);
System.out.println("Hex: "+s);
} catch (Exception e) {
System.out.println(e.toString());
}
return s;
}
public static String bytesToHex(byte[] b, int off, int len) {
StringBuffer buf = new StringBuffer();
for (int j=0; j<len; j++)
buf.append(byteToHex(b[off+j]));
return buf.toString();
}
public static String byteToHex(byte b) {
char[] a = { hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f] };
return forDigits(new String(a));
}
public static String forDigits(String val){
switch (val.length() ){
case 1:return "000"+val;
case 2:return "00"+val;
case 3:return "0"+val;
case 4:return ""+val;
default:return val;
}
}
public void sendURL(String URL,String parameters,int operationNumber){
try {
URL url;
URLConnection urlConnection;
DataOutputStream outStream;
// Create connection
url = new URL(URL);
urlConnection = url.openConnection();
((HttpURLConnection)urlConnection).setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty("Content-Length", ""+ parameters.length());
urlConnection.setRequestProperty("User-agent","Mozilla/4.0");
// Create I/O streams
outStream = new DataOutputStream(urlConnection.getOutputStream());
// Send request
outStream.writeBytes(parameters);
outStream.flush();
outStream.close();
// Get Response
BufferedReader rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
// - For debugging purposes only!
String buffer;
while((buffer = rd.readLine()) != null) {
try{
selectedMessage(Integer.parseInt(buffer),operationNumber);
}catch(Exception ex){
balance=buffer;
}
}
// Close I/O streams
rd.close();
outStream.close();
}
catch(Exception ex) {
System.out.println("Exception cought:\n"+ ex.toString());
}
}
the problem is that the buffer value is "-1-"
This value is filled in this line :
buffer = rd.readLine()
so I always find myself in this exception
}catch(Exception ex){
balance=buffer;
}
the parameters sent in the sendMessage method:
sender :شارع علي
message :وجهت إلى
numbers : 00966569114455
Updated :
I arrived to send a message in English
sender : test
message : test
in this line while((buffer = rd.readLine()) != null) {
the value of buffer equal to 1
the problem is just for sending messages in Arabic
I try to change my code without success with :
while((buffer = rd.readLine()) != null) {
try{
buffer = buffer.replaceAll("(-?[0-9]+)([^0-9]*)?","$1");
buffer=buffer.replace("-", "");
selectedMessage(Integer.parseInt(buffer),operationNumber);
}catch(Exception ex){
balance=buffer;
}
also in this line in sendURL method:
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
and in this line in convertUnicode method :
buffer=a.getBytes(StandardCharsets.UTF_8);
this is my function which return the final message :
public void selectedMessage(int value,int operationNumber){
switch(operationNumber){
case 1:switch(value){
case 1:msg= "SUCCESS";break;
case 2:msg="ERROR";break;
}break;
}
}
with my modified code I force the buffer value to be equal to 1
in sendURL method the value of parameters is :
mobile=966556541236&password=123654&numbers=966569114455&sender=شارع علي&msg=00D800A700D9008400D9008500D800B900D800A700D9008500D9008400D800A9002000D800B100D9008200D9008500D9008800D800AC00D9008700D800AA002000D800A500D9008400D90089002000D9008600D800B800D800A700D90085002000D9008400D9008400D800AA00D800AF00D800B100D9008A00D800A8&applicationType=24
You might consider doing a RegEx replaceAll on the input first, to filter the input.
Example:
buffer = rd.readLine().replaceAll("(-?[0-9]+)([^0-9]*)","$1");
This will convert input like so:
-1- -> -1
-1 -> -1
1- -> 1
Related
I'm trying to use Microsoft Graph to make a file search. I use this entry point : https://graph.microsoft.com/beta/search/query
My application do not use a user account but a daemon with an application key (see auth method).
And i send a built object.
My java code is rather simple :
public static void main(String[] args) throws Exception{
try {
// Authentication result containing token
IAuthenticationResult result = getAccessTokenByClientCredentialGrant();
String token = result.accessToken();
SearchDocumentResponseModel documentQuery = fileGraphs.searchDocument(token, QUERYSTRING, 0, 25);
System.out.println("Find a document" + documentQuery.toString());
} catch(Exception ex){
throw ex;
}
}
private static IAuthenticationResult getAccessTokenByClientCredentialGrant() throws Exception {
ConfidentialClientApplication app = ConfidentialClientApplication.builder(
CONFIDENTIAL_CLIENT_ID,
ClientCredentialFactory.createFromSecret(CONFIDENTIAL_CLIENT_SECRET))
.authority(TENANT_SPECIFIC_AUTHORITY)
.build();
ClientCredentialParameters clientCredentialParam = ClientCredentialParameters.builder(
Collections.singleton(GRAPH_DEFAULT_SCOPE))
.build();
CompletableFuture<IAuthenticationResult> future = app.acquireToken(clientCredentialParam);
return future.get();
}
The SearchDocumentResponseModel is just a set of POJO that build for me the object that i must send as a request body.
{
"requests":
[{
"entityTypes":["microsoft.graph.driveItem"],
"query":{"query_string":{"query":"any query"}},
"from":0,"size":25
}]
}
The method searchDocument is just here to build the object before i send it to the API
public SearchDocumentResponseModel searchDocument(String accessToken, String stringSearch, int from, int size) throws IOException {
SearchDocumentRequestModel searchRequest = new SearchDocumentRequestModel();
// set values here
...
URL url = new URL("https://graph.microsoft.com/beta/search/query");
return requestsBuilder.buildPostRequest(accessToken, searchRequest, url)
}
Now i want to send to server the Json and expect an answer :
public SearchDocumentResponseModel buildPostRequest(String accessToken, SearchDocumentRequestModel searchRequest, URL url) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Bearer " + accessToken);
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json; utf-8");
conn.setDoOutput(true);
conn.setRequestMethod("POST");
// write the input json in a string
String jsonInputString = new Gson().toJson(searchRequest);
try(OutputStream os = conn.getOutputStream()) {
byte[] input = jsonInputString.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
int httpResponseCode = conn.getResponseCode();
String httpResponseMessage = conn.getResponseMessage();
// reading the response
try(BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
String outputResponse = response.toString();
return new Gson().fromJson(outputResponse, SearchDocumentResponseModel.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I think i set the properties correctly. Is it coming from my code or from Microsoft Graph ? Thanks !
First of all, you should check if the access token is valid, you can send a request using postman.
If the token is valid, I think it should be the problem of your jsonInputString. The following code works fine.
URL url = new URL("https://graph.microsoft.com/beta/search/query");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "access_token" );
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json; utf-8");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String str = "";
str += "{";
str += " \"requests\": [";
str += " {";
str += " \"entityTypes\": [";
str += " \"microsoft.graph.driveItem\"";
str += " ],";
str += " \"query\": {";
str += " \"query_string\": {";
str += " \"query\": \"contoso\"";
str += " }";
str += " },";
str += " \"from\": 0,";
str += " \"size\": 25";
str += " }";
str += " ]";
str += "}";
OutputStream os = conn.getOutputStream();
byte[] input = str.getBytes("UTF-8");
os.write(input, 0, input.length);
System.out.println(conn.getResponseCode());
Update:
Query api doesn't support client credential flow.
i'm working on an instant messaging project which it's client side is android and server is java
i need to use socket with streams
here is my protocol (something like HTTP) :
Method : attachment \n
Content-Length : {some-int-value} \n
\r\n
binary data bla bla bla...
lets assume i want to send this message from client to server
by doing so exchanging header section goes pretty well
but reading binary data at the server side never complete and server goes into hang for good
Client side code :
Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(SERVER_ADDRESS, SERVER_PORT);
try {
socket.connect(address);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
byte[] data = getSomeBinaryData();
writer.write("Method : attachment" + "\n");
writer.write("Content-Length : " + data.length + "\n");
writer.write("\r\n");
writer.flush();
out.write(data); // write binary data
// do more exchange later
} catch (IOException ex) {
// handle exception
}
Server starter code :
public static void main(String[] args){
ExecutorService pool = Executors.newFixedThreadPool(50);
try (ServerSocket server = new ServerSocket(PORT_NUMBER)) {
while (true) {
try {
Socket connection = server.accept();
Callable<Void> task = new ClientTask(connection);
pool.submit(task);
} catch (IOException ex) {}
}
} catch (IOException ex) {
System.err.println("Couldn't start server");
}
}
Server Task thread for each client :
class ClientTask implements Callable<Void> {
private Socket connection;
private HashMap<String, String> header = new HashMap<>();
private byte[] content;
ClientTask(Socket c) {
this.connection = c;
}
#Override
public Void call() throws Exception {
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
readHeader(reader);
System.out.println("incoming message : " + header.get("Method"));
int contentLength = Integer.parseInt(header.get("Content-Length"));
content = new byte[contentLength];
int bytesRead = in.read(content, 0, contentLength);
System.out.print(bytesRead);
return null;
}
private void readHeader(BufferedReader reader){
try {
char c;
StringBuilder builder = new StringBuilder();
while ((c = (char) reader.read()) != '\r'){
if(c == '\n'){
String line = builder.toString();
line = line.replaceAll(" ", "");
String[] sections = line.split(":");
header.put(sections[0], sections[1]);
builder = new StringBuilder(); // clear builder
}else {
builder.append(c);
}
}
reader.read(); // skip the last \n character after header
} catch (IOException e) {
e.printStackTrace();
}
}
As James said a clue I wanted to share the solution
maybe it help someone with similar issue
in the call method of ClientTask class i should use this code :
#Override
public Void call() throws Exception {
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
readHeader(reader);
System.out.println("incoming message : " + header.get("Method"));
// read binary Content
int bytesRead = 0;
int bytesToRead = Integer.parseInt(header.get("Content-Length"));
content = new byte[bytesToRead];
while (bytesRead < bytesToRead) {
int result = in.read(content, bytesRead, bytesToRead - bytesRead);
if (result == -1)
break; // end of stream
bytesRead += result;
}
return null;
}
static String username = "######";
static String password = "#####";
static String senderid = "###";
static String message = "वउह";
static String mobileNo = "08447475458";
static String mobileNos = "08447475458,08447475458";
static String scheduledTime = "20110701 02:27:00";
static HttpURLConnection connection = null;
public static void main(String[] args) {
try {
URL url = new URL("http://msdgweb.mgov.gov.in/esms/sendsmsrequest");
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setFollowRedirects(true);
connection = sendSingleSMS(username, password, senderid,
mobileNo, message);
System.out.println("Resp Code:" + connection.getResponseCode());
System.out.println("Resp Message:"
+ connection.getResponseMessage());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Method for sending single SMS.
public static HttpURLConnection sendSingleSMS(String username,
String password, String senderId,
String mobileNo, String message) {
try {
byte[] bytes = message.getBytes("UTF-8");
String smsservicetype = "singlemsg"; // For single message.
String query = "username=" + URLEncoder.encode(username)
+ "&password=" + URLEncoder.encode(password)
+ "&smsservicetype=" + URLEncoder.encode(smsservicetype)
+ "&content=" + URLDecoder.decode(message,"utf-8") + "&mobileno="
+ URLEncoder.encode(mobileNo) + "&senderid="
+ URLEncoder.encode(senderId);
connection.setRequestProperty("Content-length", String
.valueOf(query.length()));
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset = utf-8");
connection.setRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)");
DataOutputStream output = new DataOutputStream(connection
.getOutputStream());
int queryLength = query.length();
output.writeBytes(query);
System.out.println(query);
DataInputStream input = new DataInputStream(connection
.getInputStream());
for (int c = input.read(); c != -1; c = input.read())
System.out.print((char) c);
input.close();
} catch (Exception e) {
System.out.println("Something bad just happened.");
System.out.println(e);
e.printStackTrace();
}
return connection;
I am using this code to send sms from gateway but this code is fine if the text is english but if I give some hindi text then its not able to read it and user gets some characters.
the output is something like
व� हव�� व�हव ��व� हवहব व�ह
The DataInputStream is reading bytes, but then you have to properly convert those bytes to characters using the correct encoding. For that, you could construct a String using the constructor as follows:
String hindiCharSequence = new String(bytes, "UTF-8");
The answer from #ChthonicProject is the correct answer to accept, here a bit code. It uses a ByteArrayOutputStream to collect the bytes. A DataInputStream is more useful for reading binary ints and such. Better use just a buffering. And/or read a byte[] buffer of say 160 bytes.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (BufferedInputStream input = new BufferedInputStream(connection
.getInputStream())) {
for (int c = input.read(); c != -1; c = input.read()) {
baos.write(c);
}
} // Closes input.
String msg = new String(baos.toByteArray(), StandardCharsets.UTF_8);
System.out.print(msg);
What you did, was considering every byte as a char. But with UTF-8 several bytes may make up a char, which is 16 bit.
May be the problem is with the SMS encoding. By default it uses GSM 7-bit alphabet.
Check if you can specify which encoding will be used in SMS encoding.
Applied this belore query string and its done
System.out.println(message);
String finalmessage = "";
String sss = "";
char ch = 0;
for(int i = 0 ; i < message.length();i++){
ch = message.charAt(i);
int j = (int) ch;
// System.out.println("iiii::"+j);
sss = "&#"+j+";";
finalmessage = finalmessage+sss;
}
System.out.println("ddd"+finalmessage);
message=finalmessage;
System.out.println("unicoded message=="+message);
I am getting a really long string as the response of the web service I am collecting it in the using the StringBuilder but I am unable to obtain the full value I also used StringBuffer but had no success.
Here is the code I am using:
private static String read(InputStream in ) throws IOException {
//StringBuilder sb = new StringBuilder(1000);
StringBuffer sb = new StringBuffer();
String s = "";
BufferedReader r = new BufferedReader(new InputStreamReader( in ), 1000);
for (String line = r.readLine(); line != null; line = r.readLine()) {
sb.append(line);
s += line;
} in .close();
System.out.println("Response from Input Stream Reader >>>" + sb.toString());
System.out.println("Response from Input S >>>>>>>>>>>>" + s);
return sb.toString();
}
Any help is appreciated.
You can also split the string in array of strings in order to see all of them
String delimiter = "put a delimiter here e.g.: \n";
String[] datas=sb.toString().split(delimiter);
for(String string datas){
System.out.println("Response from Input S >>>>>>>>>>>>" + string);
}
The String may not print entirely to the console, but it is actually there. Save it to a file in order to see it.
I do not think that your input is too big for a String, but only not shown to the console because it doesn't accept too long lines. Anyways, here is the solution for a really huge input as characters:
private static String[] readHugeStream(InputStream in) throws IOException {
LinkedList<String> dataList = new LinkedList<>();
boolean finished = false;
//
BufferedReader r = new BufferedReader(new InputStreamReader(in), 0xFFFFFF);
String line = r.readLine();
while (!finished) {
int lengthRead = 0;
StringBuilder sb = new StringBuilder();
while (!finished) {
line = r.readLine();
if (line == null) {
finished = true;
} else {
lengthRead += line.length();
if (lengthRead == Integer.MAX_VALUE) {
break;
}
sb.append(line);
}
}
if (sb.length() != 0) {
dataList.add(sb.toString());
}
}
in.close();
String[] data = dataList.toArray(new String[]{});
///
return data;
}
public static void main(String[] args) {
try {
String[] data = readHugeStream(new FileInputStream("<big file>"));
} catch (IOException ex) {
Logger.getLogger(StackoverflowStringLong.class.getName()).log(Level.SEVERE, null, ex);
} catch (OutOfMemoryError ex) {
System.out.println("out of memory...");
}
}
System.out.println() does not print all the characters , it can display only limited number of characters in console. You can create a file in SD card and copy the string there as a text document to check your exact response.
try
{
File root = new File(Environment.getExternalStorageDirectory(), "Responsefromserver");
if (!root.exists())
{
root.mkdirs();
}
File gpxfile = new File(root, "response.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(totalResponse);
writer.flush();
writer.close();
}
catch(IOException e)
{
System.out.println("Error:::::::::::::"+e.getMessage());
throw e;
}
is it possible to use range header in HTTP with HTTP GET request?
if yes than how?
I just want to download bytes from server with specified bytes.
i.e if I want to download bytes from 0 to 255.
See this sample code,
HttpConnection connection = null;
InputStream inputstream = null;
try
{
connection = (HttpConnection) Connector.open(url); // Enter your URL here.
//HTTP Request
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("Content-Type","//text plain");
connection.setRequestProperty("Connection", "close");
// HTTP Response
System.out.println("Status Line Code: " + connection.getResponseCode());
System.out.println("Status Line Message: " + connection.getResponseMessage());
if (connection.getResponseCode() == HttpConnection.HTTP_OK)
{
System.out.println(
connection.getHeaderField(0)+ " " + connection.getHeaderFieldKey(0));
System.out.println(
"Header Field Date: " + connection.getHeaderField("date"));
String str;
inputstream = connection.openInputStream();
int length = (int) connection.getLength();
if (length != -1)
{
byte incomingData[] = new byte[length];
inputstream.read(incomingData);
str = new String(incomingData);
}
else
{
ByteArrayOutputStream bytestream =
new ByteArrayOutputStream();
int ch;
while ((ch = inputstream.read()) != -1)
{
bytestream.write(ch);
}
str = new String(bytestream.toByteArray());
bytestream.close();
}
System.out.println(str);
}
}
catch(IOException error)
{
System.out.println("Caught IOException: " + error.toString());
}
finally
{
if (inputstream!= null)
{
try
{
inputstream.close();
}
catch( Exception error)
{
/*log error*/
}
}
if (connection != null)
{
try
{
connection.close();
}
catch( Exception error)
{
/*log error*/
}
You could try this:
HttpConnection httpConnection = (HttpConnection) Connector.open("http://www.server.com/file");
httpConnection.setRequestMethod(HttpConnection.GET);
httpConnection.setRequestProperty("Range","0-255");
Check the docs out: HttpConnection