UnsupportedMediaTypeException: 内容类型 'application/octet-stream' 不支持 bodyType=java.util.Map<java.lang.String, java.lang.String>。

7
在运行控制器的JUnit测试时,我遇到了以下错误。我已经将内容类型设置为Json,但错误仍然相同。有什么建议可能是问题的原因吗?
错误信息是:
java.lang.AssertionError: expectation "expectNext({response=employee saved Successfully})" failed (expected: onNext({response=employee saved Successfully}); actual: onError(org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported for bodyType=java.util.Map<java.lang.String, java.lang.String>))

控制器是什么?

@Slf4j
@Controller
@RequiredArgsConstructor
public class EmployeeController {

    private final EmployeeService employeeService;
    
    @PostMapping(path ="/employees",produces =  APPLICATION_JSON_VALUE)
    public @ResponseBody Mono<Map<String, String>> saveEmployees(@RequestBody List<EmployeeDto> employeeDtos) {
        log.info("Received request to save employees [{}]", employeeDtos);
        return employeeService.saveEmployee(employeeDtos);
    }
}

以下是服务类:

@Service
@Slf4j
@RequiredArgsConstructor
public class EmployeeService {

    private final WebClient webClient;

    public Mono<Map<String, String>> saveEmployees(List<EmployeeDto> employeeDtos) {
        return webClient
                .post()
                .uri("/create-employees")
                .contentType(APPLICATION_JSON)
                .bodyValue(employeeDtos)
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {
                })
                .doOnError(e -> log.error("Failed to save employees {}: {}", employeeDtos, e));

Junit 的定义如下:

@Slf4j
@SpringBootTest
class EmployeeServiceTest {

private static final WireMockServer wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private EmployeeService employeeService;

    @Test
    void shouldMakeAPostApiCallToSaveEmployee() throws JsonProcessingException {
        var actualemployeeDtos = "....";
        var randomEmployeeDto = ...;
        wireMockServer.stubFor(post("/create-employees")
                .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON_VALUE))
                .withHeader(ACCEPT, containing(APPLICATION_JSON_VALUE))
                .withRequestBody(equalToJson(actualemployeeDtos))
                .willReturn(aResponse()
                        .withStatus(OK.value())
                        .withBody("{\"response\": \"employee saved Successfully\"}")));

        StepVerifier
                .create(employeeService.saveEmployee(List.of(randomEmployeeDto)))
                .expectNext(singletonMap("response", "employee saved Successfully"))
                .verifyComplete();
    }
}
2个回答

4

在调试过程中,我发现即使是响应头也需要设置content-type,因为BodyExtractors类的readWithMessageReaders()方法会检查content-type。

.withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)

在下面的代码中设置了固定值,修复了测试用例失败的问题。

@Test
    void shouldMakeAPostApiCallToSaveEmployee() throws JsonProcessingException {
        var actualemployeeDtos = "....";
        var randomEmployeeDto = ...;
        wireMockServer.stubFor(post("/create-employees")
                .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON_VALUE))
                .withHeader(ACCEPT, containing(APPLICATION_JSON_VALUE))
                .withRequestBody(equalToJson(actualemployeeDtos))
                .willReturn(aResponse()
                        .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
                        .withStatus(OK.value())
                        .withBody("{\"response\": \"Employees saved Successfully\"}")));

        StepVerifier
                .create(employeeService.saveEmployee(List.of(randomEmployeeDto)))
                .expectNext(singletonMap("response", "Employees saved Successfully"))
                .verifyComplete();
    }

1
在我的情况下,我手动解析了包含JSON对象的一部分来修复问题。
这段代码没有起作用。
@PostMapping(value = "salvaDomanda")
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
Domanda salvaDomanda(@RequestPart("data")  Domanda domanda,
                  @RequestPart(name = "files", required = false) MultipartFile[] files)

这个(This one)
@PostMapping(value = "salvaDomanda")
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
Domanda salvaDomanda(@RequestPart("data") String jsonDomanda,
                     @RequestPart(name = "files", required = false) MultipartFile[] files)
        throws ApplicationException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    Domanda domanda = mapper.readValue(jsonDomanda, Domanda.class);

我的Spring Boot版本是2.6.3,使用Java 17。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接