java json操作

来源:互联网 发布:手机收银软件 编辑:程序博客网 时间:2024/04/29 07:24

 json操作在开发中虽不是难点,但是常用点,java操作json常用的是gson,jackjson,fastjson等等。jackjson采用单例模式,在解析性能方面,jackjson大概是gson性能的10倍左右,因此,相对更适合大数据处理。 今天我写这篇文章不是来探讨他们的性能,我更倾向于实际开发中的应用,把gson和jackjson在原有基础上进行封装,以使开发更简单。

  gson和jackjson与.NET不同,.net里面json字符串反序列化对象不用严格区分大小写, java对json字符串解析有严格的大小写限制,这是我们开发中必须注意的,gson可在字段设置别名@SerializedName("name")来定义字段大小写,同样jackjson也可设置别名@JsonProperty("name")来定义解析属性大小写,对序列化和反序列化同样生效,好了,开始上代码:

Person类:

public class Person {public Person(){};public Person(String n,String e,int a,String c){this.age=a;this.Name=n;this.Email=e;this.classEs=c;}//@JsonProperty("nAme")public String Name;public String Email;//@SerializedName("Age")private int age;private String classEs;//@JsonProperty("nAme")public String getName() {return Name;}public void setName(String name) {this.Name = name;}public String getClassEs() {return classEs;}public void setClassEs(String classEs) {this.classEs = classEs;}public String getEmail() {return Email;}public void setEmail(String email) {this.Email = email;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
gson对对象序列化是以属性名称为准,序列化结果与属性名称大小写一致,序列化结果为:{"Name":"sfdgg","Email":"sfdgs3com","age":45,"classEs":"ddfd"}。

jackjson则不同,他以公共属性方法为准,默认为驼峰命名显示,当属性全部为私有属性时,序列化结果为驼峰命名形式的json字符串,但是,当存在公共属性且公共属性不符合驼峰命名法规格的时候,他将会生成一个多余的字段与公共属性一致,如上面的结果为:{"Name":"sfdgg","Email":"sfdgs3com","age":45,"classEs":"ddfd","name":"sfdgg","email":"sfdgs3com"}。同时存在公共属性大小写结果Name和name,Email和email。

因此,gson对设置别名是在属性上面,jackjson中设置别名如果存在公共属性,则需要在公共属性及其对应的get方法上面同时设置别名,才能保持唯一,如果私有属性,只需要在get方法上面进行设置即可,反序列化则是在set方法进行设置。

好了,把封装方法的结果贴出来供大家方便使用,如有不对或需要改正的地方请大家批评指出,我会及时改正。

  /**     * Gson 对象装json字符串     * @param 输入需要转化的对象     * @return 返回转化结果     */    public static <T> String ObjToJson(T obj) {        if (obj == null) {            return "";        }         Gson gson = new Gson();        String jsonstr = gson.toJson(obj);        return jsonstr;    }

    /**     * jackjson对象转字符串     * @param 输入的对象     * @return 转化结果     */    public static <T> String MapObjToJson(T obj) {        if (obj == null) {            return "";        }        ObjectMapper objectMapper = new ObjectMapper();        String userMapJson = "";        try {            userMapJson = objectMapper.writeValueAsString(obj);        } catch (Exception e) {            return "";        }        return userMapJson;    }

Gson和jackjson对对象序列化时,对象属性未赋值,Gson默认为序列化结果不显示,jackjson字符串则以属性结果为null进行序列化,反序列化则是gson不存在的结果为空值,jackjson则会报错,这一点要特别注意,可通过配置消除这种错误,默认空值,mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 。好多其他配置大家可以看看。

    /**     * Gson字符串转对象     * @param 输入的需要转化的字符串     * @param 需要转化的对象类型     * @return 返回转化结果     * @throws InstantiationException     * @throws Exception     */    public static <T> T JsonToObj(String jsonStr, Class<? extends T> c)            throws InstantiationException, Exception {        // Gson gson = new Gson();        Object obj = gson.fromJson(jsonStr, c);        T t = c.newInstance();        if (c.isInstance(obj)) {            t = (T) obj;        }        return t;    }

    /**     * jackjson字符串转对象     * @param 输入的字符串     * @param 要转化的对象类型     * @return 转化结果     * @throws InstantiationException     * @throws Exception     */    public static <T> T MapJsonToObj(String jsonStr, Class<? extends T> c)            throws InstantiationException, Exception {        ObjectMapper objectMapper = new ObjectMapper();        Object obj = objectMapper.readValue(jsonStr, c);        T t = c.newInstance();        if (c.isInstance(obj)) {            t = (T) obj;        }        return t;    }

有的时候我们想直接通过json字符串读取属性的结果,不想转化为对象再来读取value值,则可以通过一下几个方法。

    /**     * jsckjson根据json字符串取属性结果,第一级目录     * @param 要搜索的字符串     * @param 搜索的属性名称(属性名称区分大小写)     * @return 搜过结果     */    public static String getNodevalue(String jsonstr, String indexName) {        ObjectMapper objectMapper = new ObjectMapper();        try {            JsonNode jnode = objectMapper.readTree(jsonstr);            return jnode.path(indexName).asText();        } catch (JsonProcessingException e) {        } catch (IOException e) {        }        return "";    }

第一级目录则是{"Name":"sfdgg","Email":"sfdgs3com","age":45,"classEs":"ddfd",,"AAA":{"classEs":"ddfd","BBB","sfggf"}},要搜索属性名称BBB是无法找到的,要找到他必须通过下面方法,其实这两个方法该加上一个判断参数写成一个,既然现在是两个那就按照两个看吧:

    /**     * 深度遍历搜索属性结果,搜索字符串所有节点     * @param 要搜过的字符串     * @param 要搜索的属性名称(属性名称区分大小写)     * @return 搜索的结果     */    public static String getdeepNodevalue(String jsonstr, String indexName) {        ObjectMapper objectMapper = new ObjectMapper();        try {            JsonNode jnode = objectMapper.readTree(jsonstr);            return jnode.findValue(indexName).asText();        } catch (JsonProcessingException e) {        } catch (IOException e) {        }        return "";    }

上面两个搜索属性名称都是区分大小写的,最后一个是不区分大小写的,全部遍历,一般用这个不太好:

    /**     * 忽略大小写进行属性搜索     * @param 要搜索的字符串     * @param 搜过的属性名称(属性名称不区分大小写)     * @return 搜索的结果     */    public static String getValueIgnoreCase(String jsonstr, String indexName) {        ObjectMapper objectMapper = new ObjectMapper();        try {            String result = "";            JsonNode jnode = objectMapper.readTree(jsonstr);            Iterator<String> keys = jnode.getFieldNames();            while (keys.hasNext()) {                String fieldName = keys.next();                if (fieldName.equalsIgnoreCase(indexName)) {                    result = jnode.path(fieldName).asText();                    break;                }            }            return result;        } catch (JsonProcessingException e) {        } catch (IOException e) {        }        return "";    }

终于写完了,这次发表的java的,下次发表一个.NET的,我的目的就是为了使开发更简单方便。好了,要睡觉了,明天还要上班,有啥不对的还请大家批评指出,不胜感激,谢谢。








1 0
原创粉丝点击