说我有以下对象:
public class ComplexJacksonObject extends BaseJsonObject { public int Start; public int Count; public Person MyPerson; public class Person extends BaseJsonObject { public String Firstname; public String Lastname; public Address Where; } public class Address extends BaseJsonObject { public String Street; public int Number; } }
显然,当我向杰克逊请求JSON时,我得到如下信息:
public String toJson(ComplexJacksonObject obj) { try { return generateMapper().writeValueAsString(obj); } catch (JsonProcessingException e) { e.printStackTrace(); return null; } } // returned: {"MyPerson":{"Firstname":"First","Lastname":"Last","Where":{"Street":"Street","Number":15}},"Count":1,"Start":2}
但是,我对QueryString的需求是将顶级属性对转换为Key = Value&格式,因此类似:
MyPerson={"Firstname":"First","Lastname":"Last","Where":{"Street":"Street","Number":15}}&Count=1&Start=2
当然还有MyPerson = [This_Part_Needs_To_Be_Url_Encoded]。
杰克逊中有任何通用方法会自动为我执行此操作吗?还是我会被迫提出自己的想法?一些字符串替换正则表达式?有任何想法吗?
好,
这是持有人对象:
public class ComplexJacksonObject extends BaseJsonObject { public int Start; public int Count; public Person MyPerson; public List<String> Strings; public class Person extends BaseJsonObject { public String Firstname; public String Lastname; public Address Where; } public class Address extends BaseJsonObject { public String Street; public int Number; } }
这是我如何初始化它:
ComplexJacksonObject cjo = new ComplexJacksonObject(); cjo.Count = 1; cjo.Start = 2; cjo.Strings = new ArrayList<String>(); cjo.Strings.add("One"); cjo.Strings.add("Two"); cjo.MyPerson = cjo.new Person(); cjo.MyPerson.Firstname = "Fi\",=[]{}rst"; cjo.MyPerson.Lastname = "Last"; cjo.MyPerson.Where = cjo.new Address(); cjo.MyPerson.Where.Street = "Street"; cjo.MyPerson.Where.Number = 15; String result = cjo.toQueryString(); // Strings=%5B%22One%22%2C%22Two%22%5D&MyPerson=%7BFirstname%3A"Fi%5C%5C%22%2C%3D%5B%5D%7B%7Drst"%2CLastname%3A%22Last%22%2CWhere%3A%7BStreet%3A%22Street%22%2CNumber%3A15%7D%7D&Start=2&Count=1
最后,使这种情况发生的方法:
public String toQueryString() { StringBuilder sb = new StringBuilder(); for (Field field : this.getClass().getDeclaredFields()) { if (sb.length() > 0) { sb.append("&"); } Class cls = field.getType().getSuperclass(); // serializing my complex objects - they all inherit from BaseJsonObject class if (cls != null && cls.equals(BaseJsonObject.class)) { BaseJsonObject bjo = (BaseJsonObject) getFieldValue(field); String str = toJson(bjo, true); sb.append(field.getName()).append("=").append(Uri.encode(str)); } // serializing lists, they are all List<T> else if (field.getType().equals(List.class)) { List bjo = (List) getFieldValue(field); String val = toJson(bjo, false); sb.append(field.getName()).append("=").append(Uri.encode(val)); } // serializing simple fields else { Object bjo = getFieldValue(field); String val = toJson(bjo, false).replaceAll("^\"|\"$", ""); sb.append(field.getName()).append("=").append(Uri.encode(val)); } } return sb.toString(); } private Object getFieldValue(Field field) { try { return field.get(this); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } private static ObjectMapper generateMapper() { ObjectMapper om = new ObjectMapper(); // om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); om.setDateFormat(new JacksonSimpleDateFormat()); return om; } public String toJson() { try { return generateMapper().writeValueAsString(this); } catch (JsonProcessingException e) { e.printStackTrace(); return null; } } public String toJson(Object o, boolean noQuoteProperties) { try { ObjectMapper om = generateMapper(); if (noQuoteProperties) { om.configure(com.fasterxml.jackson.core.JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); om.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); } return om.writeValueAsString(o); } catch (JsonProcessingException e) { e.printStackTrace(); return null; } }