API call missing header information for file transfer - json

i am writing a java code which will send a file to certain URL through a API call, but there is some information miss out during the GET response from the URL, it's seen like my file information missing which are display_name, file_type. The display_name will be the file name of my file Here are the return JSON data
{
   "data_id":"55229f05ab534b08b369c324311e2c99",
   "file_info":{
      "display_name":"",
      "file_size":254,
      "file_type":"Not available",
      "file_type_description":"Not available",
      "md5":"8a0c92123d8ffefd95aa1d3dd239c3f7",
      "sha1":"1cfd579d81df680b64e2127296aac55566b95b59",
      "sha256":"a86758bed1a99e12d301fd8bc90749bef89685b9a9c93ad7fa6ee832cb6a7d4e",
      "upload_timestamp":"2016-11-22T05:12:42.374Z"
   },
here is my sample java source
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
public class SentFile {
public static void main(String [] args) throws ClientProtocolException, IOException
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://192.168.0.25:8008/file");
// File file = new File("testScanFile.txt");
//FileInputStream fileInputStream = new FileInputStream(file);
FileBody bin = new FileBody(new File("testScanFile.txt"));
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
// .addPart("file",bin);
.build();
post.addHeader("content-type","application/json");
post.addHeader("Accept","application/json");
post.setEntity(reqEntity);
//InputStream is = new FileInputStream(file);
// post.setEntity(new FileEntity(file));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
// System.out.println(line);
PrintStream ps = new PrintStream(new FileOutputStream("data_id.txt"));
ps.print(line);
ps.close();
}
}
}
if i try to add in .addPart("file", bin) under the HttpEntity class, it's show me some error message, this is my reference link for the .addPart but when i executed the program, my compiler show me this error
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Type mismatch: cannot convert from MultipartEntityBuilder to HttpEntity
Syntax error on token ".", delete this token
The method build() is undefined for the type SentFile
i also tested this code and no error show up but the display_name still missing
post.addHeader("content-type","application/json");
post.addHeader("Accept","application/json");

You should really post the server API definition, however this example shows the facilities in the Apache Fluent API:
MultipartEntityBuilder.create()
.addBinaryBody("bin" // Important! Defined by the server
, new File("testScanFile.txt") // Not important, user defined
, ContentType.APPLICATION_JSON // Maybe ignored. Depends
, "testScanFile.txt" // User defined
).build();

Related

Google Drive v3 | File Append | com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden

Creating a new CustomerData.json file in Google Drive successfully.
Next operation is to update the CustomerData.json file.
On execution of the below code:
File updatedFile = service.files().update(fileId, file, mediaContent).execute();
the application throws the exception with 403: Forbidden.
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "The resource body includes fields which are not directly writable.",
"reason" : "fieldNotWritable"
} ],
"message" : "The resource body includes fields which are not directly writable."
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:432)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.app.gdrive.DriveQuickStart.updateCustomer(DriveQuickStart.java:171)
at com.app.gdrive.DriveQuickStart.main(DriveQuickStart.java:226)
Obviously I went thru the Google API documentation and code samples available on the internet, along with the StackOverflow solutions... still struggling without success.
Create operation - This creates the CustomerData.json file
public static final String createCustomer() throws IOException, GeneralSecurityException, JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Phone", "3023553505");
jsonObject.put("Name", "Bob Carson");
jsonObject.put("Business", "Spot Clicks");
jsonObject.put("Address", "46 Fairytale Dr, Newark");
jsonObject.put("State", "NJ");
jsonObject.put("Country", "USA");
FileWriter jsonFile = new FileWriter("CustomerData.json");
jsonFile.write(jsonObject.toString());
jsonFile.close();
Drive driveService = getDriveService();
String folderId = "1G9vFaUCsPN6GomJRrK7vML9bSd5Wm63t";
File fileMetadata = new File();
fileMetadata.setName("CustomerData.json");
fileMetadata.setParents(Collections.singletonList(folderId));
java.io.File filePath = new java.io.File("CustomerData.json");
FileContent mediaContent = new FileContent("application/json", filePath);
File file = driveService.files().create(fileMetadata, mediaContent)
.setFields("id, parents").execute();
driveService.permissions().create(file.getId(), new Permission().setRole("writer")
.setType("anyone").setAllowFileDiscovery(false)).execute();
return file.getId();
}
The CustomerData.json file in the drive looks like below:
Update [APPEND] operation - This fails to update the CustomerData.json file
EDIT-1 I need to APPEND additional data into the same json file, I'm not trying to update the existing data in the file.
public static final String updateCustomer(Drive service, String fileId) {
try {
String jsonString = new JSONObject()
.put("Phone", "9840056987")
.put("Name", "Rick Smiley")
.put("Business", "Smiling Bots")
.put("Address", "6 Country Park, Baltimore")
.put("State", "MD")
.put("Country", "USA")
.toString();
File file = service.files().get(fileId).execute();
System.out.println(file.getName());
BufferedWriter writer = new BufferedWriter(new FileWriter(file.getName(), true));
writer.newLine();
writer.write(jsonString);
writer.close();
java.io.File uFile = new java.io.File(file.getName());
FileContent mediaContent = new FileContent("application/json", uFile);
File updatedFile = service.files().update(fileId, file, mediaContent).execute();
return updatedFile.getId();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fileId;
}
The SCOPE is defined as
List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE_FILE);
I tried with DRIVE scope as well... also I deleted the StoredCredential file every time I change the SCOPE.
This code is used for the Desktop App, but later I'm planning use in the mobile app as well.
Quick help is appreciated
I got it resolved - here is the solution
in the updateCustomer() create a new File object like below and use that new object
File updateFile = new File();
updateFile.setName(file.getName());
Use that updateFile object thereafter

Apache HTTPClient DigestAuth doesn't forward "opaque" value from Challenge

I'm trying to use Digest authentication with HTTP Client against a 3rd-party web service that I don't control.
I started out with the sample code from here:
http://hc.apache.org/httpcomponents-client-4.5.x/httpclient/examples/org/apache/http/examples/client/ClientPreemptiveDigestAuthentication.java
I got it working against httpbin.org, before attempting the next step described below.
It appears that the target 3rd-party service that I'm using requires the opaque value to be copied from the WWW-Authentication header on the initial response to the Authorization header on the next request, as described here:
https://security.stackexchange.com/questions/24425/what-is-the-opaque-field-in-http-digest-access-authentication-used-for
However, I have turned on wire-logging and stepped through the code (again this is really just the sample code linked above, no need to copy/paste it here) and I see that the opaque is NOT copied.
Any ideas what prevents it from being copied?
I even tried overriding the processChallenge method:
DigestScheme digestAuth = new DigestScheme() {
#Override
public void processChallenge(
Header header) throws MalformedChallengeException {
but it appears that any value introduced into the Parameters at this point is ignored in the next request.
Finally fixed by overriding the Authorize header explicitly, instead of relying on the internals of HttpClient to do it automatically:
package [...];
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.*;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.*;
import org.testng.Assert;
public class DigestTest {
private static final String URL
= "https://...";
private static final String PASSWORD = ...;
private static final String USER = ...;
public static void main(String[] args) throws Exception {
new DigestTest().run();
}
public void run() throws Exception {
HttpGet httpget = new HttpGet(URL);
HttpHost target
= new HttpHost(httpget.getURI().getHost(), 443, "https");
CredentialsProvider credsProvider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials(USER, PASSWORD);
credsProvider.setCredentials(
new AuthScope(target.getHostName(), target.getPort()),
credentials);
CookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpclient
= HttpClients.custom().setDefaultCookieStore(cookieStore)
.setDefaultCredentialsProvider(credsProvider).build();
try {
DigestScheme digestAuth = new DigestScheme();
digestAuth.overrideParamter("qop", "auth");
digestAuth.overrideParamter("nc", "0");
digestAuth.overrideParamter("cnonce", DigestScheme.createCnonce());
AuthCache authCache = new BasicAuthCache();
authCache.put(target, digestAuth);
HttpClientContext localContext = HttpClientContext.create();
localContext.setAuthCache(authCache);
CloseableHttpResponse response;
response = httpclient.execute(target, httpget, localContext);
Map<String, String> wwwAuth = Arrays
.stream(response.getHeaders("WWW-Authenticate")[0]
.getElements())
.collect(Collectors.toMap(HeaderElement::getName,
HeaderElement::getValue));
// the first call ALWAYS fails with a 401
Assert.assertEquals(response.getStatusLine().getStatusCode(), 401);
digestAuth.overrideParamter("opaque", wwwAuth.get("opaque"));
digestAuth.overrideParamter("nonce", wwwAuth.get("nonce"));
digestAuth.overrideParamter("realm", wwwAuth.get("Digest realm"));
Header authenticate = digestAuth.authenticate(credentials, httpget,
localContext);
httpget.addHeader(authenticate);
response = httpclient.execute(target, httpget, localContext);
// the 2nd call is the real deal
Assert.assertEquals(response.getStatusLine().getStatusCode(), 200);
System.out.println(IOUtils
.toString(response.getEntity().getContent(), "utf-8"));
} finally {
httpclient.close();
}
}
}

Creating a JSON file from a url

Hi guys I have a problem creating a JSON file from a google url that i have. This is my code that im using.
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadUrl {
public String readUrl(String strUrl) throws IOException, InterruptedException {
Log.d("URLS = ",strUrl);
Thread.sleep(2000);
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
Log.d("downloadUrl", data.toString());
br.close();
} catch (Exception e) {
Log.d("Exception", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
}
It works fine when i throw a url that looks like this into it.
https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=40.7207523,-73.383851&radius=4828&type=bar&key=MYKEY
But when i try and throw a url that looks like this into it.
https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJe3AmoGsr6IkRuWcK1LAh-DE&key=MYKEY
I get an error: D/GooglePlacesReadTask: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.InputStream.close()' on a null object reference
I dont know how i fix this. Any help?
Aah
you did not mention this is in android,
I presume this because you said ,
android.os.NetworkOnMainThreadException
in your comment
Android does not allow time consuming tasks on main thread,
use AsyncTask to call your function or use plain old java thread
Network on main thread exception comes when you run a networking operation on main thread .
Generally AsyncTask is used for these works but if you want to use the same code you written Just add..
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

What does this socket error mean?

First of all thanks to everyone that answers questions on here. I have used this forum as a java bible. This is a homework problem and here is the assignment:
Write a program in Java that uses sockets to connect to a web server on port 80, requests a web page using GET of the HTTP protocol, and displays the resulting HTML
Not sure if I am doing this right or not. I have a very limited understanding of java. Most of this is from tutorials I have been going through. Any website links would be greatly appreciated.
Here is my error message:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Type mismatch: cannot convert from java.net.Socket to Socket
The method getInputStream() is undefined for the type Socket
Here is my code:
import java.io.*;
import java.net.*;
public class Server
{
public static void main(String[] args) throws Exception
{
Server SERVER = new Server();
SERVER.run();
}
public void run() throws Exception
{
ServerSocket one = new ServerSocket(80);
//these are the two lines of code it is warning about
Socket myskt = one.accept();
InputStreamReader IR = new InputStreamReader(myskt.getInputStream());
//end of warnings
BufferedReader BR = new BufferedReader(IR);
String message = BR.readLine();
System.out.println(message);
if (message != null)
{
PrintStream PS = new PrintStream(System.out);
PS.println("Message Received");
}
URL website = new URL("www.dogs.com");
URLConnection yc = website.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in .readLine()) != null)
System.out.println(inputLine);
one.close();
}
// TODO Auto-generated method stub
}
The issue is that our code is not well-formed - you have a compilation error. My guess is that you have a class Socket in the same package as the class you're compiling, or a left-over class file (Socket.class) on the classpath. When the compiler runs, it uses the package local version of Socket, which is not the same type as java.net.Socket - hence the exception.
To resolve thisuse the fully qualified name java.net.Socket when declaring myskt

Why JSONArray is throwing ClassNotFound Exception from JSP?

Map countryList = new HashMap();
String str = "http://10.10.10.25/TEPortalIntegration/CustomerPortalAppIntegrationService.svc/PaymentSchedule/PEPL/Unit336";
try {
URL url = new URL(str);
URLConnection urlc = url.openConnection();
BufferedReader bfr = new BufferedReader(new InputStreamReader(
urlc.getInputStream()));
String line, des;
double title;
final StringBuilder builder = new StringBuilder(2048);
while ((line = bfr.readLine()) != null) {
builder.append(line);
}
// convert response to JSON array
final JSONArray jsa = new JSONArray(builder.toString());
// extract out data of interest
for (int i = 0; i < jsa.length(); i++) {
final JSONObject jo = (JSONObject) jsa.get(i);
title = jo.getDouble("NetAmount");
countryList.put(i, title);
}
System.out.println(countryList); /* Giving result if i run in Console*/
} catch (Exception e) {
// TODO: handle exception
}
renderRequest.setAttribute("out-string", countryList);
The above code is to consume JSON web services from java client. I am able to access it from java console application. But when trying with JSP or Liferay its not working. In JSP its giving java.lang.NoClassDefFoundError: org/json/JSONArray. Please help me to fix it.
Should i need to add any more jar files to the libraries to make it working in JSP?
You need to add the jar file containing JSONArray class in your web application as per this directory structure:
Tomcat_HOME
->
webapps
->
YourWebAppName
->
WEB-INF
->lib
->Here goes your jar file
Instead of using json.org.JSONArray, have you considered using Liferay's JSON API?
You can import:
import com.liferay.portal.kernel.json.JSONArray;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
They do something like:
JSONObject jsonObject = JSONFactoryUtil.createJSONObject(myJSONObjectString);
JSONArray jsonArray = JSONFactoryUtil.createJSONArray(myJSONArrayString);
This way there is no additional JAR required!