【问题标题】:Json deserialize to URL (intercept)Json 反序列化为 URL(拦截)
【发布时间】:2015-11-04 13:44:52
【问题描述】:

我在尝试反序列化 URL 时遇到此错误

Caused by: java.net.MalformedURLException: no protocol: www.boo.com
    at java.net.URL.<init>(URL.java:586) ~[na:1.8.0_45]
    at java.net.URL.<init>(URL.java:483) ~[na:1.8.0_45]
    at java.net.URL.<init>(URL.java:432) ~[na:1.8.0_45]
    at com.fasterxml.jackson.databind.deser.std.FromStringDeserializer$Std._deserialize(FromStringDeserializer.java:212) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.std.FromStringDeserializer.deserialize(FromStringDeserializer.java:122) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:337) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:131) ~[jackson-databind-2.6.2.jar:2.6.2]
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245) ~[jackson-databind-2.6.2.jar:2.6.2]

波乔:

class foo {
   ...
   URL url
   ...
}

正如错误所说,缺少协议,如果用户没有设置协议,如何在反序列化之前插入协议?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    我综合了之前的两个答案:

    public class Foo {
       ...
       @JsonDeserialize(using = UrlDeseralizer.class)
       private URL url;
       ...
    }
    
    public class UrlDeseralizer extends JsonDeserializer<URL> {
    
        private Pattern urlPrefix = Pattern.compile("^(https?://|ftp://).*");
    
        @Override
        public URL deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            ObjectCodec objectCodec = p.getCodec();
            JsonNode node = objectCodec.readTree(p);
            String stringUrl = node.asText();
            if (!urlPrefix.matcher(stringUrl).matches()) {
                return new URL("http://" + stringUrl);
            } else {
                return new URL(stringUrl);
            }
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用自定义反序列化程序 请参阅此处了解客户反序列化器的使用情况Custom JSON Deserialization with Jackson

      【讨论】:

      • 看起来不错,但我必须设置所有参数吗?(我的班级大约有 20 个)不能只过滤 URL 一个以便更可重用吗?
      • 可以单独标记URL字段进行反序列化@JsonDeserialize( using=) private URL url;
      【解决方案3】:

      您可以使用自定义反序列化器(请参阅其他答案)。另一个解决方案 - 不是那么优雅,但简单 - 是在您的 bean 中创建一个接受字符串值的 setter,并在创建 URL 对象之前在内部做一些准备:

      private Pattern urlPrefix = Pattern.compile("^(https?://|ftp://).*"); //etc.
      //...
      public void setUrl(String url) {
          if (url != null && urlPrefix.matcher(url).matches()) {
              this.url = new URL(url);
          } else {
              this.url = new URL("http://" + url);
          }
      }
      

      【讨论】:

        【解决方案4】:

        @xedo 帮助了我(谢谢!),但为了更安全,你应该抓住所有 MalformedURLExceptions:

        public class Foo {
           ...
           @JsonDeserialize(using = UrlDeseralizer.class)
           private URL url;
           ...
        }
        
        public class UrlDeseralizer extends JsonDeserializer<URL> {
        
            private Pattern urlPrefix = Pattern.compile("^(https?://|ftp://).*");
        
            @Override
            public URL deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
                ObjectCodec objectCodec = p.getCodec();
                JsonNode node = objectCodec.readTree(p);
                String stringUrl = node.asText();
                try {
                    return new URL(stringUrl);
                } catch (MalformedURLException e) {
                    // log.debug("Malformed URL: ‘" + stringUrl + "’", e);
                    return null;
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-03-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多