gpt4 book ai didi

spring - Spring HttpHeaders 中可能存在的错误

转载 作者:行者123 更新时间:2023-12-01 00:14:45 25 4
gpt4 key购买 nike

我发现我认为可能是 Spring 类中的一个错误 HttpHeadersReadOnlyHttpHeaders .在使用 Spring 提出 Jira 缺陷之前,我想确认这一点。这是我用来创建空 HttpHeaders 的代码片段目的:

HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);

然后我使用以下方法将标题添加到我的新对象:
myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip")

在此之后 HttpHeaders.EMPTY不再为空
HttpHeaders.EMPTY.size() == 1

HttpHeaders.EMPTY 的 javadoc 指出:

/**
* The empty {@code HttpHeaders} instance (immutable).
*/
public static final HttpHeaders EMPTY



这里的问题是,当 'HttpHeaders.EMPTY' 在其他地方使用时,它会引入意外的 header 。

考虑以下单元测试:
@Test
public void testUpdateEmptyHeaders() {
assertEquals(0, HttpHeaders.EMPTY.size()); // **Success**
HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);
myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
assertEquals(0, HttpHeaders.EMPTY.size()); // **Assert Fails**
}

@Test
// This test will fail if run after the test above, but will be successful if run by itself
public void testEmptyHeaders() {
assertEquals(0, HttpHeaders.EMPTY.size());
}

以下是单元测试的结果:
// testUpdateEmptyHeaders
08:39:28.450 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@2e222612, testMethod = testUpdateEmptyHeaders@AuditContextTest, testException = java.lang.AssertionError: expected:<0> but was:<1>

java.lang.AssertionError:
Expected :0
Actual :1

// testEmptyHeaders
08:39:28.482 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@2e222612, testMethod = testEmptyHeaders@AuditContextTest, testException = java.lang.AssertionError: expected:<0> but was:<1>

java.lang.AssertionError:
Expected :0
Actual :1

我觉得这是一个错误,因为 HttpHeaders.EMPTY应该是不可变的。
我还可以通过在 Spring HttpHeaders.java 中进行两项更改来解决此问题和 ReadOnlyHttpHeaders.java

最佳答案

是的,你是对的,这可能是 spring 框架的错误 HttpHeaders

public static final HttpHeaders EMPTY

HttpHeaders.EMPTY This will return empty HttpHeaders instance (immutable). (and it is singleton)



案例:1
一起来看看 HttpHeaders.Empty ,它返回不可变对象(immutable对象)
    HttpHeaders head = HttpHeaders.EMPTY;

System.out.println(System.identityHashCode(head)); //1338668845

System.out.println(head.size()); //0

HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);

System.out.println(System.identityHashCode(myHeaders)); //159413332

myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");

head = HttpHeaders.EMPTY;
System.out.println(System.identityHashCode(head)); //1338668845
System.out.println(head.size()); //1
System.out.println(head); //{Accept-Encoding=[gzip]}

HttpHeaders head1 = HttpHeaders.EMPTY;
System.out.println(head1); //{Accept-Encoding=[gzip]}
System.out.println(System.identityHashCode(head1)); //1338668845
结论:

1 : HttpHeaders.EMPTY is always returning the singleton object

2: The problem is when HttpHeaders.EMPTY is passed to writableHttpHeaders method internally the returned object is having relation with HttpHeaders.EMPTY singleton object, look at case 2


案例:2 writableHttpHeaders 返回对象反射(reflect)到 HttpHeaders.EMPTY单例对象(内部和间接)
    HttpHeaders head = HttpHeaders.EMPTY;           

System.out.println(System.identityHashCode(head)); //1338668845

System.out.println(head.size()); //0

HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);

System.out.println(System.identityHashCode(myHeaders)); //159413332

myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");

myHeaders.add("hello", "value");

head = HttpHeaders.EMPTY;
System.out.println(System.identityHashCode(head)); //1338668845
System.out.println(head.size()); //2
System.out.println(head); //{Accept-Encoding=[gzip], hello=[value]}

HttpHeaders head1 = HttpHeaders.EMPTY;
System.out.println(head1); //{Accept-Encoding=[gzip], hello=[value]}
System.out.println(System.identityHashCode(head1)); //1338668845

myHeaders.remove("hello");

System.out.println(System.identityHashCode(head)); //1338668845
System.out.println(head.size()); //1
System.out.println(head); //{Accept-Encoding=[gzip]}

System.out.println(head1); //{Accept-Encoding=[gzip]}
System.out.println(System.identityHashCode(head1)); //1338668845

结论:

1 : add and remove operations performed on myHeaders object are reflecting to HttpHeaders.EMPTY object


案例:3 假设如果我们将 HttpHeaders 对象的空实例传递给 writableHttpHeaders使用构造函数就没有问题,一切都很清楚
    HttpHeaders head = HttpHeaders.EMPTY;

System.out.println(System.identityHashCode(head)); //1338668845

System.out.println(head.size()); //0

HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(new HttpHeaders());

System.out.println(System.identityHashCode(myHeaders)); //1323165413

myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");

myHeaders.add("hello", "value");

head = HttpHeaders.EMPTY;
System.out.println(System.identityHashCode(head)); //1338668845
System.out.println(head.size()); //0
System.out.println(head); //{}

HttpHeaders head1 = HttpHeaders.EMPTY;
System.out.println(head1); //{}
System.out.println(System.identityHashCode(head1)); //1338668845
案例:4 即使间接不可变 HttPHeaders.EMPTY可以修改,但是直接修改还是会报错
    HttpHeaders head = HttpHeaders.EMPTY;

System.out.println(System.identityHashCode(head));

System.out.println(head.size());

HttpHeaders myHeaders = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);

System.out.println(System.identityHashCode(myHeaders));

myHeaders.add(HttpHeaders.ACCEPT_ENCODING, "gzip");

head = HttpHeaders.EMPTY;
System.out.println(System.identityHashCode(head));
System.out.println(head.size());
System.out.println(head);

head.add("hello", "value");
输出:
1338668845
0
159413332
1338668845
1
{Accept-Encoding=[gzip]}
Exception in thread "main" java.lang.UnsupportedOperationException
at org.springframework.http.ReadOnlyHttpHeaders.add(ReadOnlyHttpHeaders.java:67)
at com.demo.NestedJsonParse.main(NestedJsonParse.java:40)
最终结论:是的,这是错误,您可以为 Spring 项目提出错误 spring-bug , 不可变对象(immutable对象)不能改变状态

关于spring - Spring HttpHeaders 中可能存在的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53982635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com