2015-11-04 70 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; 
     } 
    } 
}