I'm using the HttpURLConnection POST to get the response. Im able to get the responsecode 200 but the responseString is getting encoded as below::
���������RP�b��%+c//17�Wr
��u���v����QJ�r��-�N�9���
here is the code I'm using::
public static String getPOSTAJAX(String getURL,String impersonationID,String getPOSTParameters)
{
// get Impersonation ID
String getimpersonationID = "bearer "+impersonationID;
String getResponseline = "";
String getPOSTResponse = null;
String postCookies = "sid="+impersonationID;
try
{
//Open HttpURLConnection
URL url = new URL(getURL);
HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
//add request header
if (impersonationID != null && impersonationID != " ") {
urlConn.setRequestProperty("Authorization", getimpersonationID);
urlConn.setRequestProperty("Accept-Encoding","gzip, deflate");
urlConn.setRequestProperty("Cookie", postCookies);
}
urlConn.setRequestProperty("Accept","application/json,text/plain,*/*");
urlConn.setRequestProperty("Accept-Language", "en-US,en;q=0.8");
urlConn.setRequestProperty("Connection", "keep-alive");
urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.94 Safari/537.36");
urlConn.setRequestMethod("POST");
urlConn.setRequestProperty("Content-Length", String.valueOf(getPOSTParameters.getBytes().length));
urlConn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
//send the POSt Request
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
DataOutputStream writeRequest = new DataOutputStream(urlConn.getOutputStream());
writeRequest.writeBytes(getPOSTParameters);
writeRequest.flush();
writeRequest.close();
//To get the Response Codes
int responseCode = urlConn.getResponseCode();
logger.debug("\nSending 'POST' request to URL::" +url);
logger.debug("Post parameters ::"+getPOSTParameters);
logger.debug("Response Code ::" + responseCode);
//parse the response
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), Charset.forName("UTF-8")));
while((getResponseline = reader.readLine()) != null)
{
builder.append(getResponseline);
builder.append("\n");
}
reader.close();
getPOSTResponse = builder.toString();
//logger.debug("\n "+getPOSTResponse);
//Disconnect the connection
urlConn.disconnect();
}
catch (IOException ioe) {
logger.error("\n"+ioe);
}
return getPOSTResponse;
}
can anyone suggest how to decode the response?
Instead of using InputStreamReader,I would suggest to use InflaterInputStream class,which can be used to uncompress data.
StringBuilder builder = new StringBuilder();
InflaterInputStream in = new InflaterInputStream(urlConn.getInputStream()), new Inflater(true));
int i;
while((i=in.read())!=-1){
builder.append(i);
}
getPOSTResponse = builder.toString();
I 've had the same problem too and I removed all request properties except Content-Type, and now it is working.
Donno how/why it works now.
Related
I have a spring boot service calling another spring boot service.
Both services deployed into docker container.
And when the first service calling the second service, the second service got 401 response. While when i do the same request using PostMan I got a valid response.
Given I am using the credential through postman and the service itself.
Any Idea why this may happen? Is there any related to docker deployment ?
Code used to call the second service
try {
urlStr = licenseRequest.getString(LicenseRequest.URL);
logger.info("URL: "+ urlStr);
URL url = new URL(urlStr);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json");
// auth
String authStrEncoded = Base64Utils.encodeToString((username + ":" + password).getBytes());
con.setRequestProperty("Authorization", "Basic " + authStrEncoded);
if (!licenseRequest.isNull(LicenseRequest.BODY))
{
String body = licenseRequest.getString(LicenseRequest.BODY);
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream (
con.getOutputStream());
wr.write(body.getBytes());
wr.close();
}
//Get Response
InputStream is = con.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder(); // or StringBuffer if Java version 5+
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
}
I am trying to post some data to a server but not getting results as expected.
I get 200 OK response but the returned html source has a string saying
"Error - 404 Page not found"
I think I'm doing something wrong with the set of data that I'm sending.
Maybe I'm missing something as I never worked with multiform data before.
Here is the multiform data that is sent over(I've used tamper data to check what is sent over
POSTDATA =-----------------------------124853047628807
Content-Disposition: form-data; name="mgnlModelExecutionUUID"
4ee01e05-dc16-4535-a222-693b98ec9b69
-----------------------------124853047628807
Content-Disposition: form-data; name="field"
-----------------------------124853047628807
Content-Disposition: form-data; name="name"
test
-----------------------------124853047628807
Content-Disposition: form-data; name="surname"
test
-----------------------------124853047628807
Content-Disposition: form-data; name="age"
test
-----------------------------124853047628807--
In order to send this data, what I did is create a MultipartEntityBuilder like below:
StringBody name = new StringBody("test", ContentType.MULTIPART_FORM_DATA);
StringBody surname = new StringBody("test", ContentType.MULTIPART_FORM_DATA);
StringBody age = new StringBody("test", ContentType.MULTIPART_FORM_DATA);
StringBody field = new StringBody("", ContentType.MULTIPART_FORM_DATA);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addPart("name", name);
builder.addPart("surname", surname);
builder.addPart("age", age);
builder.addPart("field",field);
return builder;
On top of that the headers that I'm sending are as follow:
post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
post.addHeader("Accept", "text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8");
I tried to set the multiform header but it doesn't work
post.addHeader("Content-type", "multipart/form-data");
Any advice on what I might be missing?
THank you
I know i had problems using my code that i have written in order to post some text and also some binary files and ended up writing it for myself the whole application/multipartform .
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundry);
conn.setRequestProperty("Authorization", "----------------------------");
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"user_id\""+lineend+lineend);
out.writeBytes("1"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"preview_id\""+lineend+lineend);
out.writeBytes("1"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"categories_id\""+lineend+lineend);
out.writeBytes("2"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"title\""+lineend+lineend);
out.writeBytes("Mama"+lineend);
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"tags\""+lineend+lineend);
out.writeBytes("mama"+lineend);
out.flush();
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"video\"; filename=\""+file.getName()+"\""+lineend);
out.writeBytes(lineend);
Log.d("UPLOAD", "Titlul video-ului ="+file.getName());
//decoding of bytes from video
FileInputStream file_stream = new FileInputStream(file);
bytesAvailable =file_stream.available();
bufferSize = Math.min(bytesAvailable,maxBufferSize);
buffer = new byte[bufferSize];
Log.d("UPLOAD", "Bytes Read Video =" +bytesRead);
bytesRead = file_stream.read(buffer);
//writting to outputstream
while (bytesRead >0){
out.write(buffer, 0, bytesRead);
bytesRead=file_stream.read(buffer);
}
Log.d("UPLOAD", "Done Loading first buffer");
file_stream.close();
out.writeBytes(twoHiphens+boundry+lineend);
out.writeBytes("Content-Disposition: form-data; name=\"thumb\"; filename=\""+image.getName()+"\""+lineend);
out.writeBytes(lineend);
Log.d("UPLOAD", "Titlul preview-ului ="+image.getName());
//decodint image bytes
FileInputStream image_stream = new FileInputStream(image);
int bytesRead2;
int bytesAvailable2, bufferSize2 ;
bytesAvailable2 = image_stream.available();
bufferSize2 = Math.min(bytesAvailable2, maxBufferSize);
byte []buffer2 = new byte[bufferSize2];
//writing to outputstream
bytesRead2 = image_stream.read(buffer2);
while(bytesRead2>0){
out.write(buffer2, 0, bytesRead2); // bytesAvailable2 = image_stream.available();
bytesRead2 = image_stream.read(buffer2);
}
image_stream.close();
Log.d("UPLOAD", "Done loading the second buffer");
out.writeBytes(twoHiphens+boundry+twoHiphens+lineend);
out.writeBytes(lineend);
out.flush();
out.close();
Log.d("UPLOAD","Response Code = "+conn.getResponseCode());
String responseMessage = conn.getResponseMessage();
Log.d("UPLOAD", "Response Message = "+responseMessage);
InputStream in;
if(conn.getResponseCode() >= 400){
in = conn.getErrorStream();
}else{
in = conn.getInputStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
StringBuilder response = new StringBuilder();
char []bytes = new char[512];
int read ;
while((read = reader.read(bytes))!=-1){
response.append(bytes, 0, read);
}
Log.d("UPLOAD", "Response " +response);
conn.disconnect();
You can omit the code that referrers to binary data . Hope it would give you some help
Maybe the Content Type of each StringBody mustn't be ContentType.MULTIPART_FORM_DATA . Maybe it should be "text/plain "
Try this !
File file = new File(path);
File image = new File("/storage/emulated/0/DCIM/100MEDIA/a_thumbnail.jpg");
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(urls[0]);
HttpResponse response = null ;
post.setHeader("Authorization","----------------------------");
MultipartEntity ent = new MultipartEntity();
try {
ent.addPart("user_id",new StringBody("1"));
ent.addPart("categories_id",new StringBody("3"));
ent.addPart("tags",new StringBody("mama"));
ent.addPart("title",new StringBody("mama"));
ent.addPart("preview_id",new StringBody("2"));
ent.addPart("thumb", new FileBody(image));
ent.addPart("video", new FileBody(file));
post.setEntity(ent);
response = client.execute(post);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
answer= answer+bufferedReader.readLine();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return answer;
}
WebRequest request = WebRequest.Create("https://accounts.google.com/o/oauth2/token");
request.Method = "POST";
string postData = "code=" + code + "&client_id=" + _clientId + "&client_secret=" + _clientSecret + "&redirect_uri=" + _callback_url + "&grant_type=authorization_code";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
I have placed a google sign in button in HTML page, on its callback got auth code to call ajax web servcice containing above code. But I am getting Error 400 on GetResponse(), I don't know why. Can any body please help me?
I have found following link workable in my case:
Code on page Page load :
protected void Page_Load(object sender, EventArgs e)
{
if (Request["code"] != null)
{
vCode = Request["code"].ToString();
getRefreshToken();
}
else
{
Response.Redirect(vAuthURL + "?scope=" + vScope + "&state=%2Fprofile&client_id=" + vClientId + "&redirect_uri=" + vRedURL + "&response_type=code&access_type=offline&approval_prompt=force", false);
}
}
Following function is being called in page load when code is available:
private void getRefreshToken()
{
string vClientId = "974762xxxxxx-xxxxxxxxx.apps.googleusercontent.com";
string vSecCode = "xxxxxxxxxxxxxxx";
string vScope = "https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.login";
string vRedURL = "http://localhost:50488/wwwroot/member/social/googlesignin.aspx";
string vAuthURL = "https://accounts.google.com/o/oauth2/auth";
StringBuilder authLink = new StringBuilder();
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
authLink.AppendFormat("code={0}", vCode);
authLink.AppendFormat("&client_id={0}", vClientId);
authLink.AppendFormat("&client_secret={0}", vSecCode);
authLink.AppendFormat("&redirect_uri={0}", vRedURL);
authLink.Append("&grant_type=authorization_code");
UTF8Encoding utfenc = new UTF8Encoding();
byte[] bytes = utfenc.GetBytes(authLink.ToString());
Stream os = null;
webRequest.ContentLength = bytes.Length; // Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); // Send it
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse == null) { Response.Write("null"); }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
string jsonStr = sr.ReadToEnd().Trim();
}
Probably the important thing was to get code with server side code instead of mixing the client code and server side access_token getting script. Hope this works for you too.
I'm trying to upload an image to my profile using the api but I'm getting a Unknown: NOT_FOUND 404 error. the call I am using is /d2l/api/lp/1.0/profile/myProfile/image, I am passing the content type, length and filename (profileImage). I'm passing the image as a dataStream. I've reduced the size of the image as well. Any ideas?
also here is part of my CallAction code orginally gotten from the Getting Started example
public void CallAction(ID2LUserContext userContext, int retryAttempts, string url, byte[] data, string method = "")
{
Uri uri = userContext.CreateAuthenticatedUri(url, method);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.AllowAutoRedirect = false;
request.Method = method;
if (method.Equals("PUT") || method.Equals("POST"))
{
request.ContentType = "image/jpeg";
//request.Headers.Add("Content-Disposition", "form-data; name=\"profileImage\"; filename=\"profileImage.jpg\"");
request.Headers.Add("Accept-Encoding", "gzip, deflate, compress");
//request.Headers.Add("X-Upload-Content-Type", "image/jpg");
//request.Headers.Add("X-Upload-Content-Length", data.Length.ToString());
//request.Headers.Add("X-Upload-File-Name", "profileImage");
request.ContentLength = data.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(data, 0, data.Length);
dataStream.Flush();
dataStream.Close();
}
}
Also when I run a get to retrieve my photo it also returns a 404 error.
We have tested this call against our test instances here, and it does work. Here's what the HTTP packet headers look like for a valid test call (from a call formed with the python requests module):
{ 'User-Agent': 'python-requests/1.2.3 CPython/3.3.2 Darwin/12.4.0',
'Accept': '*/*',
'Content-Type': 'multipart/form-data; boundary=716acd781e224902854e6845bc62f653',
'Content-Length': '117886',
'Accept-Encoding': 'gzip, deflate, compress' }
to this URL:
https://somelms.edu/d2l/api/lp/1.0/profile/myProfile/image?
x_a={appId}
&x_c=Lz3PDTaUgG46cMF3CajAsiiGzz0C6u5QTLieAmbONZ0
&x_b={userId}
&x_d=7sSqbce1_ictuNAs80n01h0jSI0YxxKbPM01W7f49a0
&x_t={timestamp}
with a body that looks like this (note the part headers in this body, that characterize the content of the single part in the body that contains the image data):
--716acd781e224902854e6845bc62f653
Content-Disposition: form-data; name="profileImage"; filename="profileImage-student.png"
Content-Type: image/png
{image bytes here}
--716acd781e224902854e6845bc62f653--
This code should fix your problem:
public static void UploadFilesToRemoteUrl(byte[] profileImage, ID2LUserContext userContext, string accion)
{
//Reference:
//action = "/d2l/api/lp/1.3/profile/" + profileIdentifier + "/image";
//profileImage = the profileImage of user read from disk:
/*
FileStream fileStream = new FileStream(pictureLocalPath, FileMode.Open, FileAccess.Read);
Byte[] img = new Byte[fileStream.Length];
fileStream.Read(img, 0, Convert.ToInt32(img.Length));
fileStream.Close();
*/
var uri = userContext.CreateAuthenticatedUri(accion, "POST");
string boundary = "bde472ff1f1a46539e54e655857c27c1";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.ContentType = "multipart/form-data; boundary=" +
boundary;
request.Headers.Add("Accept-Encoding", "gzip, deflate, compress");
request.Method = "POST";
request.KeepAlive = true;
request.Proxy.Credentials = new NetworkCredential(Constantes.UsuarioProxy, Constantes.PasswordProxy, Constantes.DominioProxy);
Stream memStream = new System.IO.MemoryStream();
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"profileImage\"; filename=\"profileImage.jpg\"\r\nContent-Type: image/jpeg;\r\n\r\n";
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formdataTemplate);
memStream.Write(formitembytes, 0, formitembytes.Length);
//escribo el array de byte de la imagen
memStream.Write(profileImage, 0, profileImage.Length);
byte[] boundaryClose = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
memStream.Write(boundaryClose, 0, boundarybytes.Length);
StreamReader readerReq = new StreamReader(memStream);
string stringReq = readerReq.ReadToEnd();
request.ContentLength = memStream.Length;
Stream requestStream = request.GetRequestStream();
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string responseValence = reader.ReadToEnd();
response.Close();
}
}
I'm trying to integrate with an API that requires a PUT to update data:
Here's an example from them using curl:
curl --request PUT \
--user-agent "Your Client Name/1.0" \
--header "Content-Type: application/xml" \
--data-binary '<order><status_id>10</status_id></order>' \
https://www.example.com/api/v2/orders/101
However, I'd need to use JSON (they support that as well) using .NET MVC 3. Any idea on how I can do that?
I use the code below for GET successfully:
Order obj = Call<Order>(url, "GET");
private T Call<T>(string url, string methodType) where T : class {
T result;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = methodType;
request.Accept = "application/json";
request.ContentType = "application/json";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = reader.ReadToEnd();
result = (T)jsSerializer.Deserialize<T>(jsonData);
}
return result;
}
However, can I issue a PUT using a similar method?
Order obj = Call<Order>(url, "PUT");
If so, where do I put the data that's required in "data-binary"?
Well, here's a possible point of origin - untested; written straight into the browser; not production code; assumes that the PUT call both sends and receives the same object type (which is probably not the case)...
The main addition is that you need to supply the request's ContentLength, and you need to write the serialized JSON object to the request stream, which you'll get by calling HttpWebRequest::GetRequestStream(). It's the same approach as when POSTing.
private T Call<T>(string url, string methodType, T data) where T: class
{
T result;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = methodType;
request.ContentType = "application/json";
request.Accept = "application/json";
if (methodType == "PUT" || methodType == "POST")
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = jsSerializer.Serialize(data);
byte[] arrData = Encoding.UTF8.GetBytes(jsonData);
request.ContentLength = arrData.Length;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(arrData, 0, arrData.Length);
}
}
// Note: You may not need to parse any response content,
// or it may be a different class
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader
= new StreamReader(response.GetResponseStream()))
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
string jsonData = reader.ReadToEnd();
result = (T)jsSerializer.Deserialize<T>(jsonData);
}
}
return result;
}