2015-11-04 48 views
2

我當試圖反序列化URL的Json反序列化到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] 

POJO的這個錯誤:

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

正如錯誤說,缺少協議,如何可以插入反序列化之前的協議,如果它不是由用戶設置?

回答

2

我做了兩個以前的答案的組合:

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); 
     } 
    } 

} 
1

您可以使用自定義解串器 這裏指的custome解串器使用Custom JSON Deserialization with Jackson

+0

看起來不錯,但我必須將所有參數設置(我的課有大約20)不能過濾只有一個更可重用的URL? – xedo

+1

您可以單獨爲反序列化@JsonDeserialize標記URL字段(使用= ) \t \t私人URL url; – Senthil

1

您可以使用自定義解串器(見其他答案)。另一種解決方案 - 不那麼優雅,但是簡單 - 是創建一個URL對象之前內創建bean的一個setter接受字符串值,並做一些準備工作:

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); 
    } 
} 
1

@xedo幫我,但說多了一點安全,你應該抓住一切MalformedURLException S(謝謝!):

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; 
     } 
    } 
}