自定义ResponseEntity未反序列化

问题描述 投票:0回答:1

我想从我的

ResponseEntity
方法(子类)返回自定义
@Controller
。但是,在我的测试中反序列化时遇到困难。这是 MRE:

import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
public class FallbackController {
    @GetMapping("/fallback/{app-name}")
    public Mono<CircuitBreakerFallbackMessage> getFallback(@PathVariable("app-name") String appName) {
        return Mono.just(new CircuitBreakerFallbackMessage(appName));
    }

    @Getter
    public static class CircuitBreakerFallbackMessage extends ResponseEntity<Map<String, String>> {
        @JsonCreator
        public CircuitBreakerFallbackMessage(String message) {
            super(buildMessage(message), HttpStatus.GATEWAY_TIMEOUT);
        }

        private static Map<String, String> buildMessage(String appName) {
            String message = MessageFormat.format("{0} is currently unavailable", appName);
            HashMap<String, String> messageMap = new HashMap<>();
            messageMap.put("message", message);
            return messageMap;
        }
    }
}
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.reactive.server.WebTestClient;

import java.text.MessageFormat;
import java.util.Map;
import java.util.regex.Pattern;

import static org.assertj.core.api.Assertions.assertThat;

@WebFluxTest(controllers = FallbackController.class)
class FallbackControllerTest {
    @Autowired
    WebTestClient testClient;

    @Test
    void testGetFallback() {
        String appName = "some-app";
        CircuitBreakerFallbackMessage fallbackMessage = testClient
                .get()
                .uri(MessageFormat.format("/fallback/{0}", appName))
                .exchange()
                .expectStatus().isEqualTo(HttpStatus.GATEWAY_TIMEOUT)
                .expectBody(CircuitBreakerFallbackMessage.class) // it throws here
                .returnResult()
                .getResponseBody();
        assertThat(fallbackMessage).isNotNull();
        Map<String, String> fallbackMessageBody = fallbackMessage.getBody();
        assertThat(fallbackMessageBody).isNotNull();
        assertThat(fallbackMessage)
                .extracting(fallbackMessageBody.get("message"))
                .asString()
                .containsPattern(Pattern.compile(appName + " (is )?(currently )?unavailable"));
    }
}
<!--I won't include the entire pom, but you'd need these -->
<!-- Boot 3.2.1 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

结果:

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.example.dynamicgateway.controller.FallbackController$CircuitBreakerFallbackMessage` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (org.springframework.core.io.buffer.DataBufferInputStream); line: 1, column: 2]

我的错误是什么?

在同步应用程序中,如果没有任何

ResponseEntity
@JsonCreator
反序列化不是很好吗?我认为课堂上缺少 Jackson 注释不应该成为问题

java spring-boot spring-mvc jackson
1个回答
0
投票

看起来您正在序列化为 JSON 对象,如下所示:

{ "message": "example message" }

但是用

@JsonCreator
注解的构造函数只有一个字符串参数。您可以尝试将构造函数更改为:

@JsonCreator
public CircuitBreakerFallbackMessage(@JsonProperty("message") String message)
© www.soinside.com 2019 - 2024. All rights reserved.