【问题标题】:Dynamic value based on input value in javajava中基于输入值的动态值
【发布时间】:2021-11-26 10:02:40
【问题描述】:

我有如下一门课。

public class ResponseData {
    private Long entityId;
    private String type;
    private List<String> value;
}

问题陈述:

我正在向调用者发送 JSON 格式的 ResponseData 列表。

类型变量的可能值是“String”、“Integer”、“Date”、“Time”和“Reference”

我的要求是,如果类型的值是“整数”或“参考”,那么值字段的类型应该是整数列表,其余类型字段的值,值字段的类型应该是字符串列表。

【问题讨论】:

  • 你使用的是什么 JSON 解析器 - Jackson?
  • 是杰克逊解析器

标签: java spring-boot java-8 casting typecasting-operator


【解决方案1】:

您可以使用带有自定义反序列化器的参数化类。这是一个工作代码。

  • ResponseData&lt;T&gt;:以列表元素类型为参数的参数化类
  • DS:一个自定义的 Jackson 反序列化器,它了解如何映射到 ResponseData&lt;T&gt;

(为方便起见,我使用了 Lombok 注释。)

请注意,ResponseData&lt;T&gt; 已使用 @JsonDeserialize 进行注释,表示反序列化到类的对象应使用此反序列化器。休息应该是不言自明的。

public class DynamicTypes{
    @NoArgsConstructor @AllArgsConstructor( staticName = "of" )
    @Getter @Setter @ToString
    @JsonDeserialize(using = DS.class)
    public static class ResponseData<T>{
        private Long entityId;
        private String type;
        private List<T> value;
    }
    
    public static void main( String[] args ){
        try{
            ObjectMapper m = new ObjectMapper();
            
            List<String> inputJSONs = Arrays.asList( 
                    "{\"entityId\":1,\"type\":\"String\",\"value\":[\"ONE\",\"TWO\"]}",
                    "{\"entityId\":2,\"type\":\"Integer\",\"value\":[1,2]}" );
            
            for( String json : inputJSONs ) {
                ResponseData<?> rd = m.readValue( json, ResponseData.class );
                System.out.println( rd );
            }
        }
        catch( JsonProcessingException e ){
            e.printStackTrace();
        }
    }
    
    private static class DS extends StdDeserializer<ResponseData<?>>{
        protected DS(){
            super( ResponseData.class );
        }
        
        @Override
        public ResponseData<?> deserialize(JsonParser jp, DeserializationContext ctxt) 
          throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree( jp );
            String type = node.get( "type" ).asText();

            String valueText = node.get( "value" ).toString();
            ObjectMapper om = new ObjectMapper();
            ResponseData<?> rd = new ResponseData<>();
            switch( type ) {
                case "Integer":
                case "Reference":
                    ResponseData<Integer> rdInt = new ResponseData<>();
                    List<Integer> valueInt = om.readValue( valueText, new TypeReference<List<Integer>>(){} );
                    rdInt.setValue( valueInt );
                    rd = rdInt;
                    break;
                default:
                    ResponseData<String> rdStr = new ResponseData<>();
                    List<String> valueStr = om.readValue( valueText, new TypeReference<List<String>>(){} );
                    rdStr.setValue( valueStr );
                    rd = rdStr;
            }
            
            rd.setEntityId( node.get( "entityId" ).asLong() );
            rd.setType( type );
            
            return rd;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 2018-06-26
    • 2021-02-04
    相关资源
    最近更新 更多