I'm using the following two JAVA methods to create a signed URL to upload to Google Cloud Storage, using HTTP PUT. The first method is supposed to generate the actual upload URL using POST, while the second one is supposed to generate the URL using serviceAccountCredentials, to be used(to POST) by the first one.
First Method
 public String getUploadLink(String bucketName, String uuid, String objectName, String mimeType)
        throws IOException, GenericAttachmentException {
    if (!bucketExists(bucketName)) {
        createBucket(bucketName);
    }
    URL myURL = new URL(getSignedUrlToPost(bucketName, uuid, objectName, mimeType));
    HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection();
    myURLConnection.setRequestMethod("POST");
    myURLConnection.setRequestProperty("Content-Type", mimeType);
    myURLConnection.setRequestProperty("x-goog-resumable", "start");
    // Send POST request
    myURLConnection.setDoOutput(true);
    DataOutputStream wr = new DataOutputStream(myURLConnection.getOutputStream());
    wr.flush();
    wr.close();
    int responseCode = myURLConnection.getResponseCode();
    if (responseCode != 201) {
        throw new GenericAttachmentException(500,
                "Error generating signed URL",
                "Something went wrong while attempting to generate the URL.");
    }
    return myURLConnection.getHeaderField("Location");
}
Second Method
private String getSignedUrlToPost(String bucketName, String uuid, String objectName,
                                  String mimeType) throws GenericAttachmentException {
    try {
        String verb = "POST";
        long now = System.currentTimeMillis();
        /* Expire in a minute. */
        long expiryTimeInSeconds = (now + 60 * 1000L) / 1000;
        String canonicalizedExtensionHeaders = "x-goog-resumable:start";
        byte[] sr = serviceAccountCredentials.sign(
                (verb + "\n\n" + mimeType + "\n" + expiryTimeInSeconds + "\n" + canonicalizedExtensionHeaders
                        +
                        "\n" + "/" + bucketName + "/" + uuid + "/" + objectName).getBytes());
        String urlSignature = new String(Base64.encodeBase64(sr));
        return "https://storage.googleapis.com/" + bucketName + "/" + uuid + "/" + objectName +
                "?GoogleAccessId=" + serviceAccountEmail +
                "&Expires=" + expiryTimeInSeconds +
                "&Signature=" + URLEncoder.encode(urlSignature, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        throw new GenericAttachmentException(500,
                "Something went wrong while encoding the URL.",
                e.getMessage());
    }
}
This gives me an upload URL, as follows:
https://storage.googleapis.com/bucket-name/7c9a5bd6-ece2-497d-b485-a9c53e27f253/a.pdf?GoogleAccessId=storage-dev@project-name-xxxxxx.iam.gserviceaccount.com&Expires=1592883655&Signature=IlTGvwGNN8VYrPE9qzSW0AIAwqMvbNoZ34TQ4nr4Po5vwZx78or9iiqBhO0jqoeoX6BYP%2BHGkWPIKMUijB%2FZ0L6Z%2BtnaZZkIJ581YQ3JK8BEHWqWyf0V07RwAN0TGAyld7h1JntWmGDyXKtjmy6Skt1C0GocJZA2x9GMxo94OD9kpFbjBucixgQDE%2BEtCzDUXWkymATls690pyLftXhAI0CVWg%2FPlcAe2Q%2F9M%2F68s5eWVSXa0%2BXIVQQ%2FucgXO8RbEDeu%2BWjrL3TcYQFTFd8Q%2BvcwKkpjbmKGpmMnYuTc7HSKrRWLLGxixsLBSjKdQDK4Tu14%2F0ROJVJo4Gv%2FX4oknQ%3D%3D&upload_id=AAANsUlwcmdpeCuME5YbeSpnfw5eQw_Sb65xl7t59b6GcNkNE0PUfe44tUDXHfobXRo-EBGI6X-I5zPqXyPBm4paSyBGyzZCWw
Issues:
- I'm able to upload an object, using the above 
URL, but the link doesn't expire after one minute. - The link doesn't invalidate itself after the initial upload is done,
meaning, when I use the same link to upload, for example, 
xyz.jpgusingHTTP PUT, it returns200 OK, even though it doesn't actually uploadxyz.jpgand replace the original file. 
Shouldn't the upload link invalidate itself once it is used to upload something to the server? Am i missing something here? Could really use some help.