暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

spark项目实战(十~~十二)

逗先生大数据 2020-11-17
326
点击上方蓝字  关注我们

Spark项目之电商用户行为分析大数据平台之(十)IDEA项目搭建及工具类介绍

目录

一、创建Maven项目

二、常用工具类

2.1 配置管理组建

2.2 常量的接口

2.3 时间日期工具类

2.4 数字格式化工具类

2.5 参数工具类

2.6 字符串工具类

2.7 校验工具类



正文



一、创建Maven项目

创建项目,名称为LogAnalysis



二、常用工具类

2.1 配置管理组建

ConfigurationManager.java

 import java.io.InputStream;

 import java.util.Properties;


 /**

  * 配置管理组件

  * 

  * 1、配置管理组件可以复杂,也可以很简单,对于简单的配置管理组件来说,只要开发一个类,可以在第一次访问它的

  *         时候,就从对应的properties文件中,读取配置项,并提供外界获取某个配置key对应的value的方法

  * 2、如果是特别复杂的配置管理组件,那么可能需要使用一些软件设计中的设计模式,比如单例模式、解释器模式

  *         可能需要管理多个不同的properties,甚至是xml类型的配置文件

  * 3、我们这里的话,就是开发一个简单的配置管理组件,就可以了

  *

  */

 public class ConfigurationManager {

     

     // Properties对象使用private来修饰,就代表了其是类私有的

     // 那么外界的代码,就不能直接通过ConfigurationManager.prop这种方式获取到Properties对象

     // 之所以这么做,是为了避免外界的代码不小心错误的更新了Properties中某个key对应的value

     // 从而导致整个程序的状态错误,乃至崩溃

     private static Properties prop = new Properties();


     static {

         try {

             InputStream in = ConfigurationManager.class

                     .getClassLoader().getResourceAsStream("conf.properties");

             prop.load(in);

         } catch (Exception e) {

             e.printStackTrace();  

         }

     }

     

     /**

      * 获取指定key对应的value

      * 

      * @param key 

      * @return value

      */

     public static String getProperty(String key) {


         return prop.getProperty(key);

     }

     

     /**

      * 获取整数类型的配置项

      * @param key

      * @return value

      */

     public static Integer getInteger(String key) {

         String value = getProperty(key);

         try {

             return Integer.valueOf(value);

         } catch (Exception e) {

             e.printStackTrace();

         }

         return 0;

     }

     

     /**

      * 获取布尔类型的配置项

      * @param key

      * @return value

      */

     public static Boolean getBoolean(String key) {

         String value = getProperty(key);

         try {

             return Boolean.valueOf(value);

         } catch (Exception e) {

             e.printStackTrace();

         }

         return false;

     }

     

     /**

      * 获取Long类型的配置项

      * @param key

      * @return

      */

     public static Long getLong(String key) {

         String value = getProperty(key);

         try {

             return Long.valueOf(value);

         } catch (Exception e) {

             e.printStackTrace();

         }

         return 0L;

     }


2.2 常量的接口

Constants.java




 /**

  * 常量接口

  * @author Administrator

  *

  */

 public interface Constants {


     /**

      * 项目配置相关的常量

      */

     String JDBC_DRIVER = "jdbc.driver";

     String JDBC_DATASOURCE_SIZE = "jdbc.datasource.size";

     String JDBC_URL = "jdbc.url";

     String JDBC_USER = "jdbc.user";

     String JDBC_PASSWORD = "jdbc.password";

     String JDBC_URL_PROD = "jdbc.url.prod";

     String JDBC_USER_PROD = "jdbc.user.prod";

     String JDBC_PASSWORD_PROD = "jdbc.password.prod";

     String SPARK_LOCAL = "spark.local";

     String SPARK_LOCAL_TASKID_SESSION = "spark.local.taskid.session";

     String SPARK_LOCAL_TASKID_PAGE = "spark.local.taskid.page";

     String SPARK_LOCAL_TASKID_PRODUCT = "spark.local.taskid.product";

     String KAFKA_METADATA_BROKER_LIST = "kafka.metadata.broker.list";

     String KAFKA_TOPICS = "kafka.topics";

     

     /**

      * Spark作业相关的常量

      */

     String SPARK_APP_NAME_SESSION = "UserVisitSessionAnalyzeSpark";

     String SPARK_APP_NAME_PAGE = "PageOneStepConvertRateSpark";

     String FIELD_SESSION_ID = "sessionid";

     String FIELD_SEARCH_KEYWORDS = "searchKeywords";

     String FIELD_CLICK_CATEGORY_IDS = "clickCategoryIds";

     String FIELD_AGE = "age";

     String FIELD_PROFESSIONAL = "professional";

     String FIELD_CITY = "city";

     String FIELD_SEX = "sex";

     String FIELD_VISIT_LENGTH = "visitLength";

     String FIELD_STEP_LENGTH = "stepLength";

     String FIELD_START_TIME = "startTime";

     String FIELD_CLICK_COUNT = "clickCount";

     String FIELD_ORDER_COUNT = "orderCount";

     String FIELD_PAY_COUNT = "payCount";

     String FIELD_CATEGORY_ID = "categoryid";

     

     String SESSION_COUNT = "session_count";

     

     String TIME_PERIOD_1s_3s = "1s_3s";

     String TIME_PERIOD_4s_6s = "4s_6s";

     String TIME_PERIOD_7s_9s = "7s_9s";

     String TIME_PERIOD_10s_30s = "10s_30s";

     String TIME_PERIOD_30s_60s = "30s_60s";

     String TIME_PERIOD_1m_3m = "1m_3m";

     String TIME_PERIOD_3m_10m = "3m_10m";

     String TIME_PERIOD_10m_30m = "10m_30m";

     String TIME_PERIOD_30m = "30m";

     

     String STEP_PERIOD_1_3 = "1_3";

     String STEP_PERIOD_4_6 = "4_6";

     String STEP_PERIOD_7_9 = "7_9";

     String STEP_PERIOD_10_30 = "10_30";

     String STEP_PERIOD_30_60 = "30_60";

     String STEP_PERIOD_60 = "60";

     

     /**

      * 任务相关的常量

      */

     String PARAM_START_DATE = "startDate";

     String PARAM_END_DATE = "endDate";

     String PARAM_START_AGE = "startAge";

     String PARAM_END_AGE = "endAge";

     String PARAM_PROFESSIONALS = "professionals";

     String PARAM_CITIES = "cities";

     String PARAM_SEX = "sex";

     String PARAM_KEYWORDS = "keywords";

     String PARAM_CATEGORY_IDS = "categoryIds";

     String PARAM_TARGET_PAGE_FLOW = "targetPageFlow";

     

 }


2.3 时间日期工具类

DateUtils.java




  import java.text.ParseException;

  import java.text.SimpleDateFormat;

  import java.util.Calendar;

  import java.util.Date;

  

  **

   * 时间日期工具类

   * */

  public class DateUtils {

  

      public static final SimpleDateFormat TIME_FORMAT =

              new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

      public static final SimpleDateFormat DATE_FORMAT =

              new SimpleDateFormat("yyyy-MM-dd");

      public static final SimpleDateFormat DATEKEY_FORMAT =

              new SimpleDateFormat("yyyyMMdd");

  

      **

       * 判断第一个时间是否在第二个时间之前

       * */

      public static boolean before(String firstTime,String secondTime){

          try {

              Date first = TIME_FORMAT.parse(firstTime);

              Date second = TIME_FORMAT.parse(secondTime);

  

              if(first.before(second)){

                  return true;

              }

          } catch (ParseException e) {

              e.printStackTrace();

          }

          return false;

      }

  

      **

       * 判断第一个时间是否在第二个时间之后

       * */

      public static boolean after(String firstTime,String secondTime){

          try {

              Date first = TIME_FORMAT.parse(firstTime);

              Date second = TIME_FORMAT.parse(secondTime);

  

              if(first.after(second)){

                  return true;

              }

          }catch (ParseException e){

              e.printStackTrace();

          }

          return false;

      }

  

      **

       * 计算2个时间的差值(单位为秒)

       * */

      public static int minus(String firstTime,String secondTime){

          try {

              Date first = TIME_FORMAT.parse(firstTime);

              Date second = TIME_FORMAT.parse(secondTime);

              long millisecond = first.getTime() - second.getTime();

              return Integer.valueOf(String.valueOf(millisecond/1000));

          }catch (ParseException e){

              e.printStackTrace();

          }

          return 0;

      }

  

      **

       * 获取年月日和小时

       * */

      public static String getDateHour(String datetime){

          String date = datetime.split(" ")[0];

          String hourMinuteSecond = datetime.split(" ")[1];

          String hour = hourMinuteSecond.split(":")[0];

          return date+"_"+hour;

      }

  

      **

       * 获取当天的日期

       * */

      public static String getTodayDate(){

          return DATE_FORMAT.format(new Date());

      }

  

      **

       * 获取昨天的日期

       * */

      public static String getYesterdayDate(){

          Calendar calendar = Calendar.getInstance();

          calendar.setTime(new Date());

          calendar.add(Calendar.DAY_OF_YEAR,-1);

  

          Date time = calendar.getTime();

          return DATE_FORMAT.format(time);

      }

  

      **

       * 格式化日期(yyyy-MM-dd)

       */

      public static String formatDate(Date date) {

1         return DATE_FORMAT.format(date);

1     }

1     /**

1      * 格式化时间(yyyy-MM-dd HH:mm:ss)

1      */

1     public static String formatTime(Date date) {

1         return TIME_FORMAT.format(date);

1     }

1     /**

1      * 解析时间字符串

1      */

1     public static Date parseTime(String time) {

1         try {

1             return TIME_FORMAT.parse(time);

1         } catch (ParseException e) {

1             e.printStackTrace();

1         }

1         return null;

1     }

1     /**

1      * 格式化日期key

1      */

1     public static String formatDateKey(Date date) {

1         return DATEKEY_FORMAT.format(date);

1     }

1     /**

1      * 格式化日期key

1      */

1     public static Date parseDateKey(String datekey) {

1         try {

1             return DATEKEY_FORMAT.parse(datekey);

1         } catch (ParseException e) {

1             e.printStackTrace();

1         }

1         return null;

1     }

1     /**

1      * 格式化时间,保留到分钟级别

1      */

1     public static String formatTimeMinute(Date date) {

1         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");

1         return sdf.format(date);

1     }

1 }


2.4 数字格式化工具类

NumberUtils.java




 import java.math.BigDecimal;


 /**

  * 数字格式化工具类

  * @author Administrator

  *

  */

 public class NumberUtils {


     /**

      * 格式化小数

      * @param num 字符串

      * @param scale 四舍五入的位数

      * @return 格式化小数

      */

     public static double formatDouble(double num, int scale) {

         BigDecimal bd = new BigDecimal(num);  

         return bd.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();

     }

     

 }




2.5 参数工具类

ParamUtils.java




 import com.alibaba.fastjson.JSONArray;

 import com.alibaba.fastjson.JSONObject;

 import com.bw.conf.ConfigurationManager;

 import com.bw.constant.Constants;



 /**

  * 参数工具类

  * @author Administrator

  *

  */

 public class ParamUtils {


     /**

      * 从命令行参数中提取任务id

      * @param args 命令行参数

      * @return 任务id

      */

     public static Long getTaskIdFromArgs(String[] args, String taskType) {

         boolean local = ConfigurationManager.getBoolean(Constants.SPARK_LOCAL);

         

         if(local) {

             return ConfigurationManager.getLong(taskType);

         } else {

             try {

                 if(args != null && args.length > 0) {

                     return Long.valueOf(args[0]);

                 }

             } catch (Exception e) {

                 e.printStackTrace();

             }

         }

         

         return null;

     }

     

     /**

      * 从JSON对象中提取参数

      * @param jsonObject JSON对象

      * @return 参数

      */

     public static String getParam(JSONObject jsonObject, String field) {

         JSONArray jsonArray = jsonObject.getJSONArray(field);

         if(jsonArray != null && jsonArray.size() > 0) {

             return jsonArray.getString(0);

         }

         return null;

     }

     

 }




2.6 字符串工具类

StringUtils.java




 /**

  * 字符串工具类

  * @author Administrator

  *

  */

 public class StringUtils {


     /**

      * 判断字符串是否为空

      * @param str 字符串

      * @return 是否为空

      */

     public static boolean isEmpty(String str) {

         return str == null || "".equals(str);

     }

     

     /**

      * 判断字符串是否不为空

      * @param str 字符串

      * @return 是否不为空

      */

     public static boolean isNotEmpty(String str) {

         return str != null && !"".equals(str);

     }

     

     /**

      * 截断字符串两侧的逗号

      * @param str 字符串

      * @return 字符串

      */

     public static String trimComma(String str) {

         if(str.startsWith(",")) {

             str = str.substring(1);

         }

         if(str.endsWith(",")) {

             str = str.substring(0, str.length() - 1);

         }

         return str;

     }

     

     /**

      * 补全两位数字

      * @param str

      * @return

      */

     public static String fulfuill(String str) {

         if(str.length() == 2) {

             return str;

         } else {

             return "0" + str;

         }

     }

     

     /**

      * 从拼接的字符串中提取字段

      * @param str 字符串

      * @param delimiter 分隔符 

      * @param field 字段

      * @return 字段值

      */

     public static String getFieldFromConcatString(String str, 

             String delimiter, String field) {

         try {

             String[] fields = str.split(delimiter);

             for(String concatField : fields) {

                 // searchKeywords=|clickCategoryIds=1,2,3

                 if(concatField.split("=").length == 2) {

                     String fieldName = concatField.split("=")[0];

                     String fieldValue = concatField.split("=")[1];

                     if(fieldName.equals(field)) {

                         return fieldValue;

                     }

                 }

             }

         } catch (Exception e) {

             e.printStackTrace();

         }

         return null;

     }

     

     /**

      * 从拼接的字符串中给字段设置值

      * @param str 字符串

      * @param delimiter 分隔符 

      * @param field 字段名

      * @param newFieldValue 新的field值

      * @return 字段值

      */

     public static String setFieldInConcatString(String str, 

             String delimiter, String field, String newFieldValue) {

         String[] fields = str.split(delimiter);

         

         for(int i = 0; i < fields.length; i++) {

             String fieldName = fields[i].split("=")[0];

             if(fieldName.equals(field)) {

                 String concatField = fieldName + "=" + newFieldValue;

                 fields[i] = concatField;

                 break;

             }

         }

         

         StringBuffer buffer = new StringBuffer("");

         for(int i = 0; i < fields.length; i++) {

             buffer.append(fields[i]);

             if(i < fields.length - 1) {

                 buffer.append("|");  

             }

         }

         

         return buffer.toString();

     }

     

 }




2.7 校验工具类

ValidUtils.java




 /**

  * 校验工具类

  * @author Administrator

  *

  */

 public class ValidUtils {

     

     /**

      * 校验数据中的指定字段,是否在指定范围内

      * @param data 数据

      * @param dataField 数据字段

      * @param parameter 参数

      * @param startParamField 起始参数字段

      * @param endParamField 结束参数字段

      * @return 校验结果

      */

     public static boolean between(String data, String dataField, 

             String parameter, String startParamField, String endParamField) {

         String startParamFieldStr = StringUtils.getFieldFromConcatString(

                 parameter, "\\|", startParamField);

         String endParamFieldStr = StringUtils.getFieldFromConcatString(

                 parameter, "\\|", endParamField); 

         if(startParamFieldStr == null || endParamFieldStr == null) {

             return true;

         }

         

         int startParamFieldValue = Integer.valueOf(startParamFieldStr);

         int endParamFieldValue = Integer.valueOf(endParamFieldStr);

         

         String dataFieldStr = StringUtils.getFieldFromConcatString(

                 data, "\\|", dataField);

         if(dataFieldStr != null) {

             int dataFieldValue = Integer.valueOf(dataFieldStr);

             if(dataFieldValue >= startParamFieldValue &&

                     dataFieldValue <= endParamFieldValue) {

                 return true;

             } else {

                 return false;

             }

         }

         

         return false;

     }

     

     /**

      * 校验数据中的指定字段,是否有值与参数字段的值相同

      * @param data 数据

      * @param dataField 数据字段

      * @param parameter 参数

      * @param paramField 参数字段

      * @return 校验结果

      */

     public static boolean in(String data, String dataField, 

             String parameter, String paramField) {

         String paramFieldValue = StringUtils.getFieldFromConcatString(

                 parameter, "\\|", paramField);

         if(paramFieldValue == null) {

             return true;

         }

         String[] paramFieldValueSplited = paramFieldValue.split(",");  

         

         String dataFieldValue = StringUtils.getFieldFromConcatString(

                 data, "\\|", dataField);

         if(dataFieldValue != null) {

             String[] dataFieldValueSplited = dataFieldValue.split(",");

             

             for(String singleDataFieldValue : dataFieldValueSplited) {

                 for(String singleParamFieldValue : paramFieldValueSplited) {

                     if(singleDataFieldValue.equals(singleParamFieldValue)) {

                         return true;

                     }

                 }

             }

          }

         

         return false;

     }

     

     /**

      * 校验数据中的指定字段,是否在指定范围内

      * @param data 数据

      * @param dataField 数据字段

      * @param parameter 参数

      * @param paramField 参数字段

      * @return 校验结果

      */

     public static boolean equal(String data, String dataField, 

             String parameter, String paramField) {  

         String paramFieldValue = StringUtils.getFieldFromConcatString(

                 parameter, "\\|", paramField);

         if(paramFieldValue == null) {

             return true;

         }

         

         String dataFieldValue = StringUtils.getFieldFromConcatString(

                 data, "\\|", dataField);

         if(dataFieldValue != null) {

             if(dataFieldValue.equals(paramFieldValue)) {

                 return true;

             }

          }

         

         return false;

     }

     

 }

Spark项目之电商用户行为分析大数据平台之(十一)JSON及FASTJSON

目录

  • 一、概述

  • 二、JSON的结构

    • 2.1 简单值

    • 2.2 对象

    • 2.3 数组

    • 三、JSON详解

  • 四、FastJson


正文

回到顶部

一、概述

JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。XML也是一种数据交换格式,为什么没 有选择XML呢?因为XML虽然可以作为跨平台的数据交换格式,但是在JS(JavaScript的简写)中处理XML非常不方便,同时XML标记比数据 多,增加了交换产生的流量,而JSON没有附加的任何标记,在JS中可作为对象处理,所以我们更倾向于选择JSON来交换数据。这篇文章主要从以下几个方 面来说明JSON。

回到顶部

二、JSON的结构

2.1 简单值

简单值使用与javascript相同的语法,可以在JSON中表示字符串、数值、布尔值和null

字符串必须使用双引号表示,不能使用单引号。数值必须以十进制表示,且不能使用NaN和Infinity

[注意]JSON不支持javascript中的特殊值undefined

//合格的简单值5"hello world"truenull
复制
//不合格的简单值+0x1'hello world'undefined
NaN
Infinity
复制


2.2 对象

对象作为一种复杂数据类型,表示的是一组有序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值(其中关键字是字符串,而值可以是字符串,数值,true,false,null,对象或数组)

与javascript的对象字面量相比,JSON有三个不同的地方

  1、JSON没有变量的概念

  2、JSON中,对象的键名必须放在双引号里面

  3、因为JSON不是javascript语句,所以没有末尾的分号

  [注意]同一个对象中不应该出现两个同名属性

//合格的对象{    "name":"huochai",    "age":29,    "school":{        "name":"diankeyuan",        "location":"beijing"
    }
}
复制
//不合格的对象{ name: "张三", 'age': 32 }//属性名必须使用双引号{};//不需要末尾的分号{ "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),  "getName": function() {      return this.name;
  }
} // 不能使用函数和日期对象
复制


2.3 数组

数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组

JSON数组也没有变量和分号,把数组和对象结合起来,可以构成更复杂的数据集合

[注意]数组或对象最后一个成员的后面,不能加逗号

[
    {
        key1:value1,
        key2:value2 
    },
    {
         key3:value3,
         key4:value4   
    }
]
复制


三、JSON详解

JSON详解

JSON的全称是”JavaScript Object Notation”,意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式。XML也是一种数据交换格式,为什么没 有选择XML呢?因为XML虽然可以作为跨平台的数据交换格式,但是在JS(JavaScript的简写)中处理XML非常不方便,同时XML标记比数据 多,增加了交换产生的流量,而JSON没有附加的任何标记,在JS中可作为对象处理,所以我们更倾向于选择JSON来交换数据。这篇文章主要从以下几个方 面来说明JSON。

1,JSON的两种结构
2,认识JSON字符串
3,在JS中如何使用JSON
4,在.NET中如何使用JSON
5,总结

{
    key1:value1,
    key2:value2,
    ...
}
复制

其中关键字是字符串,而值可以是字符串,数值,true,false,null,对象或数组

数组结构以”[”开始,”]”结束。中间由0或多个以”,”分隔的值列表组成,语法结构如代码。

[
    {
        key1:value1,
        key2:value2 
    },
    {
         key3:value3,
         key4:value4   
    }
]
复制

认识JSON字符串

之前我一直有个困惑,分不清普通字符串,json字符串和json对象的区别。经过一番研究终于给弄明白了。比如在js中。

字符串:这个很好解释,指使用“”双引号或’’单引号包括的字符。例如:var comStr = 'this is string';
json字符串:指的是符合json格式要求的js字符串。例如:var jsonStr = "{StudentID:'100',Name:'tmac',Hometown:'usa'}";
json对象:指符合json格式要求的js对象。例如:var jsonObj = { StudentID: "100", Name: "tmac", Hometown: "usa" };

var obj = {
            1: "value1",
            "2": "value2",
            count: 3,
            person: [ //数组结构JSON对象,可以嵌套使用                        {
                            id: 1,
                            name: "张三"
                        },
                        {
                            id: 2,
                            name: "李四"
                        }
                   ],
            object: { //对象结构JSON对象
                id: 1,
                msg: "对象里的对象"    
            }
        };
复制

1,从JSON中读数据

function ReadJSON() {
            alert(obj.1); //会报语法错误,可以用alert(obj["1"]);说明数字最好不要做关键字
            alert(obj.2); //同上
            alert(obj.person[0].name); //或者alert(obj.person[0]["name"])
            alert(obj.object.msg); //或者alert(obj.object["msg"])
        }
复制

2,向JSON中写数据

比如要往JSON中增加一条数据,代码如下:

function Add() { //往JSON对象中增加了一条记录 obj.sex= "男" //或者obj["sex"]="男" }

增加数据后的JSON对象如图:

3,修改JSON中的数据

我们现在要修改JSON中count的值,代码如下:

function Update() { obj.count = 10; //或obj["count"]=10 }

修改后的JSON如图。

4,删除JSON中的数据

我们现在实现从JSON中删除count这条数据,代码如下:

function Delete() { delete obj.count; }

删除后的JSON如图

可以看到count已经从JSON对象中被删除了。

5,遍历JSON对象

可以使用for…in…循环来遍历JSON对象中的数据,比如我们要遍历输出obj对象的值,代码如下:

function Traversal() { for (var c in obj) { console.log(c + ":", obj[c]); } }

程序输出结果为:

.NET,它是一个非常著名的在.net中处理JSON的工具,我们最常用的是下面两个功能。


1,通过序列化将.net对象转换为JSON字符串

在web开发过程中,我们经常需要将从数据库中 查询到的数据(一般为一个集合,列表或数组等)转换为JSON格式字符串传回客户端,这就需要进行序列化,这里用到的是JsonConvert对象的 SerializeObject方法。其语法格式为:JsonConvert.SerializeObject(object),代码中 的”object”就是要序列化的.net对象,序列化后返回的是json字符串。

比如,现在我们有一个TStudent的学生表,表中的字段和已有数据如图所示

从表中我们可以看到一共有五条数据,现在我们要从数据库中取出这些数据,然后利用JSON.Net的JsonConvert对象序列化它们为json字符串,并显示在页面上。C#代码如下

protected void Page_Load(object sender, EventArgs e)
        {            using (L2SDBDataContext db = new L2SDBDataContext())
            {
                List<Student> studentList = new List<Student>();                var query = from s in db.TStudents                            select new { 
                                StudentID=s.StudentID,
                                Name=s.Name,
                                Hometown=s.Hometown,
                                Gender=s.Gender,
                                Brithday=s.Birthday,
                                ClassID=s.ClassID,
                                Weight=s.Weight,
                                Height=s.Height,
                                Desc=s.Desc
                            };                foreach (var item in query)
                {
                    Student student = new Student { StudentID=item.StudentID,Name=item.Name,Hometown=item.Hometown,Gender=item.Gender,Brithday=item.Brithday,ClassID=item.ClassID,Weight=item.Weight,Height=item.Height,Desc=item.Desc};
                    studentList.Add(student);
                }
                lbMsg.InnerText = JsonConvert.SerializeObject(studentList);
            }
        }
复制

输出结果

从图中我们可以看到,数据库中的5条记录全部取出来并转化为json字符串了。


2,使用LINQ to JSON定制JSON数据

使用JsonConvert对象的SerializeObject只是简单地将一个list或 集合转换为json字符串。但是,有的时候我们的前端框架比如ExtJs对服务端返回的数据格式是有一定要求的,比如下面的数据格式,这时就需要用到 JSON.NET的LINQ to JSON,LINQ to JSON的作用就是根据需要的格式来定制json数据。

比如经常用在分页的json格式如代码:

{ "total": 5, //记录总数 "rows":[ //json格式的数据列表 ] }

使用LINQ to JSON前,需要引用Newtonsoft.Json的dll和using Newtonsoft.Json.Linq的命名空间。LINQ to JSON主要使用到JObject, JArray, JProperty和JValue这四个对象,JObject用来生成一个JSON对象,简单来说就是生成”{}”,JArray用来生成一个JSON数 组,也就是”[]”,JProperty用来生成一个JSON数据,格式为key/value的值,而JValue则直接生成一个JSON值。下面我们就 用LINQ to JSON返回上面分页格式的数据。代码如下:

protected void Page_Load(object sender, EventArgs e)
        {            using (L2SDBDataContext db = new L2SDBDataContext())
            {                //从数据库中取出数据并放到列表list中
                List<Student> studentList = new List<Student>();                var query = from s in db.TStudents                            select new
                            {
                                StudentID = s.StudentID,
                                Name = s.Name,
                                Hometown = s.Hometown,
                                Gender = s.Gender,
                                Brithday = s.Birthday,
                                ClassID = s.ClassID,
                                Weight = s.Weight,
                                Height = s.Height,
                                Desc = s.Desc
                            };                foreach (var item in query)
                {
                    Student student = new Student { StudentID = item.StudentID, Name = item.Name, Hometown = item.Hometown, Gender = item.Gender, Brithday = item.Brithday, ClassID = item.ClassID, Weight = item.Weight, Height = item.Height, Desc = item.Desc };
                    studentList.Add(student);
                }                //基于创建的list使用LINQ to JSON创建期望格式的JSON数据
                lbMsg.InnerText = new JObject(                        new JProperty("total",studentList.Count),                        new JProperty("rows",                                new JArray(                                        //使用LINQ to JSON可直接在select语句中生成JSON数据对象,无须其它转换过程                                        from p in studentList                                        select new JObject(                                                new JProperty("studentID",p.StudentID),                                                new JProperty("name",p.Name),                                                new JProperty("homeTown",p.Hometown)
                                            )
                                    )
                            )
                    ).ToString();
            }
        }
复制

输出结果为:


3,处理客户端提交的JSON数据

客户端提交过来的数据一般都是json字符串,有了更好地进行操作(面向对象的方式),所以我们一般都会想办法将json字符串转换为json对象。例如客户端提交了以下数组格式json字符串。

[ {StudentID:"100",Name:"aaa",Hometown:"china"}, {StudentID:"101",Name:"bbb",Hometown:"us"}, {StudentID:"102",Name:"ccc",Hometown:"england"} ]

在服务端就可以使用JObject或JArray的Parse方法轻松地将json字符串转换为json对象,然后通过对象的方式提取数据。下面是服务端代码。

protected void Page_Load(object sender, EventArgs e)
        {            string inputJsonString = @"
                [
                    {StudentID:'100',Name:'aaa',Hometown:'china'},
                    {StudentID:'101',Name:'bbb',Hometown:'us'},
                    {StudentID:'102',Name:'ccc',Hometown:'england'}
                ]";
            JArray jsonObj = JArray.Parse(inputJsonString);            string message = @"<table border='1'>
                    <tr><td width='80'>StudentID</td><td width='100'>Name</td><td width='100'>Hometown</td></tr>";            string tpl = "<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>";            foreach (JObject jObject in jsonObj)
            {
                message += String.Format(tpl, jObject["StudentID"], jObject["Name"],jObject["Hometown"]);
            }
            message += "</table>";
            lbMsg.InnerHtml = message;
        }
复制

输出结果:

当然,服务端除了使用LINQ to JSON来转换json字符串外,也可以使用JsonConvert的DeserializeObject方法。如下面代码实现上面同样的功能。

List<Student> studentList = JsonConvert.DeserializeObject<List<Student>>(inputJsonString);//注意这里必须为List<Student>类型,因为客户端提交的是一个数组json foreach (Student student in studentList) { message += String.Format(tpl, student.StudentID, student.Name,student.Hometown); }


四、FastJson

FastJson对于JSON格式字符串、JSON对象及JavaBean之间的相互转换

fastJson对于json格式字符串的解析主要用到了一下三个类:

JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换。

JSONObject:fastJson提供的json对象。

JSONArray:fastJson提供json数组对象。

我们可以把JSONObject当成一个Map<String,Object>来看,只是JSONObject提供了更为丰富便捷的方法,方便我们对于对象属性的操作。我们看一下源码。

同样我们可以把JSONArray当做一个List<Object>,可以把JSONArray看成JSONObject对象的一个集合。

此外,由于JSONObject和JSONArray继承了JSON,所以说也可以直接使用两者对JSON格式字符串与JSON对象及javaBean之间做转换,不过为了避免混淆我们还是使用JSON。


首先定义三个json格式的字符串,作为我们的数据源。

//json字符串-简单对象型private static final String  JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";//json字符串-数组类型private static final String  JSON_ARRAY_STR = "[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]";//复杂格式json字符串private static final String  COMPLEX_JSON_STR = "{\"teacherName\":\"crystall\",\"teacherAge\":27,\"course\":{\"courseName\":\"english\",\"code\":1270},\"students\":[{\"studentName\":\"lily\",\"studentAge\":12},{\"studentName\":\"lucy\",\"studentAge\":15}]}";
复制


示例1:JSON格式字符串与JSON对象之间的转换。

示例1.1-json字符串-简单对象型与JSONObject之间的转换

    /**
     * json字符串-简单对象型与JSONObject之间的转换     */
    public static void testJSONStrToJSONObject(){
        JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);        //JSONObject jsonObject1 = JSONObject.parseObject(JSON_OBJ_STR); //因为JSONObject继承了JSON,所以这样也是可以的
        System.out.println(jsonObject.getString("studentName")+":"+jsonObject.getInteger("studentAge"));
    }
复制


示例1.2-json字符串-数组类型与JSONArray之间的转换

    /**
     * json字符串-数组类型与JSONArray之间的转换     */
    public static void testJSONStrToJSONArray(){
        JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);        //JSONArray jsonArray1 = JSONArray.parseArray(JSON_ARRAY_STR);//因为JSONArray继承了JSON,所以这样也是可以的        //遍历方式1
        int size = jsonArray.size();        for (int i = 0; i < size; i++){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            System.out.println(jsonObject.getString("studentName")+":"+jsonObject.getInteger("studentAge"));
        }        //遍历方式2
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            System.out.println(jsonObject.getString("studentName")+":"+jsonObject.getInteger("studentAge"));
        }
    }
复制


示例1.3-复杂json格式字符串与JSONObject之间的转换

    /**
     * 复杂json格式字符串与JSONObject之间的转换     */
    public static void testComplexJSONStrToJSONObject(){
        JSONObject jsonObject = JSON.parseObject(COMPLEX_JSON_STR);        //JSONObject jsonObject1 = JSONObject.parseObject(COMPLEX_JSON_STR);//因为JSONObject继承了JSON,所以这样也是可以的        
        String teacherName = jsonObject.getString("teacherName");
        Integer teacherAge = jsonObject.getInteger("teacherAge");
        JSONObject course = jsonObject.getJSONObject("course");
        JSONArray students = jsonObject.getJSONArray("students");
    }
复制


示例2:JSON格式字符串与javaBean之间的转换。

首先,我们针对数据源所示的字符串,提供三个javaBean。

public class Student {    private String studentName;    private Integer studentAge;    public String getStudentName() {        return studentName;
    }    public void setStudentName(String studentName) {        this.studentName = studentName;
    }    public Integer getStudentAge() {        return studentAge;
    }    public void setStudentAge(Integer studentAge) {        this.studentAge = studentAge;
    }
}
复制
public class Course {    private String courseName;    private Integer code;    public String getCourseName() {        return courseName;
    }    public void setCourseName(String courseName) {        this.courseName = courseName;
    }    public Integer getCode() {        return code;
    }    public void setCode(Integer code) {        this.code = code;
    }
}
复制
public class Teacher {    private String teacherName;    private Integer teacherAge;    private Course course;    private List<Student> students;    public String getTeacherName() {        return teacherName;
    }    public void setTeacherName(String teacherName) {        this.teacherName = teacherName;
    }    public Integer getTeacherAge() {        return teacherAge;
    }    public void setTeacherAge(Integer teacherAge) {        this.teacherAge = teacherAge;
    }    public Course getCourse() {        return course;
    }    public void setCourse(Course course) {        this.course = course;
    }    public List<Student> getStudents() {        return students;
    }    public void setStudents(List<Student> students) {        this.students = students;
    }
}
复制

json字符串与javaBean之间的转换推荐使用 TypeReference<T> 这个类,使用泛型可以更加清晰,当然也有其它的转换方式,这里就不做探讨了。

示例2.1-json字符串-简单对象型与javaBean之间的转换

   **
     * json字符串-简单对象与JavaBean_obj之间的转换     */
    public static void testJSONStrToJavaBeanObj(){
        Student student = JSON.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});        //Student student1 = JSONObject.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});//因为JSONObject继承了JSON,所以这样也是可以的
        System.out.println(student.getStudentName()+":"+student.getStudentAge());
    }
复制

示例2.2-json字符串-数组类型与javaBean之间的转换

/**
     * json字符串-数组类型与JavaBean_List之间的转换     */
    public static void testJSONStrToJavaBeanList(){
        
        ArrayList<Student> students = JSON.parseObject(JSON_ARRAY_STR, new TypeReference<ArrayList<Student>>() {});        //ArrayList<Student> students1 = JSONArray.parseObject(JSON_ARRAY_STR, new TypeReference<ArrayList<Student>>() {});//因为JSONArray继承了JSON,所以这样也是可以的
        for (Student student : students) {
            System.out.println(student.getStudentName()+":"+student.getStudentAge());
        }
    }
复制

示例2.3-复杂json格式字符串与与javaBean之间的转换

    /**
     * 复杂json格式字符串与JavaBean_obj之间的转换     */
    public static void testComplexJSONStrToJavaBean(){
        Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});        //Teacher teacher1 = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});//因为JSONObject继承了JSON,所以这样也是可以的
        String teacherName = teacher.getTeacherName();
        Integer teacherAge = teacher.getTeacherAge();
        Course course = teacher.getCourse();
        List<Student> students = teacher.getStudents();
    }
复制

对于TypeReference<T>,由于其构造方法使用 protected 进行修饰,所以在其他包下创建其对象的时候,要用其实现类的子类:new TypeReference<Teacher>() {}

此外的:

1,对于JSON对象与JSON格式字符串的转换可以直接用 toJSONString()这个方法。

2,javaBean与JSON格式字符串之间的转换要用到:JSON.toJSONString(obj);

3,javaBean与json对象间的转换使用:JSON.toJSON(obj),然后使用强制类型转换,JSONObject或者JSONArray。

Spark项目之电商用户行为分析大数据平台之(十二)Spark上下文构建及模拟数据生成

目录

一、模拟生成数据

二、构建Spark上下文

三、打印的测试数据

3.1 user_visit_action

3.2 user_info

3.3 product_info



正文



一、模拟生成数据



 package com.bw.test;


 import java.util.ArrayList;

 import java.util.Arrays;

 import java.util.List;

 import java.util.Random;

 import java.util.UUID;


 import com.bw.util.DateUtils;

 import com.bw.util.StringUtils;

 import org.apache.spark.api.java.JavaRDD;

 import org.apache.spark.api.java.JavaSparkContext;

 import org.apache.spark.sql.DataFrame;

 import org.apache.spark.sql.Row;

 import org.apache.spark.sql.RowFactory;

 import org.apache.spark.sql.SQLContext;

 import org.apache.spark.sql.types.DataTypes;

 import org.apache.spark.sql.types.StructType;



 /**

  * 模拟数据程序

  * @author Administrator

  *

  */

 public class MockData {


     /**

      * 模拟数据

      * @param sc

      * @param sqlContext

      */

     public static void mock(JavaSparkContext sc,

             SQLContext sqlContext) {

         List<Row> rows = new ArrayList<Row>();

         

         String[] searchKeywords = new String[] {"火锅", "蛋糕", "重庆辣子鸡", "重庆小面",

                 "呷哺呷哺", "新辣道鱼火锅", "国贸大厦", "太古商场", "日本料理", "温泉"};

         String date = DateUtils.getTodayDate();

         String[] actions = new String[]{"search", "click", "order", "pay"};

         Random random = new Random();

         

         for(int i = 0; i < 100; i++) {

             //生产100个userID

             long userid = random.nextInt(100);    

             

             for(int j = 0; j < 10; j++) {

                 //每个userID有10个sessionID

                 String sessionid = UUID.randomUUID().toString().replace("-", "");  

                 String baseActionTime = date + " " + random.nextInt(23);

                 

                 Long clickCategoryId = null;

                 //每个sessionID可能会做0-100之间的action操作

                 for(int k = 0; k < random.nextInt(100); k++) {

                     long pageid = random.nextInt(10);    

                     String actionTime = baseActionTime + ":" + StringUtils.fulfuill(String.valueOf(random.nextInt(59))) + ":" + StringUtils.fulfuill(String.valueOf(random.nextInt(59)));

                     String searchKeyword = null;

                     Long clickProductId = null;

                     String orderCategoryIds = null;

                     String orderProductIds = null;

                     String payCategoryIds = null;

                     String payProductIds = null;

                     

                     String action = actions[random.nextInt(4)];

                     if("search".equals(action)) {

                         searchKeyword = searchKeywords[random.nextInt(10)];   

                     } else if("click".equals(action)) {

                         if(clickCategoryId == null) {

                             clickCategoryId = Long.valueOf(String.valueOf(random.nextInt(100)));    

                         }

                         clickProductId = Long.valueOf(String.valueOf(random.nextInt(100)));  

                     } else if("order".equals(action)) {

                         orderCategoryIds = String.valueOf(random.nextInt(100));  

                         orderProductIds = String.valueOf(random.nextInt(100));

                     } else if("pay".equals(action)) {

                         payCategoryIds = String.valueOf(random.nextInt(100));  

                         payProductIds = String.valueOf(random.nextInt(100));

                     }

                     

                     Row row = RowFactory.create(date, userid, sessionid, 

                             pageid, actionTime, searchKeyword,

                             clickCategoryId, clickProductId,

                             orderCategoryIds, orderProductIds,

                             payCategoryIds, payProductIds, 

                             Long.valueOf(String.valueOf(random.nextInt(10))));    

                     rows.add(row);

                 }

             }

         }

         

         JavaRDD<Row> rowsRDD = sc.parallelize(rows);

         

         StructType schema = DataTypes.createStructType(Arrays.asList(

                 DataTypes.createStructField("date", DataTypes.StringType, true),

                 DataTypes.createStructField("user_id", DataTypes.LongType, true),

                 DataTypes.createStructField("session_id", DataTypes.StringType, true),

                 DataTypes.createStructField("page_id", DataTypes.LongType, true),

                 DataTypes.createStructField("action_time", DataTypes.StringType, true),

                 DataTypes.createStructField("search_keyword", DataTypes.StringType, true),

                 DataTypes.createStructField("click_category_id", DataTypes.LongType, true),

                 DataTypes.createStructField("click_product_id", DataTypes.LongType, true),

                 DataTypes.createStructField("order_category_ids", DataTypes.StringType, true),

                 DataTypes.createStructField("order_product_ids", DataTypes.StringType, true),

                 DataTypes.createStructField("pay_category_ids", DataTypes.StringType, true),

                 DataTypes.createStructField("pay_product_ids", DataTypes.StringType, true),

                 DataTypes.createStructField("city_id", DataTypes.LongType, true)));


         DataFrame df = sqlContext.createDataFrame(rowsRDD, schema);


         df.registerTempTable("user_visit_action");  

         for(Row _row : df.take(1)) {

             System.out.println(_row);  

         }

         

         /**

          * ==================================================================

          */

         

         rows.clear();

         String[] sexes = new String[]{"male", "female"};

         for(int i = 0; i < 100; i ++) {

             long userid = i;

             String username = "user" + i;

             String name = "name" + i;

             int age = random.nextInt(60);

             String professional = "professional" + random.nextInt(100);

             String city = "city" + random.nextInt(100);

             String sex = sexes[random.nextInt(2)];

             

             Row row = RowFactory.create(userid, username, name, age, 

                     professional, city, sex);

             rows.add(row);

         }

         

         rowsRDD = sc.parallelize(rows);

         

         StructType schema2 = DataTypes.createStructType(Arrays.asList(

                 DataTypes.createStructField("user_id", DataTypes.LongType, true),

                 DataTypes.createStructField("username", DataTypes.StringType, true),

                 DataTypes.createStructField("name", DataTypes.StringType, true),

                 DataTypes.createStructField("age", DataTypes.IntegerType, true),

                 DataTypes.createStructField("professional", DataTypes.StringType, true),

                 DataTypes.createStructField("city", DataTypes.StringType, true),

                 DataTypes.createStructField("sex", DataTypes.StringType, true)));

         

         DataFrame df2 = sqlContext.createDataFrame(rowsRDD, schema2);

         for(Row _row : df2.take(1)) {

             System.out.println(_row);  

         }

         

         df2.registerTempTable("user_info");  

         

         /**

          * ==================================================================

          */

         rows.clear();

         

         int[] productStatus = new int[]{0, 1};

         

         for(int i = 0; i < 100; i ++) {

             long productId = i;

             String productName = "product" + i;

             String extendInfo = "{\"product_status\": " + productStatus[random.nextInt(2)] + "}";    

             

             Row row = RowFactory.create(productId, productName, extendInfo);

             rows.add(row);

         }

         

         rowsRDD = sc.parallelize(rows);

         

         StructType schema3 = DataTypes.createStructType(Arrays.asList(

                 DataTypes.createStructField("product_id", DataTypes.LongType, true),

                 DataTypes.createStructField("product_name", DataTypes.StringType, true),

                 DataTypes.createStructField("extend_info", DataTypes.StringType, true)));

         

         DataFrame df3 = sqlContext.createDataFrame(rowsRDD, schema3);

         for(Row _row : df3.take(1)) {

             System.out.println(_row);  

         }

         

         df3.registerTempTable("product_info"); 

     }

     

 }



二、构建Spark上下文



 import com.bw.conf.ConfigurationManager;

 import com.bw.constant.Constants;

 import com.bw.test.MockData;

 import org.apache.spark.SparkConf;

 import org.apache.spark.api.java.JavaSparkContext;

 import org.apache.spark.sql.SQLContext;



 /**

  * 用户访问session分析Spark作业

  *

  * */

 public class UserVisitSessionAnalyzeSpark {


     public static void main(String[] args) {

         //构建Spark上下文

         SparkConf sparkConf = new SparkConf();

         //Spark作业本地运行

         sparkConf.setMaster("local");

         //为了符合大型企业的开发需求,不能出现硬编码,创建一个Constants接口类,定义一些常量

         sparkConf.setAppName(Constants.SPARK_APP_NAME_SESSION);


         JavaSparkContext jsc = new JavaSparkContext(sparkConf);

         SQLContext sqlContext = new SQLContext(jsc);


         mockData(jsc,sqlContext);

         jsc.stop();

     }



     /**

      * 生成模拟数据(只有本地模式,才会去生成模拟数据)

      * @param sc

      * @param sqlContext

      */

     private static void mockData(JavaSparkContext sc, SQLContext sqlContext) {

         boolean local = ConfigurationManager.getBoolean(Constants.SPARK_LOCAL);

         if(local) {

             MockData.mock(sc, sqlContext);

         }

     }

 }

三、打印的测试数据

3.1 user_visit_action

用户下的订单

[2018-05-23,34,4ad62c0824194e5687467bb84b9beeb9,3,2018-05-23 18:27:37,null,null,null,null,null,8,64,8]
复制

3.2 user_info

[0,user0,name0,26,professional11,city4,male]
复制

3.3 product_info

[0,product0,{"product_status": 1}]
复制



文章转载自逗先生大数据,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论