Gson解析json

GSON:谷歌的一款开源项目,主要用于解析json数据,有很多很友好的个性化设置

  思想:把json字符串与java对象相关联

  序列化:把java对象转换成json字符串

  反序列化:把json字符串转换成java对象

使用springMVC获取web前端传送过来的数据

  Gson处理简单数据(key对应的value是简单的String类型/或者number

Gson的使用前提:导入jar包     gson-2.2.4.jar

主要的方法:

  Gson fromJson(String jsonStr,Type)  //用于把json字符串转换成type类型的java对象

  String toJson(Object obj)  //把obj对象变成json字符串

例如:

前端传送如下json字符串:
{
  "username":"kylin",
  "password":"123456"
}
//那么controller中就可以有如下的操作(User类的内容就不导入)
@RequestMapping(value = "/LOGIN",method = RequestMethod.POST) public String LOGIN(@RequestBody String jsonStr){ //使用gson来获取数据并且进行操作 Gson gson=new Gson(); //序列化 User user=gson.fromJson(jsonStr,User.class); String username=user.getUsername(); String password=user.getPassword(); System.out.println(username+" "+password); return "welcome"; }

 

Gson处理复杂数据(key对应的value可能是数组/对象)

  处理方式:

    如果是对象的话,那么对应的javabean类,需要设置一个公有的内部类对象,如果是数组的话,那么对应的javabean类中可以把对应的字段设置为list集合/set集合

例如:

前端传送数据如下: 
{
"name":"kylin", "age":20, "major":["English","Chinese","math"], "grade":{ "course":"computer", "score":"100", "level":"good"
} }

对应的Student类:

Student.java
package
com.kylin.JavaBean; import java.util.List; public class Student { private String name; //名字 private int age; //年纪 private List<String> major; //主修课程 private Grade grade; //某科目 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<String> getMajor() { return major; } public void setMajor(List<String> major) { this.major = major; } public Grade getGrade() { return grade; } public void setGrade(Grade grade) { this.grade = grade; }   //注意:内部类应该被设置为public public class Grade { private String course; private String score; private String level; public String getCourse() { return course; } public void setCourse(String course) { this.course = course; } public String getScore() { return score; } public void setScore(String score) { this.score = score; } public String getLevel() { return level; } public void setLevel(String level) { this.level = level; } } }

Controller中请求处理方法:

 @RequestMapping(value = "/Student",method = RequestMethod.POST)
    public String Student_Login(@RequestBody String jsonStr){
        //jsonstr获取数据
        /*
       {
        "name":"kylin",
        "age":20,
        "major":["English","Chinese","math"],
        "grade":{
                "course":"computer",
                "score":"100",
                "level":"good"
         }
    }
        * */
        //因为本地已经有想匹配的javabean对象,所有直接当成简单的数据获取就
        Gson gson=new Gson();
        Student student=gson.fromJson(jsonStr,Student.class);
        //成功获取数组里面的内容
        List<String> major=student.getMajor();
        for (String i:major){
            System.out.println(i);
        }
        //接下来就是解析内部类中的内容
        /*
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  //必须通过Outter对象来创建*/
        //成功获取grade对象
        Student.Grade grade=student.new Grade();
        grade=student.getGrade();
        String gradeCourse=grade.getCourse();
        String gradeLevel=grade.getLevel();
        String gradeScore=grade.getScore();
        System.out.println("内部的东西"+gradeScore+gradeCourse+gradeLevel);


        return "welcome";  //welcome是一个jsp文件,配置了视图解析器的,不需要过多的纠结
    }

以上是从web前端获取json数据----简单数据,复杂数据(含有数组/对象)的处理方式;下面将介绍如何从web后端传送符合规范的json字符串给前端。

后端返回简单数据给前端------过于简单这里就不介绍了,主要介绍后端返回复杂json数据给前端的方法

 

后端返回复杂json字符串给前端

方式:使用javabean/使用map集合

使用javabean方式


@RequestMapping(value = "/DataBackByJavaBean",method = RequestMethod.POST)
@ResponseBody
public String DataBack(@RequestParam String id){
//本来是需要获取前端传过来的id,然后进行数据库查询 然后再返回结果 这里就随便的进行一次获取吧
System.out.println("前端传过来的id:"+id);
//设置需要传送的数据
Student student=new Student();
student.setName("kylin");
student.setAge(11);
List<String> major=new ArrayList<>();
major.add("Chinese");
major.add("Math");
student.setMajor(major);
Student.Grade grade=student.new Grade();
grade.setCourse("XXX");
grade.setScore("111");
grade.setLevel("good");
student.setGrade(grade);

//数据设置完毕 进行gson操作-----变成json字符串
//使用GsonBuilder创建的gson对象会更加的强大,可以有更多的个性化操作
GsonBuilder gsonBuilder=new GsonBuilder();
Gson gson=gsonBuilder.create();
String jsonStr=gson.toJson(student);
System.out.println(jsonStr);
return jsonStr;
}

 

使用map集合方式(优点:对于需要返回的数据可以任意设置,不用局限于只能使用javabean的属性)

 @RequestMapping(value = "/DataBackByMap",method = RequestMethod.POST)
    @ResponseBody
    public String DataBackByMap(@RequestParam String id){
        System.out.println(id);
        //使用map方式来处理
        Map<String,Object>params=new HashMap<>();
        params.put("status","200");
        params.put("name","kylin");
        List<String> major=new LinkedList<>();
        major.add("XXX");
        major.add("YYY");
        params.put("major",major);
        Student student=new Student();
        Student.Grade grade=student.new Grade();
        grade.setLevel("GOOD");
        grade.setScore("1111");
        grade.setCourse("xxxxxxssss");
        params.put("grade",grade);

        //转换成jsonStr字符串
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
            @Override
            public String translateName(Field field) {
                if (field.getName().equals("name")){
                    return "NAME";
                }
                return field.getName();
            }
        });
        Gson gson = gsonBuilder.create();
        gson.toJson()
        String jsonStr=gson.toJson(params);
        System.out.println(params);
        return jsonStr;

    }

 以上主要介绍了如何从web前端获取json数据并且如何从web后端传送数据给web前端(如果对@RequestBody和@ResponseBody不理解的朋友,可以自行百度)

下面主要扩展性的讲解一下Gson的一些其他特性:

1.修改javaBean中的属性在json转换中的名字

  有两种方式,分别是:

            1.@SerializedName 注解的使用(在定义javaBean类的时候,对属性进行注解)

            2.GsonBuilder的 setFieldNamingStrategy 方法 ,FieldNamingStrategy 自定义规则

  比如需要的数据是:

{
    "id":"123",
    "name":"kylin",
    "author":{
        "id":"222",
        "name":"kkkk"
    }
}

   而实际类对应的数据是:

{
    "id":"123",
    "name":"kylin",
    "user":{
        "id":"222",
        "name":"kkkk"
    }
}

方式一:

在对应的javaBean类中;在user属性上添加注解@SerializedName

@SerializedName("author")
private User user;

 例如:

@SerializedName(value = "user_password", alternate = {"userName",
                        "username"})//value是默认字段名称、alternate是备选字段名称
private String userPassword;

缺点:这种方式会使得以后所有涉及到该属性的json在转换的过程中,user都会变成author;而且其权限相对较大,会覆盖其他的对该属性的操作,比如我在另外一个地方使用方式2来

对属性的名字进行修改,但最终还是会被其@SerializedName覆盖

 

方式二:(推荐)

GsonBuilder的 setFieldNamingStrategy 方法 ,FieldNamingStrategy 自定义规则

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingStrategy(new FieldNamingStrategy() {
            @Override
            public String translateName(Field field) {
                if (field.getName().equals("name")){
                    //相当于遍历一遍,如果找到名字为name的就把他变成NAME
                    return "NAME"
                }
                return field.getName();
            }
        });
        Gson gson = gsonBuilder.create();

FieldNamingStrategy中还有很多其他的规则,如果有兴趣可以自己去了解一下~

 

下面贴一些GsonBuilder中比较常见的方法和注解

   //序列化null
    serializeNulls()
    // 设置日期时间格式,另有2个重载方法
    // 在序列化和反序化时均生效
    setDateFormat("yyyy-MM-dd")
    // 禁此序列化内部类
    disableInnerClassSerialization()
    //生成不可执行的Json(多了 )]}' 这4个字符)
    generateNonExecutableJson()
    //禁止转义html标签
    disableHtmlEscaping()
    //格式化输出
    setPrettyPrinting()
    create()

     @Expose(serialize=true,deserialize=false)
     private String name;//序列化是忽略,反序列化时参与。

 

posted @ 2018-06-25 17:28  Shan-KyLin  阅读(7258)  评论(0编辑  收藏  举报