在 webflutest Springboot 3.2 中导入自定义 jackson 序列化器(模块)

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

我在 webflux 和 SpringBoot 3.2 中有一个应用程序

我有自定义杰克逊模块和序列化器,不幸的是,当我尝试执行测试时没有找到序列化器

自定义模块

package ae.company.banking.configuration.converters;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new MoneyModule());
        objectMapper.registerModule(new JavaTimeModule());
        return objectMapper;
    }
}

反序列化器

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import org.javamoney.moneta.Money;
import org.springframework.stereotype.Component;

@Component
public class MoneyDeserializer extends JsonDeserializer<Money> {

    @Override
    public Money deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonNode node = p.getCodec().readTree(p);
        double amount = node.get("amount").asDouble();
        String currencyCode = node.get("currency").asText();

        CurrencyUnit currency = Monetary.getCurrency(currencyCode);
        return Money.of(amount, currency);
    }
}

模块

package ae.company.banking.configuration.converters;

import com.fasterxml.jackson.databind.module.SimpleModule;
import org.javamoney.moneta.Money;

public class MoneyModule extends SimpleModule {
    public MoneyModule() {
        addSerializer( Money.class, new MoneySerializer());
        addDeserializer( Money.class, new MoneyDeserializer());
    }
}

我的测试

@WebFluxTest( controllers = UserController.class )
@Import( { JacksonConfig.class, FindUserById.class, FindAllUsers.class, AddUserAccount.class, AddUserBeneficiary.class, WebFluxControllerSecurityTestConfig.class } )
class UserControllerTest {
    @Autowired
    UserController controller;

    @MockBean
    UserRepository repository;

    @MockBean
    JwtTokenFilter filter;

    @Test
    @WithMockUser
    void testGetgetUserById() {
        CurrencyUnit eur = Monetary.getCurrency( "EUR" );

        var user = User.builder()
                .id( "4787889456456456456frfrfrf582" )
                .identityId( "iyioyuy9y98y9y9" )
                .firstName( "firstname2" )
                .lastName( "lastname2" )
                .role( Role.USER )
      .balance( Money.of( 200, eur ) )
                .username( "[email protected]" ).build();
        when( repository.findById( "4787889456456456456frfrfrf87" ) )
                .thenReturn( Mono.just( user ) );

        var testClient = WebTestClient.bindToController( controller ).webFilter( new SecurityContextServerWebExchangeWebFilter() )
                .apply( springSecurity() )
                .build();
        testClient
                .get().uri( "/api/v1/users/4787889456456456456frfrfrf87" )
                .exchange()
                .expectStatus().isOk()
                .expectBodyList( UserDto.class )
                .hasSize( 1 );
        Mockito.verify( repository, times( 1 ) ).findById( "4787889456456456456frfrfrf87" );
    }

还有错误

原因:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造

javax.money.MonetaryAmount
的实例(不存在像默认构造函数那样的创建者):抽象类型需要映射到具体类型,具有自定义反序列化器,或者包含附加类型信息

spring-boot spring-webflux jackson-databind jackson-modules
1个回答
0
投票

为了让它发挥作用,我做了这个

var testClient = WebTestClient

        .bindToController( controller ).webFilter( new SecurityContextServerWebExchangeWebFilter() )
        .apply( springSecurity() )
        .build();
testClient
        .mutate()
        .codecs( clientCodecConfigurer ->
                clientCodecConfigurer.defaultCodecs()
                        .jackson2JsonDecoder( new Jackson2JsonDecoder( mapper ) ) ).build()
        .post().uri( "/api/v1/users/4787889456456456456frfrfrf87/SAVING" )
        .exchange()
        .expectStatus().isCreated()
        .expectBodyList( UserDto.class )
        .hasSize( 1 );
Mockito.verify( repository, times( 1 ) ).save( user );

并注入映射器

@Autowired ObjectMapper 映射器;

我会尝试@M的解决方案。迪努姆

© www.soinside.com 2019 - 2024. All rights reserved.