Skip to content

About

Box Open SDK for Java (open source, community, punk rock). Generated by box-gantry.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Box Open SDK for Java

box-open-sdk (Java)

release Maven Central javadoc license

An open source, community-built Box API client for Java — one resource manager per API area behind a single dev.unofficialbox.Client, over a dependency-free java.net.http runtime with retry, backoff, and token refresh.

Not affiliated with, authorized, or endorsed by Box, Inc. "Box" is a trademark of Box, Inc. This is an independent, generated client.

Install (Maven)

<dependency>
  <groupId>dev.unofficialbox</groupId>
  <artifactId>box-open-sdk</artifactId>
  <version>0.12.0</version>
</dependency>

Quickstart

Authenticate, look up the current user, create a folder, upload a file, extract its fields with Box AI, tag it with metadata, and query for it — end to end. Request bodies use fluent builders:

import dev.unofficialbox.Client;
import dev.unofficialbox.auth.Auth;
import dev.unofficialbox.runtime.Runtime;
import dev.unofficialbox.model.schemas.*;
import java.util.List;
import java.util.Map;

public final class Quickstart {
    public static void main(String[] args) throws Exception {
        // Client Credentials Grant (server-to-server); developer token, OAuth,
        // and JWT also live in dev.unofficialbox.auth.Auth.
        var client = new Client(Auth.clientCredentials(
            Runtime.CcgConfig.enterprise("CLIENT_ID", "CLIENT_SECRET", "ENTERPRISE_ID")));

        // The current user.
        var me = client.users.getMe(null);
        System.out.println("authenticated as " + me.id());

        // Create a folder at the account root ("0").
        var folder = client.folders.create(
            CreateFolderRequest.builder()
                .name("Invoices")
                .parent(AttributesParent.builder().id("0").build())
                .build(),
            null);

        // Upload a file into it.
        var uploaded = client.uploads.uploadFile(
            CreateFileContentRequest.builder()
                .attributes(PostFileContentAttributes.builder()
                    .name("invoice.pdf")
                    .parent(AttributesParent.builder().id(folder.id()).build())
                    .build())
                .file("<file bytes>".getBytes())
                .build(),
            null);
        var fileId = uploaded.entries().orElseThrow().get(0).id();

        // Extract fields from the file with Box AI.
        var answer = client.ai.extract(
            AiExtract.builder()
                .prompt("Extract the invoice number and total amount.")
                .items(List.of(
                    AiItemBase.builder().id(fileId).type(AiCitationType.FILE).build()))
                .build());
        System.out.println(answer);

        // Attach that metadata to the file (an enterprise template).
        client.fileMetadata.createFileMetadata(
            fileId,
            GetFileIdMetadataIdScope.ENTERPRISE,
            "invoiceData",
            Map.of("invoiceNumber", "INV-0042", "total", 1250));

        // Query for files carrying that metadata.
        var results = client.search.queryByMetadata(
            MetadataQuery.builder()
                .from("enterprise_0.invoiceData")
                .ancestorFolderId(folder.id())
                .build());
        System.out.println(results);
    }
}

Parallel chunked upload

BoxChunkedUpload uploads a large file's parts in parallel on virtual threads — no flags needed:

var file = new dev.unofficialbox.BoxChunkedUpload(client)
        .upload(bytes, "large.bin", folderId);

Structured concurrency (opt-in preview)

BoxStructuredChunkedUpload does the same with structured concurrency, a Java preview API. Code that uses it passes --enable-preview at both compile and run time (javac --release 26 --enable-preview …, java --enable-preview …). A preview class only loads on the JDK release it was compiled for (26); the default class has no such limit.

HTTP versions

API requests prefer HTTP/3: the first request goes over HTTP/2 and later ones upgrade once Box advertises HTTP/3 (Alt-Svc), falling back to HTTP/2 or HTTP/1.1. Pick another preference on a configured session:

var session = Runtime.Session.builder(auth)
    .httpVersion(java.net.http.HttpClient.Version.HTTP_2)
    .build();
var client = new Client(session);

The builder also takes maxRetries, default headers, base URLs, or your own HttpClient (which carries its own version — set one or the other). Token requests keep their own client.

Proxies

Requests follow the JVM's default proxy selector: the https.proxyHost / https.proxyPort / http.nonProxyHosts system properties, not the HTTPS_PROXY environment variable. To set one in code instead, give it to both the auth config and the session:

var proxy = java.net.ProxySelector.of(new java.net.InetSocketAddress("proxy.internal", 3128));
var auth = Runtime.clientCredentials(
    Runtime.CcgConfig.enterprise(clientId, clientSecret, enterpriseId).proxy(proxy));
var session = Runtime.Session.builder(auth).proxy(proxy).build();

With a proxy, the built-in client prefers HTTP/2: HTTP/3 runs over UDP, which an HTTP proxy can't carry. An injected HttpClient carries its own proxy — set one or the other.

Hooks and logging

onRequest and onResponse observe every HTTP attempt — each retry and the resend after a token refresh included — with its method, URL, headers (the Authorization value withheld), status, elapsed time, and attempt number:

var session = Runtime.Session.builder(auth)
    .onResponse(r -> System.out.println(
        r.request().method() + " " + r.status() + " " + r.elapsed() + " #" + r.request().attempt()))
    .build();

Hooks observe only; they can't change a request. Token requests are not observed.

debugLogging(System.getLogger("dev.unofficialbox")) logs one line per attempt at DEBUG. Query values whose names look secret (token, secret, password, code, …) read REDACTED; the token and bodies are never logged.

Retries

A 429 is retried for any request; a 5xx or a failed connection only for idempotent methods, since a POST may already have taken effect. Up to five retries wait with exponential backoff and full jitter — up to 500ms·2ⁿ before retry n, capped at 30s — raised to Box's Retry-After when it sends one. A 401 refreshes the token once. Tune the budget and the backoff:

var session = Runtime.Session.builder(auth)
    .maxRetries(3)
    .retryBackoff(java.time.Duration.ofMillis(200), java.time.Duration.ofSeconds(10))
    .build();

Documentation

The docs/ tree carries the per-manager reference — a call snippet for every method — and the authentication, pagination, and errors guides.

About

Box Open SDK for Java (open source, community, punk rock). Generated by box-gantry.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages