HttpsURLConnection strange characters - java

all.
I'm trying to connect with a service to get a token by HttpsURLConnection(using groovy). The connection works ok, I'm getting an http code 200, but I'm getting the response with all strage characters.
responseCode: 200
Response Code : 200
Response Msg : OK
********** LINE: ‹ -̱
********** LINE: „0Ð^ðdë(‰&±¼ ›uD0’¤Pÿ]‰¶3óæ_WMHÄ)¹^a„NÊnÒDÂÒE…×ÞûóʪÞ!§ÈB>6¾Ý—1r|Þ·9rróý(‡¶}ÒD¡LCðPWçB9ÿý
Response: ‹ -̱„0Ð^ðdë(‰&±¼ ›uD0’¤Pÿ]‰¶3óæ_WMHÄ)¹^a„NÊnÒDÂÒE…×ÞûóʪÞ!§ÈB>6¾Ý—1r|Þ·9rróý(‡¶}ÒD¡LCðPWçB9ÿý
The charset i'm using is UTF-8. I've tried by postman and it works ok. I don't know what i'm doin wrong in my code.
connection.setDoOutput(true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream());
outputStreamWriter.write(Parameters);
outputStreamWriter.flush();
int responseCode = connection.getResponseCode();
String responseMessage = connection.getResponseMessage();
logger.debug("responseCode: " + responseCode);
if(responseCode == 200){
logger.debug("Response Code : " + responseCode);
logger.debug("Response Msg : " + responseMessage);
BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = input.readLine()) != null) { //In this while i'm getting the response from service
response.append(inputLine);
logger.debug("\*\*\*\*\*\*\*\*\*\* LINE: " + inputLine);
}
input.close();
logger.debug("Response: " + response.toString()); //Here i'm printing the response in the log file
JSONObject jsonObj = new JSONObject(response.toString());
token = jsonObj.getString("access_token");

If it is not binary stream, but text this certainly seems like an encoding issue.
By using new InputStreamReader(connection.getInputStream()) you will use the default charset - does that match what is in the stream?
Try looking at what the URLConnection is reporting as the encoding/content type : https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html
Then look how a library handles the conversion, for instance:
Apache's HttpClient BasicHttpClientResponseHandler delegates to EntityUtils, have a look at how that works: EntityUtils.java
But overall, why not save yourself the pain and use a library to do this? Several are discussed here: https://www.baeldung.com/java-http-response-body-as-string

Related

compare HTTP Post between Python and Java (Jenkins 302/403 response code)

I have a simple python code working but I am unable to get it to work in Java
it also works via curl and postman.
Please help
The following code is python and is fairly simple and straightforward. it returns 200.
<!-- language: lang-python -->
import requests
params = (
('member', 'xxx'),
)
response = requests.post('http://jenkinsurl1/submitRemoveMember', params=params, auth=('user', 'notbase64encodedtoken'))
print(response)
Returns 200
The following code is in java and I am unable to find a simple and straightforward way to do this in java.
<!-- language: lang-java -->
//main() function
String auth = "user" + ":" + "notbase64encodedtoken";
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
final String POST_PARAMS = "member=xxxx";
MyPOSTRequest(POST_PARAMS,encodedAuth,"http://jenkinsurl1/submitRemoveMember");
public static void MyPOSTRequest(String Parameters, byte[] encodedAuth, String POST_URL) throws IOException {
URL obj = new URL(POST_URL);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
byte[] postData = Parameters.getBytes( StandardCharsets.UTF_8 );
int postDataLength = postData.length;
con.setRequestMethod("POST");
con.setDoOutput( true );
con.setInstanceFollowRedirects( false );
con.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty( "charset", "utf-8");
con.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));
String authHeaderValue = "Basic " + new String(encodedAuth);
con.setRequestProperty("Authorization", authHeaderValue);
con.setUseCaches( false );
try( DataOutputStream wr = new DataOutputStream( con.getOutputStream())) {
wr.write( postData );
wr.flush();
}
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) { //success
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
// print result
System.out.println(response.toString());
} else {
System.out.println("POST request not worked");
}
}
POST Response Code :: 302
POST request not worked
Your Java code doesn't process redirect response (HTTP code 302).
This was more to do with Jenkins idiosyncrasies than to do with java. The 302 error code was expected and Jenkins accepts and does the work required and returns with 302. Although I don't know how python deals with it internally (and calls two times?) and returns code 200 eventually
FYI if setInstanceFollowedRedirects is set to true, I get a 403
jenkins bug similar unanswered on Stackoverflow
This is how I went around it. Posting for others who might run into it.
int responseCode = con.getResponseCode();
System.out.println("POST Response Code :: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP) { //MOVED_TEMP
String location = con.getHeaderField("Location");
System.out.println(location);
MyPOSTRequest(Parameters, encodedAuth, location); //calling the same function again with redirected url.
}
POST Response Code :: 302
http://jenkinsurl1
POST Response Code :: 200

URLConnection.setRequestProperty() not working?

I'm trying to integrate the Genius API into my Java program but I'm not entirely sure what I'm doing with making the actual HTTP request.
Here's the code I'm trying to use:
URLConnection connection = new URL("https://api.genius.com/search?q=juice").openConnection();
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Authorization", "Bearer TOKEN");
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
return content.toString();
(where TOKEN is my Genius auth token)
but I'm getting an IOException with a 403 forbidden message.
java.io.IOException: Server returned HTTP response code: 403 for URL: https://api.genius.com/search?q=juice
This same request worked when I tried with Hurl.it:
so I'm not exactly sure what's going on here. When I tried printing out the headers to see if they went through, I got this:
System.out.println("auth: " + connection.getHeaderField("Authorization"));
System.out.println("content: " + connection.getHeaderField("Content-Type"));
/** output */
auth: null
content: text/html; charset=UTF-8
I would appreciate any help here - thank you!!

REST API Client response in java encoding trouble

I have a problem with an API call response in java.
See below the API response of my request, server replies with content that is unreadable as text:
Here is my code:
String urlt = "xxxxxx";
URL url = new URL(urlt);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.addRequestProperty("Accept-Encoding", "gzip");
conn.addRequestProperty("User-Agent", "okhttp/3.4.1");
if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
conn.disconnect();
and an example of response headers:
With the following line, you tell the server that you are ready to accept a compressed response:
conn.addRequestProperty("Accept-Encoding", "gzip");
As shown in picture of response headers, the server obliges and gives you gzip-encoded (compressed) content.
But then you proceed to read the response, assuming it's just text... so yeah it prints as garbage in your console.
Either you remove that header above, or be ready to uncompress gzipped content.

Sending Arabic over HTTP post as parameter not working [duplicate]

This question already has answers here:
How to handle Arabic in java
(2 answers)
Closed 6 years ago.
I hit a URL with an Arabic parameter value (like below):
http://62.215.226.164/fccsms_P.aspx?UID=something&P=somethingS=InfoText&G=96567771404&M=اخص شقث غخع خن ؤخةث&L=E
It works perfectly; I get the message on a phone in Arabic. When I try to achieve the same through the following code, though, I only get question marks in the message.
public void sendSms(SendSms object)
throws MalformedURLException, ProtocolException, IOException
{
String message = new String(object.getMessage().getBytes(), "UTF-8");
System.out.println(message); // This also prints only question marks
PrintStream out = new PrintStream(System.out, true, "UTF-8");
out.print(message);
String charset="UTF-8";
URL url = new URL("http://62.215.226.164/fccsms_P.aspx");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Accept-Charset", charset);
con.setRequestMethod("POST");
// con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en,ar_KW;q=0.5");
con.setRequestProperty("Content-Type", "text/html;charset=utf-8");
String urlParameters = "UID=test&P=test&S=InfoText&G=965" + object.getPhone() + "&M= Hello " + object.getName() + " " + message + " &L=A";
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
}
To get the message in Arabic, what do I need to add or change in the code?
If you want to send Arabic data as parameter you need to encode this data to UTF-8.
You can use following code to get the proper output.
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
bw.write(urlParameters);
bw.flush();
bw.close();
The problem occurred in the following code. So replace your code below with the code above.
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
It is because http doesn't support the characterset,
your browser handles url-encoding automatically,
In your code you need to encode each parameter separately because of special characters eg. asuming object.getMessage() does not return ???:
String message = URLEncoder.encode(
""اخص شقث غخع خن ؤخةث",
java.nio.charset.StandardCharsets.UTF_8.toString() );
And then concatenate:
String urlParameters = "UID=...&M=" + message + "&L=A";

Imgur API request using Java returns 400 status

I am trying to send a GET request to the Imgur API to upload an image.
When I use the following code I receive a 400 status response from the Imgur server - which, according to the Imgur error documentation, means I am missing or have incorrect parameters.
I know the parameters are correct as I have tested them directly in the browser URL (which successfully uploads an image) - so I must not be adding the parameters correctly within the code:
private void addImage(){
String data = URLEncoder.encode("image", "UTF-8") + "=" + URLEncoder.encode("http://www.lefthandedtoons.com/toons/justin_pooling.gif", "UTF-8");
data += "&" + URLEncoder.encode("key", "UTF-8") + "=" + URLEncoder.encode("myPublicConsumerKey", "UTF-8");
// Send data
java.net.URL url = new java.net.URL("http://api.imgur.com/2/upload.json");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
Logger.info( line );
}
wr.close();
rd.close();
}
This code is based on the API examples provided by Imgur.
Can anyone tell me what I am doing wrong and how I may resolve the problem?
Thanks.
In this sample, imgur service returns 400 Bad Request status response with a non-empty body because of incorrect API key. In case of non successful HTTP response you shold read the response body from an error input stream. For example:
// Get the response
InputStream is;
if (((HttpURLConnection) conn).getResponseCode() == 400)
is = ((HttpURLConnection) conn).getErrorStream();
else
is = conn.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
And, by the way your example is POST, not GET, because you are sending the parameters in the request body instead of the URL.

Categories