我在尝试反序列化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
...
}
正如错误所说,缺少协议,如果用户没有设置协议,如何在反序列化之前插入协议?
答案 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;
}
}
}