博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据传输格式:json 与 xml 与反射机制

Posted on 2020-12-01 23:42  海绵谷  阅读(222)  评论(0编辑  收藏  举报
  • 一、数据格式
    1.JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,主要用于restful接口返回数据。---
    2.xml 主要用于一些老项目,用xml报文提交数据,返回数据;但是通常拿到数据还是会转成json数据传给前端。
    3.json的解析工具fastjson,gson,net.sf.json(用),jackSon;xml的解析工具 dom4j(实际用)、xpath(mybaties底层解析mapper.xml用的);
  • 二、反射机制
/**
 * @author ngLee
 * @version 1.0
 * @Desc 反射 API  实例
 * @date 2020/12/3 20:39
 */

public class ReflectApp {
    static String packName = "com.example.ngreflect.dto.UserDto";
    public void spiltLine(){
        System.out.println("=======================华丽分割线=====================================");
    }
    /**
     * @desc 获取一个对象,class.forName();
     * @author ngLee
     * @date 2020/12/3 20:45
     */
    @Test
    public  void getNewObject(){
        try {
            Class clazz = Class.forName(packName);
            //newInstance()使用的是无参构造,所以如果只添加了有参构造,而没有无参构造就会报错
            UserDto userDto = (UserDto) clazz.newInstance();
            userDto.setId("600652");
            System.out.println(userDto.getId());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc 获取到对象字段Field
     * @author ngLee
     * @date 2020/12/3 21:18
     */
    @Test
    public void getClazzFileds(){
        try {
            Class clazz = Class.forName(packName);
            //获取某个类的自身的所有字段
            Field[] fields = clazz.getDeclaredFields();
            Arrays.stream(fields).forEach(x-> System.out.println(x.getName()+"--"+x.getType()));
            spiltLine();
            //获取某个类的所有的public字段,其中是包括父类的public字段的
            Field[] arrs = clazz.getFields();
            Arrays.stream(arrs).forEach(field -> System.out.println(field.getName()+"--"+field.getType()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc 获取对象的方法 Method
     * @author ngLee
     * @date 2020/12/3 21:35
     */
    @Test
    public void getClazzMethods(){
        try {
            Class clazz = Class.forName(packName);
            //获取某个类的自身的所有方法
            Method[] methods = clazz.getDeclaredMethods();
            Arrays.stream(methods).forEach(method -> System.out.println(method.getName()+"---"+method.getReturnType()));
            spiltLine();
            //获取某个类的public所有方法,包括父类
            Method[] arr = clazz.getMethods();
            Arrays.stream(arr).forEach(method -> System.out.println(method.getName()+"---"+method.getReturnType()));
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc 使用有参构造生成实例化对象 construct
     * @author ngLee
     * @date 2020/12/3 21:46
     */
    @Test
    public void youcanConstruct(){
        try {
            Class clazz = Class.forName(packName);
            //所有当前类的构造方法
            Constructor[] constructor = clazz.getConstructors();
            //获取其中的一个构造方法
            Constructor youcan = Arrays.stream(constructor).filter( cons ->cons.getParameterCount() == 4 ).findFirst().get();
            //使用newInstance(..);
            UserDto userDto = (UserDto) youcan.newInstance("1","沪深300","612623",5);
            System.out.println(userDto.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc 使用filed 对象为实例化对象赋值,非set赋值,破坏了封装性
     * UserDto 正常赋值userName,会有--正常set的后缀,而本次案例没有
     * @author ngLee
     * @date 2020/12/3 22:04
     */
    @Test
    public void setFiled(){
        try {
            Class clazz = Class.forName(packName);
            UserDto userDto = (UserDto) clazz.newInstance();
            Field[] fields = clazz.getDeclaredFields();
            //要设置的对象内容
            HashMap mp = getUserMap();
            for (Field field : fields) {
                //设置可访问
                field.setAccessible(true);
                String fieldName = field.getName();
                //获取类型
                if(field.getType().getName().equals("java.lang.String")){
                    //字段.set(对象,值);
                    field.set(userDto,mp.get(fieldName));
                }
                field.setAccessible(false);
            }
            System.out.println(userDto.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc  通过属性描述器设值(PropertyDescriptor)
     * @author ngLee
     * @date 2020/12/3 22:41
     */
    @Test
    public void setterMethod(){
        try {
            UserDto userDto = new UserDto();
            //先获取所有字段
            Field[] fields = userDto.getClass().getDeclaredFields();
            //要设置的对象内容
            HashMap<String,String> map = getUserMap();
            for (Field field : fields) {
                String fdName = field.getName();
                //获取属性描述器,
                PropertyDescriptor descriptor = new PropertyDescriptor(fdName,userDto.getClass());
                //获取setter方法
                Method method = descriptor.getWriteMethod();
                //调用setter方法,需要判断参数类型,不然会抛出参非法数类型异常
                method.invoke(userDto,getValueByFiled(map.get(fdName),field));
            }
            System.out.println(userDto.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * @desc 测试用的数据
     * @author ngLee
     * @date 2020/12/3 23:02
     */
    private HashMap<String,String> getUserMap(){
        HashMap mp = new HashMap();
        mp.put("id","2");
        mp.put("userName","顺周期");
        mp.put("tel","161715");
        mp.put("birth","1997-03-12");
        mp.put("everName","王伟,王强");
        return mp;
    }
    /**
     * @desc 字段的类型判断
     * @author ngLee
     * @date 2020/12/3 23:03
     */
    private Object getValueByFiled(String value,Field field){
        Class tyClazz = field.getType();
        //基本类型
        if(field.getType().isPrimitive()){
            if(tyClazz == int.class || tyClazz == Integer.class){
                if(Strings.isNullOrEmpty(value)){
                    return 0;
                }
                return Integer.parseInt(value);
            }
        }
        //引用类型
        if(tyClazz != null && !Strings.isNullOrEmpty(value)){
            
            if(tyClazz.isAssignableFrom(String[].class)){
                //字符串数组
                return value.split(",");
            }else if(tyClazz.isAssignableFrom(String.class)){
                //字符串
                return value;
            }else if(tyClazz.isAssignableFrom(Integer.class)){
                //Interger
                return Integer.parseInt(value);
            }else if(tyClazz.isAssignableFrom(LocalDate.class)){
                //java8日期
                return convertStringToDate("yyyy-MM-dd",value);
            }
            
        }
        return null;
    }
    /**
     * @desc 日期
     * @author ngLee
     * @date 2020/12/3 23:43
     */
    public  LocalDate convertStringToDate(String fmt,String dateStr){
        if (Strings.isNullOrEmpty(fmt) || Strings.isNullOrEmpty(dateStr)) {
            return null;
        } else {
            DateTimeFormatter sdf = DateTimeFormatter.ofPattern(fmt, Locale.CHINA);
            try {
                return LocalDate.parse(dateStr,sdf);
            } catch (DateTimeParseException var4) {
                System.out.println("ParseException");
                return null;
            }
        }
    }
}