MS Graph API: Getting 404 when saving to _layouts folder - java

I'm using the MS Graph Java SDK to save a file to user's OneDrive and under a given path:
#Test
public void createDriveItem() {
String fileName = "moon.pdf";
String fullPath = "a/_layouts/b" + fileName;
byte[] content = Files.readAllBytes(Paths.get(fileName));
graph.users(userId)
.drive()
.root()
.itemWithPath(encodePath(fullPath))
.content()
.buildRequest()
.put(content);
}
private String encodePath(String path) {
String encoding = StandardCharsets.UTF_8.name();
try {
return URLEncoder.encode(path, encoding);
} catch (UnsupportedEncodingException e) {
return path;
}
}
I'm using MS Graph Java SDK v2.5.0, Java 11.
However, this request fails with 404 : Not Found. It also fails if I don't encode the path. It looks like the /_layouts/ which is making troubles because, once I add something to it, the request works.
Also, I reproduced this error with a number of accounts.
My question is: Is this actually expected? If yes, why does creating the same folder structure work when done through the web UI?

I believe you should not be able to add items into /_layouts/ on SharePoint Online.

Related

Google drive api to get all children is not working if I dynamically pass fileId to query

I am trying google drive api to search parents of a folder. In search query i have to pass file id dynamically instead of hard coding. I tried below code. but I am getting file not found json response.
here its not taking fileId as value i think its consider as String
if I hardcode the value it is working.
FileList result = service.files().list().setQ("name='testfile' ").execute();
for (com.google.api.services.drive.model.File file : result.getFiles()) {
System.out.printf("Found file: %s (%s)\n",
file.getName(), file.getId());
String fileId =file.getId();
FileList childern = service.files().list().setQ(" + \"file.getId()\" in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
This should help.
String fileid=file.getId()
service.files().list().setQ("'" + fileId + "'" + " in parents").setFields("files(id, name, modifiedTime, mimeType)").execute();
Make sure you have valid file.getId()
I know your question states java but the only sample of this working is in C#. Another issue is as far as i know PageStreamer.cs does not have an equivalent in the java client library.
I am hoping that C# and java are close enough that this might give you some ideas of how to get it working in Java. My java knowledge is quote basic but i may be able to help you debug it if you want to try to convert this.
try
{
// Initial validation.
if (service == null)
throw new ArgumentNullException("service");
// Building the initial request.
var request = service.Files.List();
// Applying optional parameters to the request.
request = (FilesResource.ListRequest)SampleHelpers.ApplyOptionalParms(request, optional);
var pageStreamer = new Google.Apis.Requests.PageStreamer<Google.Apis.Drive.v3.Data.File, FilesResource.ListRequest, Google.Apis.Drive.v3.Data.FileList, string>(
(req, token) => request.PageToken = token,
response => response.NextPageToken,
response => response.Files);
var allFiles = new Google.Apis.Drive.v3.Data.FileList();
allFiles.Files = new List<Google.Apis.Drive.v3.Data.File>();
foreach (var result in pageStreamer.Fetch(request))
{
allFiles.Files.Add(result);
}
return allFiles;
}
catch (Exception Ex)
{
throw new Exception("Request Files.List failed.", Ex);
}

How to use Azure storage blob services [duplicate]

This question already has answers here:
Compiler error "archive for required library could not be read" - Spring Tool Suite
(24 answers)
Closed 4 years ago.
I need your help as I am new to this field. I want to use Azure storage blob service to upload images, list and download, but I am facing some problems.
I have imported a project from this repository, and as soon as I import I am getting errors:
Description Resource Path Location Type
Archive for required library: 'C:/Users/NUTRIP-DEVLP1/.m2/repository/org/apache/commons/commons-lang3/3.4/commons-lang3-3.4.jar' in project 'blobAzureApp' cannot be read or is not a valid ZIP file blobAzureApp Build path Build Path Problem
Description Resource Path Location Type
The project cannot be built until build path errors are resolved blobAzureApp Unknown Java Problem
Should I run this as a normal Java application or a Maven project? If Maven, how do I run it?
I suggest you using official java sdk in your maven project.
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>10.1.0</version>
</dependency>
sample upload code:
static void uploadFile(BlockBlobURL blob, File sourceFile) throws IOException {
FileChannel fileChannel = FileChannel.open(sourceFile.toPath());
// Uploading a file to the blobURL using the high-level methods available in TransferManager class
// Alternatively call the Upload/StageBlock low-level methods from BlockBlobURL type
TransferManager.uploadFileToBlockBlob(fileChannel, blob, 8*1024*1024, null)
.subscribe(response-> {
System.out.println("Completed upload request.");
System.out.println(response.response().statusCode());
});
}
sample list code:
static void listBlobs(ContainerURL containerURL) {
// Each ContainerURL.listBlobsFlatSegment call return up to maxResults (maxResults=10 passed into ListBlobOptions below).
// To list all Blobs, we are creating a helper static method called listAllBlobs,
// and calling it after the initial listBlobsFlatSegment call
ListBlobsOptions options = new ListBlobsOptions(null, null, 10);
containerURL.listBlobsFlatSegment(null, options)
.flatMap(containersListBlobFlatSegmentResponse ->
listAllBlobs(containerURL, containersListBlobFlatSegmentResponse))
.subscribe(response-> {
System.out.println("Completed list blobs request.");
System.out.println(response.statusCode());
});
}
private static Single <ContainersListBlobFlatSegmentResponse> listAllBlobs(ContainerURL url, ContainersListBlobFlatSegmentResponse response) {
// Process the blobs returned in this result segment (if the segment is empty, blobs() will be null.
if (response.body().blobs() != null) {
for (Blob b : response.body().blobs().blob()) {
String output = "Blob name: " + b.name();
if (b.snapshot() != null) {
output += ", Snapshot: " + b.snapshot();
}
System.out.println(output);
}
}
else {
System.out.println("There are no more blobs to list off.");
}
// If there is not another segment, return this response as the final response.
if (response.body().nextMarker() == null) {
return Single.just(response);
} else {
/*
IMPORTANT: ListBlobsFlatSegment returns the start of the next segment; you MUST use this to get the next
segment (after processing the current result segment
*/
String nextMarker = response.body().nextMarker();
/*
The presence of the marker indicates that there are more blobs to list, so we make another call to
listBlobsFlatSegment and pass the result through this helper function.
*/
return url.listBlobsFlatSegment(nextMarker, new ListBlobsOptions(null, null,1))
.flatMap(containersListBlobFlatSegmentResponse ->
listAllBlobs(url, containersListBlobFlatSegmentResponse));
}
}
sample download code:
static void getBlob(BlockBlobURL blobURL, File sourceFile) {
try {
// Get the blob using the low-level download method in BlockBlobURL type
// com.microsoft.rest.v2.util.FlowableUtil is a static class that contains helpers to work with Flowable
blobURL.download(new BlobRange(0, Long.MAX_VALUE), null, false)
.flatMapCompletable(response -> {
AsynchronousFileChannel channel = AsynchronousFileChannel.open(Paths
.get(sourceFile.getPath()), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
return FlowableUtil.writeFile(response.body(), channel);
}).doOnComplete(()-> System.out.println("The blob was downloaded to " + sourceFile.getAbsolutePath()))
// To call it synchronously add .blockingAwait()
.subscribe();
} catch (Exception ex){
System.out.println(ex.toString());
}
}
More details, please refer to this doc.Hope it helps you.

sparkjava: Load PNG as base64 from InputStream

I have the following method to load resources as String where path is the String to the resource on my classpath (which works just fine on plain text):
try (Scanner scanner = new Scanner(MyClass.class.getResourceAsStream(path))) {
return scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
}
Now I want to load a PNG image as a base64 String so I can send it back through sparkjava with Content-Type: image/png.
How can I do that?
Do not use any libraries, only plain old Java.
After setting the MIME type in the header with response.header("Content-Type", "image/png") (look up your MIME type here), you can use this:
try {
return Files.readAllBytes(Paths.get(MyClass.class.getResource(path).toURI()));
} catch (IOException | URISyntaxException exception) {
exception.printStackTrace();
}
return null;
Apart from that, to base64-encode a String in Java 8, you can use the java.util.Base64.Encoder class, so you'd just run the result of the method I posted in my description through
Base64.getMimeEncoder().encodeToString(resourceAsString.getBytes(StandardCharsets.UTF_8))
and send it back as response. I haven't got it to work for me though, for some odd reason. I simply used my framework's static files feature.

How to know whether a string path is Web URL or a File based

I have a text field to acquire location information (String type) from User. It could be file directory based (e.g. C:\directory) or Web url (e.g. http://localhost:8008/resouces). The system will read some predetermined metadata file from the location.
Given the input string, how can I detect the nature of the path location whether it is a file based or Web URL effectively.
So far I have tried.
URL url = new URL(location); // will get MalformedURLException if it is a file based.
url.getProtocol().equalsIgnoreCase("http");
File file = new File(location); // will not hit exception if it is a url.
file.exist(); // return false if it is a url.
I am still struggling to find a best way to tackle both scenarios. :-(
Basically I would not prefer to explicitly check the path using the prefix such as http:// or https://
Is there an elegant and proper way of doing this?
You can check if the location starts with http:// or https://:
String s = location.trim().toLowerCase();
boolean isWeb = s.startsWith("http://") || s.startsWith("https://");
Or you can use the URI class instead of URL, URI does not throw MalformedURLException like the URL class:
URI u = new URI(location);
boolean isWeb = "http".equalsIgnoreCase(u.getScheme())
|| "https".equalsIgnoreCase(u.getScheme())
Although new URI() may also throw URISyntaxException if you use backslash in location for example. Best way would be to either use prefix check (my first suggestion) or create a URL and catch MalformedURLException which if thrown you'll know it cannot be a valid web url.
If you're open to the use of a try/catch scenario being "elegant", here is a way that is more specific:
try {
processURL(new URL(location));
}
catch (MalformedURLException ex){
File file = new File(location);
if (file.exists()) {
processFile(file);
}
else {
throw new PersonalException("Can't find the file");
}
}
This way, you're getting the automatic URL syntax checking and, that failing, the check for file existence.
you can try:
static public boolean isValidURL(String urlStr) {
try {
URI uri = new URI(urlStr);
return uri.getScheme().equals("http") || uri.getScheme().equals("https");
}
catch (Exception e) {
return false;
}
}
note that this will return false for any other reason that invalidates the url, ofor a non http/https url: a malformed url is not necessarily an actual file name, and a good file name can be referring to a non exisiting one, so use it in conjunction with you file existence check.
public boolean urlIsFile(String input) {
if (input.startsWith("file:")) return true;
try { return new File(input).exists(); } catch (Exception e) {return false;}
}
This is the best method because it is hassle free, and will always return true if you have a file reference. For instance, other solutions don't and cannot cover the plethora of protocol schemes available such as ftp, sftp, scp, or any future protocol implementations. So this one is the one for all uses and purposes; with the caveat of the file must exist, if it doesn't begin with the file protocol.
if you look at the logic of the function by it's name, you should understand that, returning false for a non existent direct path lookup is not a bug, that is the fact.

How to pass URL parameters from Java to local HTML file in Windows 7?

I desperately need your expertise in resolving a Windows-7 issue.
Scenario: I have a frame-based Help package that is set up for context-sensitive help calls. A Java application is able to control what page the Help packages opens to by passing a tag representing the desired HTML named anchor to an HTML file called pophelp. This file has javascripting that reads the passed tag from the end of the URL and maps it to the appropriate HTML file in the help package and opens it.
Issue: The above scenario works in Windows XP, but no longer in Windows 7.
Calling mechanism from Java application: rundll32 url.dll,FileProtocolHandler file://filepath/pophelp.html?tag
Summary of findings so far: It appears that url.dll no longer allows parameters to be passed with URLs in Windows 7. Parameters are being stripped. I also tried the same type of call using Desktop.getDesktop().browse() from Java, but it too seems to strip off all parameters after .html.
Sample code:
Original call that works in Windows XP --
Running command: rundll32 url.dll,FileProtocolHandler file://C:\Program Files\App System\App-Editor-8.0.1\help\pophelp.html?TAG=callsubflow
Result: ?TAG=callsubflow is not passed.
New code using Desktop.getDesktop().browse() --
public static void main(String[] args) {
String url = "file:///C:/Program Files/App System/App-Editor-8.0.1/help/pophelp.html?TAG=callsubflow";
try {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new URI(url.replace(" ", "%20")));
}
}
} catch (IOException e) {
System.out.println("Unable to open "+url+": "+e.getMessage());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
Result: ?TAG=callsubflow is not passed.
Any assistance would be appreciated!
I really can't tell why Windows removes parameters on local files. As mentioned in the comments this seams to be some kind of weird restrictions for security. But I once had a similar problem and I found a workaround that fits in this situation as well.
Simply create a local temporary HTML file (without parameters) that redirects you to the desired one (with parameters).Have a look at these two methods:
// creates w3c conform redirect HTML page
public String createRedirectPage(String url){
return "<!DOCTYPE HTML>" +
"<meta charset=\"UTF-8\">" +
"<meta http-equiv=\"refresh\" content=\"1; url=" + url + "\">" +
"<script>" +
"window.location.href = \"" + url + "\"" +
"</script>" +
"<title>Page Redirection</title>" +
"<!-- Note: don't tell people to `click` the link, just tell them that it is a link. -->" +
"If you are not redirected automatically, follow the <a href='" + url + "'>link</a>";
}
// creates temporary file with content of redirect HTML page
public URI createRedirectTempFile(String url) {
BufferedWriter writer = null;
File tmpFile = null;
try {
// creates temporary file
tmpFile = File.createTempFile("pophelp", ".html", null);
// deletes file when the virtual machine terminate
tmpFile.deleteOnExit();
// writes redirect page content to file
writer = new BufferedWriter(new FileWriter(tmpFile));
writer.write(createRedirectPage(url));
writer.close();
}
catch (IOException e) {
return null;
}
return tmpFile.toURI();
}
Now you can use these like this:
String url = "file:///C:/Program Files/App System/App-Editor-8.0.1/help/pophelp.html?TAG=callsubflow";
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(createRedirectTempFile(url.replace(" ", "%20")));
}
}
I have a solution, not a quick (or pretty) solution, but a solution nonetheless :)
rundll32 url.dll,FileProtocolHandler does pass params when using URLs with http/s protocol (try rundll32 url.dll,FileProtocolHandler http://www.google.com?q=google), so you can setup small http server (like Jetty i guess) to serve your help files and show them using
rundll32 url.dll,FileProtocolHandler http://localhost:[helpServerIp]/help/pophelp.html?TAG=callsubflow

Categories

Resources