Json反序列化为URL(拦截)

时间:2015-11-04 13:44:52

标签: java json jackson

我在尝试反序列化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
   ...
}

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

4 个答案:

答案 0 :(得分: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 :(得分:1)

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

答案 2 :(得分:1)

您可以使用自定义反序列化器(请参阅其他答案)。另一个解决方案 - 不是那么优雅,而是直截了当 - 是在bean中创建一个setter,它接受String值并在创建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);
    }
}

答案 3 :(得分:0)

@xedo帮助了我(谢谢!),但为了更加安全一点,你应该抓住所有MalformedURLException

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