Вы не можете вызывать предварительно подписанный URL-адрес напрямую через браузер.
Вам необходимо передавать заголовки в запросе
x-amz-server-side-encryption- алгоритм клиента
x-amz-шифрование на стороне сервера-ключ клиента
шифрование на стороне сервера x-amz -Customer-key-MD5
Пожалуйста, проверьте документ для получения дополнительной информации https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
При использовании предварительно назначенного URL-адреса для загрузки нового объекта, извлечения существующего объекта или извлечения только метаданных объекта необходимо предоставить все заголовки шифрования в клиентском приложении.
blockquote>Пожалуйста, проверьте пример кода, вызывающего подписанный URL через библиотеку Unirest https://github.com/pavanpawar4591/s3signurlwith-sse-c
public static void getPreSignedURL() throws URISyntaxException { java.util.Date expiration = new java.util.Date(); long expTimeMillis = expiration.getTime(); expTimeMillis += 1000 * 60 * 60; expiration.setTime(expTimeMillis); System.out.println("Generating pre-signed URL."); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, keyName) .withMethod(HttpMethod.GET).withExpiration(expiration).withSSECustomerKey(SSE_KEY); // generatePresignedUrlRequest.setContentType("video/mp4"); generatePresignedUrlRequest.setSSECustomerKeyAlgorithm(SSEAlgorithm.AES256); URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest); System.out.println("Pre-Signed URL: " + url.toURI() + " With key: " + SSE_KEY); System.out.println("------------------------------"); //https://aws.amazon.com/blogs/developer/generating-amazon-s3-pre-signed-urls-with-sse-c-part-4/ // refer to above doc try { HttpResponse
response = Unirest.get(url.toURI().toString()) .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_ALGORITHM, SSEAlgorithm.AES256.getAlgorithm()) .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY, Base64.encodeAsString(SECRET_KEY.getEncoded())) .header(Headers.SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY_MD5, Md5Utils.md5AsBase64(SECRET_KEY.getEncoded())) .header("cache-control", "no-cache").header("postman-token", "d3453c38-1b59-a12e-fd97-dbe2150eadf5") .asString(); System.out.println(response.getStatus()); System.out.println(response.getStatusText()); System.out.println(response.getBody()); } catch (UnirestException e) { e.printStackTrace(); } }
Округление является плохой идеей. Используйте BigDecimal
и установите, это - точность по мере необходимости. Как:
public static void main(String... args) {
float a = 1.2f;
float b = 3.0f;
float c = a * b;
BigDecimal a2 = BigDecimal.valueOf(a);
BigDecimal b2 = BigDecimal.valueOf(b);
BigDecimal c2 = a2.multiply(b2);
BigDecimal a3 = a2.setScale(2, RoundingMode.HALF_UP);
BigDecimal b3 = b2.setScale(2, RoundingMode.HALF_UP);
BigDecimal c3 = a3.multiply(b3);
BigDecimal c4 = a3.multiply(b3).setScale(2, RoundingMode.HALF_UP);
System.out.println(c); // 3.6000001
System.out.println(c2); // 3.60000014305114740
System.out.println(c3); // 3.6000
System.out.println(c == 3.6f); // false
System.out.println(Float.compare(c, 3.6f) == 0); // false
System.out.println(c2.compareTo(BigDecimal.valueOf(3.6f)) == 0); // false
System.out.println(c3.compareTo(BigDecimal.valueOf(3.6f)) == 0); // false
System.out.println(c3.compareTo(BigDecimal.valueOf(3.6f).setScale(2, RoundingMode.HALF_UP)) == 0); // true
System.out.println(c3.compareTo(BigDecimal.valueOf(3.6f).setScale(9, RoundingMode.HALF_UP)) == 0); // false
System.out.println(c4.compareTo(BigDecimal.valueOf(3.6f).setScale(2, RoundingMode.HALF_UP)) == 0); // true
}
По общему правилу, числа с плавающей запятой никогда не следует сравнивать как (a == b) , а как (Math.abs (ab) < delta)
, где delta - небольшое число.
Значение с плавающей запятой, имеющее фиксированное количество цифр в десятичной форме, не обязательно должно иметь фиксированное количество цифр в двоичной форме.
Дополнение для ясности:
Хотя строгое ==
сравнение чисел с плавающей запятой имеет очень мало практического смысла, строгое сравнение <
и >
, напротив, это допустимый вариант использования (пример - логический запуск, когда определенное значение превышает порог: (val> threshold) && panic ();
)
Это слабость всех представлений с плавающей запятой, и это происходит потому, что некоторые числа, которые кажутся фиксированными в десятичной системе, на самом деле имеют бесконечное количество десятичных знаков в двоичной системе. система. Итак, то, что вы думаете, это 1.2, на самом деле что-то вроде 1.199999999997, потому что при представлении его в двоичном формате он должен отрубать десятичные дроби после определенного числа, и вы теряете некоторую точность. Затем умножение его на 3 фактически дает 3,5999999 ...
http://docs.python.org/py3k/tutorial/floatingpoint.html <- это могло бы лучше объяснить это (даже если это для python, это общая проблема представления с плавающей запятой)
Если вас интересуют числа с фиксированной точностью, вам следует использовать тип с фиксированной точностью, например BigDecimal
, а не по своей сути приближенный (хотя и с высокой точностью) тип, например float
. Существует множество похожих вопросов о переполнении стека, которые более подробно рассматриваются на многих языках.
Я думаю, что это не имеет ничего общего с Java, это происходит с любым числом с плавающей запятой IEEE 754. Это из-за природы представления с плавающей запятой. Любые языки, использующие формат IEEE 754, столкнутся с той же проблемой.
Как было предложено Дэвидом выше, вы должны использовать метод abs класса java.lang.Math, чтобы получить абсолютное значение (отбросьте положительный / отрицательный знак).
Вы можете прочитать это: http://en.wikipedia.org/wiki/IEEE_754_revision , а также хороший учебник по численным методам, который удовлетворит проблему.
public static void main(String[] args) {
float a = 1.2f;
float b = 3.0f;
float c = a * b;
final float PRECISION_LEVEL = 0.001f;
if(Math.abs(c - 3.6f) < PRECISION_LEVEL) {
System.out.println("c is 3.6");
} else {
System.out.println("c is not 3.6");
}
}
Как и другие писали:
Сравните числа с плавающей запятой с:
if (Math.abs (a - b)
Вы можете написать хороший метод для этого :
public static int compareFloats(float f1, float f2, float delta)
{
if (Math.abs(f1 - f2) < delta)
{
return 0;
} else
{
if (f1 < f2)
{
return -1;
} else {
return 1;
}
}
}
/**
* Uses <code>0.001f</code> for delta.
*/
public static int compareFloats(float f1, float f2)
{
return compareFloats(f1, f2, 0.001f);
}
Итак, вы можете использовать его так:
if (compareFloats(a * b, 3.6f) == 0)
{
System.out.println("They are equal");
}
else
{
System.out.println("They aren't equal");
}
Чтобы сравнить два числа с плавающей запятой, f1
и f2
с точностью до #. ###
Я полагаю, вам потребуется сделайте так:
((int) (f1 * 1000 + 0.5)) == ((int) (f2 * 1000 + 0.5))
f1 * 1000
поднимает 3,14159265 ...
до 3141,59265
, + 0,5
приводит к 3142,09265
а (int)
отбрасывает десятичные дроби, 3142
. То есть он включает 3 десятичных знака и правильно округляет последнюю цифру.