gpt4 book ai didi

spring - Wiremock 为 Spring Cloud Contract stub 运行器返回错误的内容类型

转载 作者:行者123 更新时间:2023-12-05 06:33:41 25 4
gpt4 key购买 nike

我是第一次尝试 Spring-Cloud-Contract。我试图让我的客户自动发现契约(Contract) stub ,但即使我的契约(Contract)在响应中指定了“application/json”的内容类型,我从 WireMock 获得的内容类型为“application/octet” '.我做错了什么?

我的服务中有一个简单的方法,它从 /status 端点返回这样的模型:

{
"name": string,
"status": string
}

我的契约(Contract)是这样的:

import org.springframework.cloud.contract.spec.Contract

Contract.make {
request {
method('GET')
headers {
contentType(applicationJson())
}
url("/status")
}

response {
status OK()
body(
name: "Demo",
status: "RUNNING"
)
headers {
contentType(applicationJson())
}
}
}

在我的客户端中,我有一个使用 Spring RestTemplate 来查询此端点的类:

@Component
public class StatusClient {

private final RestTemplate restTemplate;

public StatusClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

public Status getStatus() {
return this.restTemplate
.exchange("http://localhost:8080/status", HttpMethod.GET, null, Status.class)
.getBody();
}
}

@Data
class Status implements Serializable {
private String name;
private String status;
}

我的单元测试使用 @AutoConfigureStubRunner 从本地存储库中提取最新版本的合约,并对来自合约的响应进行断言(例如名称 = Demo,状态 = RUNNING)。

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureStubRunner(ids = {"com.example:contract-demo:+:8080"}, stubsMode = StubRunnerProperties.StubsMode.LOCAL)
public class StatusClientTests {

@Autowired
private StatusClient client;

@Test
public void testThatStatusReturnsSuccessfully() {
Status result = this.client.getStatus();
assertEquals("Demo", result.getName());
assertEquals("RUNNING", result.getStatus());
}
}

当我运行测试时,WireMock 报告它按预期收到的契约(Contract):

2018-05-31 11:36:49.919  INFO 14212 --- [tp1255723887-26] WireMock                                 : Request received:
127.0.0.1 - GET /status

User-Agent: [Java/1.8.0_161]
Connection: [keep-alive]
Host: [localhost:8080]
Accept: [application/json, application/*+json]



Matched response definition:
{
"status" : 200,
"body" : "{\"name\":\"Demo\",\"status\":\"RUNNING\"}",
"headers" : {
"contentType" : "application/json"
},
"transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 200
contentType: [application/json]

但是当 RestTemplate 尝试反序列化它时,它会抛出异常,因为一旦它命中提取数据的方法,响应内容类型实际上是“application/octet”:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.example.contractclientdemo.Status] and content type [application/octet-stream]

at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:119)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:991)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:974)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:725)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:680)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:600)
at com.example.contractclientdemo.StatusClient.getStatus(StatusClient.java:18)

我正在为 Spring 云版本使用 Finchley.RC2,并且 spring-cloud-starter-contract-stub-runner 是我除了 spring-boot-starter 之外唯一的测试依赖项-测试

我知道 WireMock 返回了错误的内容类型,因为我深入调试了 Spring 中的 HttpMessageConverterExtractor 类,这就是 getContentType 方法在查询时返回的内容。

为什么 WireMock 返回错误的内容类型,尽管它在日志中报告了正确的内容类型?我怎样才能让它正确返回一个 application/json 以便我可以反序列化我的简单消息?

最佳答案

我遇到了和你完全一样的问题。我通过添加

解决了它
headers {
header 'Content-Type': 'application/json;charset=UTF-8'
}

响应。您的回复中似乎有,虽然是以另一种方式写的,但这确实解决了我的问题。所以这与它有关。

在进行更改之前,curl 显示没有 Content-Type 响应 header :

curl -v -H "Accept: application/json" localhost:6565/products/ABC
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 6565 (#0)
GET /products/ABC HTTP/1.1
Host: localhost:6565
User-Agent: curl/7.58.0
Accept:application/json

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Server: Jetty(9.2.z-SNAPSHOT)

Connection #0 to host localhost left intact

{  
"price": {
"currencyCode": "EUR",
"value": "100.50"
},
"name": "Fake product"
}

完成更改后,curl 返回了这个并且 RestTemplate 设法反序列化了它。

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Server: Jetty(9.2.z-SNAPSHOT)

这是我的工作契约(Contract):

import org.springframework.cloud.contract.spec.Contract
Contract.make {
description "should return product information"
request{
method GET()
url("/products/ABC")
}
response {
status 200
headers {
header 'Content-Type': 'application/json;charset=UTF-8'
}
body([
name: 'Fake product',
price:[
currencyCode: 'EUR',
value: 100.50
]
])
}
}

希望对你有帮助

关于spring - Wiremock 为 Spring Cloud Contract stub 运行器返回错误的内容类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50630316/

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