我有一个JSON,我解析为Result对象列表。该对象包含5个字符串字段,称为photo1,photo2等。 (基于json)是否可以直接将它们读入List字段?
JSON喜欢:
{
"ErrorMessage": null,
"Result": [{
"id": "462290",
"name_English": "name in english",
"name_Local": "külföldiül a név",
"zipcode": "5463",
"photo1": "dfglkj.com/blabla",
"photo2": "dfglkj.com/blabla",
"photo3": "dfglkj.com/blabla",
"photo4": "dfglkj.com/blabla",
"photo5": "dfglkj.com/blabla"
}]
}
和我的对象:
static final class ApiResponse
{
public String ErrorMessage;
public List<Result> Result = new ArrayList<Result>();
}
static final class Result
{
public String id;
public String name_English;
public String name_Local;
public List<String> photos;
public String zipcode;
}
我有一个ObjectMapper:
private static ObjectMapper newObjectMapper()
{
final ObjectMapper om =
new ObjectMapper() //
.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false) //
.configure(JsonParser.Feature.CANONICALIZE_FIELD_NAMES, true);
om.registerSubtypes(ApiResponse.class);
return om;
}
在解析器中:
final ApiResponse ret = OM.readValue(inputStream, ApiResponse.class);
答案 0 :(得分:2)
根据加埃塔诺的回答,我写了一个更通用的解决方案(任意数量的照片,任意数量的其他领域
import java.util.HashSet;
public class DoublePoint {
private double x,y;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DoublePoint other = (DoublePoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public DoublePoint(double x, double y) {
super();
this.x = x;
this.y = y;
}
public static void main(String[] args) {
HashSet<DoublePoint> set = new HashSet<>();
set.add(new DoublePoint(1.5, 2.5));
System.out.println(set.contains(new DoublePoint(1.5, 2.5)));//return true
}
}
答案 1 :(得分:1)
我发现的最佳解决方案是为 ObjectMapper 定义自定义反序列化器。
您可以告诉 JACKSON 将自定义反序列化程序与ApiResponse类上“Result”对象列表的特定注释一起使用:
public class ApiResponse {
private String errorMessage;
@JsonDeserialize(using = CustomDeserializer.class)
private List<Result> result = new ArrayList<Result>();
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String arg) {
errorMessage = arg;
}
public List<Result> getResult() {
if(result==null)
{
result = new ArrayList<Result>();
}
return result;
}
public void setResult(List<Result> arg) {
result = arg;
}
}
public class Result {
private String id;
private String name_English;
private String name_Local;
private List<String> photos;
private String zipcode;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName_English() {
return name_English;
}
public void setName_English(String name_English) {
this.name_English = name_English;
}
public String getName_Local() {
return name_Local;
}
public void setName_Local(String name_Local) {
this.name_Local = name_Local;
}
public List<String> getPhotos() {
if(photos == null)
{
photos = new ArrayList<String>();
}
return photos;
}
public void setPhotos(List<String> photos) {
this.photos = photos;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
}
请注意java命名方案:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html
自定义反序列化器将如下所示:
public class CustomDeserializer extends StdDeserializer<List<Result>> {
private static final long serialVersionUID = -3483096770025118080L;
public CustomDeserializer() {
this(null);
}
public CustomDeserializer(Class<?> vc) {
super(vc);
}
@Override
public List<Result> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
List<Result> listResult = new ArrayList<Result>();
for (JsonNode interNode : node) {
Result result = new Result();
if (interNode.get("id") != null) {
result.setId(interNode.get("id").asText());
}
if (interNode.get("name_English") != null) {
result.setName_English(interNode.get("name_English").asText());
}
if (interNode.get("name_Local")!= null) {
result.setName_Local(interNode.get("name_Local").asText());
}
if (interNode.get("zipcode") !=null ) {
result.setZipcode(interNode.get("zipcode").asText());
}
// photo array
if (interNode.get("photo1") != null) {
result.getPhotos().add(interNode.get("photo1").asText());
}
if (interNode.get("photo2") != null) {
result.getPhotos().add(interNode.get("photo2").asText());
}
if (interNode.get("photo3") != null) {
result.getPhotos().add(interNode.get("photo3").asText());
}
if (interNode.get("photo4") != null) {
result.getPhotos().add(interNode.get("photo4").asText());
}
if (interNode.get("photo5") != null) {
result.getPhotos().add(interNode.get("photo5").asText());
}
listResult.add(result);
}
return listResult;
}
答案 2 :(得分:1)
如果您可以更改POJO代码,那么最简单的选择就是使用@JsonAnySetter
和@JsonAnyGetter
并在那里编写自定义代码。(如@Oleg建议的那样)但不要忘记到@JsonIgnore
List<String> photos
。
@Data // lombok.Data; for getters and setters
public static final class Result {
public String id;
public String name_English;
public String name_Local;
@JsonIgnore
public List<String> photos = new ArrayList<>();
public String zipcode;
@JsonAnySetter
public void setOther(String key, String value){
photos.add(value);
}
@JsonAnyGetter
public Map<String,String> getOther(){
Map<String,String> map = new HashMap<>();
for (int i = 0;i<photos.size();i++)
map.put("photo" + i + 1, photos.get(i));
return map;
}
}
但如果您无法更改POJO代码,则必须编写自定义序列化程序和反序列化程序